/** Automatic scoring for on-site inspector measurements. */
export type MeasureStatus = "Low" | "Normal" | "Medium" | "High";
export type OverallRisk = "Low Risk" | "Moderate Risk" | "Elevated Risk" | "High Risk";

export type Reading = { status: MeasureStatus; score: number; hex: string; tone: string };

const HEX: Record<MeasureStatus, string> = {
  Low: "#2563eb",
  Normal: "#15803d",
  Medium: "#b45309",
  High: "#b91c1c",
};

const TONE: Record<MeasureStatus, string> = {
  Low: "bg-sky-500/15 text-foreground",
  Normal: "bg-success/15 text-foreground",
  Medium: "bg-warning/25 text-foreground",
  High: "bg-destructive/10 text-destructive",
};

const clamp = (n: number) => Math.max(0, Math.min(100, Math.round(n)));
const wrap = (status: MeasureStatus, score: number): Reading => ({
  status,
  score: clamp(score),
  hex: HEX[status],
  tone: TONE[status],
});

/** Temperature in °C → mold-favourability status and score. e.g. 27 °C → Medium · 72% */
export function temperatureReading(value: number | string | null | undefined): Reading | null {
  const t = Number(value);
  if (value === "" || value === null || value === undefined || Number.isNaN(t)) return null;
  const status: MeasureStatus = t < 18 ? "Low" : t < 24 ? "Normal" : t < 30 ? "Medium" : "High";
  return wrap(status, (t - 9) * 4);
}

/** Relative humidity in % → status and score. e.g. 65% RH → Medium · 74% */
export function humidityReading(value: number | string | null | undefined): Reading | null {
  const h = Number(value);
  if (value === "" || value === null || value === undefined || Number.isNaN(h)) return null;
  const status: MeasureStatus = h < 30 ? "Low" : h < 50 ? "Normal" : h < 70 ? "Medium" : "High";
  return wrap(status, h * 1.1 + 2);
}

export const MOISTURE_OPTIONS = ["Dry", "Slightly Damp", "Damp", "Very Wet"] as const;
export type MoistureOption = (typeof MOISTURE_OPTIONS)[number];

const MOISTURE: Record<MoistureOption, { status: MeasureStatus; score: number }> = {
  Dry: { status: "Low", score: 12 },
  "Slightly Damp": { status: "Normal", score: 40 },
  Damp: { status: "Medium", score: 70 },
  "Very Wet": { status: "High", score: 92 },
};

export function moistureReading(value: string | null | undefined): Reading | null {
  const m = MOISTURE[value as MoistureOption];
  return m ? wrap(m.status, m.score) : null;
}

export const DETECTOR_OPTIONS = [
  "Leak Detected",
  "No Leak Detected",
  "Further Investigation Required",
] as const;
export type DetectorOption = (typeof DETECTOR_OPTIONS)[number];

const DETECTOR: Record<DetectorOption, { status: MeasureStatus; score: number }> = {
  "No Leak Detected": { status: "Low", score: 10 },
  "Further Investigation Required": { status: "Medium", score: 55 },
  "Leak Detected": { status: "High", score: 95 },
};

export function detectorReading(value: string | null | undefined): Reading | null {
  const d = DETECTOR[value as DetectorOption];
  return d ? wrap(d.status, d.score) : null;
}

export type OverallAssessment = {
  risk: OverallRisk;
  score: number;
  hex: string;
  tone: string;
  explanation: string;
};

const RISK_HEX: Record<OverallRisk, string> = {
  "Low Risk": "#15803d",
  "Moderate Risk": "#a16207",
  "Elevated Risk": "#c2410c",
  "High Risk": "#b91c1c",
};

const RISK_TONE: Record<OverallRisk, string> = {
  "Low Risk": "bg-success/15 text-foreground",
  "Moderate Risk": "bg-warning/25 text-foreground",
  "Elevated Risk": "bg-warning/40 text-foreground",
  "High Risk": "bg-destructive/10 text-destructive",
};

/** Weighted overall environmental risk from the available readings. */
export function overallRisk(input: {
  temperature?: Reading | null;
  humidity?: Reading | null;
  moisture?: Reading | null;
  detector?: Reading | null;
}): OverallAssessment | null {
  const parts: { label: string; reading: Reading; weight: number }[] = [];
  if (input.temperature) parts.push({ label: "temperature", reading: input.temperature, weight: 0.15 });
  if (input.humidity) parts.push({ label: "humidity", reading: input.humidity, weight: 0.3 });
  if (input.moisture) parts.push({ label: "moisture", reading: input.moisture, weight: 0.3 });
  if (input.detector) parts.push({ label: "water detector", reading: input.detector, weight: 0.25 });
  if (!parts.length) return null;

  const weight = parts.reduce((sum, p) => sum + p.weight, 0);
  const score = clamp(parts.reduce((sum, p) => sum + p.reading.score * p.weight, 0) / weight);
  const risk: OverallRisk =
    score < 30 ? "Low Risk" : score < 50 ? "Moderate Risk" : score < 70 ? "Elevated Risk" : "High Risk";

  const drivers = parts
    .filter((p) => p.reading.status === "High" || p.reading.status === "Medium")
    .map((p) => `${p.label} (${p.reading.status.toLowerCase()}, ${p.reading.score}%)`);

  const explanation =
    drivers.length > 0
      ? `Overall ${risk.toLowerCase()} (${score}%) driven mainly by ${drivers.join(", ")}. These conditions can support mold growth, so drying, ventilation and a professional inspection are advised.`
      : `Overall ${risk.toLowerCase()} (${score}%). The recorded readings are within normal ranges and do not currently indicate conditions that favour mold growth.`;

  return { risk, score, hex: RISK_HEX[risk], tone: RISK_TONE[risk], explanation };
}
