import { createFileRoute, Link } from "@tanstack/react-router";
import { useCallback, useRef, useState } from "react";
import { toast } from "sonner";
import { Camera, Upload, Info, Loader2, Thermometer, Droplets, CreditCard, Video, Sparkles, FileText } from "lucide-react";
import { AppShell } from "@/components/AppShell";
import { MoldEducationPanel } from "@/components/MoldEducationPanel";
import { AiDisclaimer } from "@/components/AiDisclaimer";
import { PaymentGate, useAiScanCredit, consumeCredit } from "@/components/PaymentGate";
import { ReportActions } from "@/components/ReportActions";
import { supabase } from "@/integrations/supabase/client";
import { useAuth } from "@/lib/use-auth";
import { extractKeyFrames, videoDuration } from "@/lib/video-frames";
import { annotateAll, LEGEND } from "@/lib/annotate";
import { generateReport, makeReportNo, uploadReportPdf } from "@/lib/report-actions";
import { COMPANY } from "@/lib/company";
import type { Assessment } from "@/lib/report-types";
import {
  DETECTOR_OPTIONS,
  MOISTURE_OPTIONS,
  detectorReading,
  humidityReading,
  moistureReading,
  overallRisk,
  temperatureReading,
  type Reading,
} from "@/lib/measurements";

export const Route = createFileRoute("/check")({
  head: () => ({
    meta: [
      { title: "AI Mold Check | Emma Mold Inspection Services" },
      {
        name: "description",
        content:
          "Upload a photo of a suspicious spot for an AI-assisted preliminary visual assessment with environmental risk, leakage signs and next steps.",
      },
      { property: "og:title", content: "AI Mold Photo Assessment" },
      {
        property: "og:description",
        content: "AI-assisted preliminary visual assessment — ₦5,000 per image analysis.",
      },
    ],
  }),
  component: CheckPage,
});

const tips = [
  "Turn on the lights or open curtains — avoid using flash straight on.",
  "Hold the camera 30–50 cm from the surface so texture is visible.",
  "Include a little of the surrounding wall for context.",
  "Take a second photo of any water stain, leak or damp corner nearby.",
];

const envLabels: { key: keyof NonNullable<Assessment["environmental"]>; label: string }[] = [
  { key: "ventilation", label: "Poor ventilation" },
  { key: "humidity", label: "High humidity" },
  { key: "condensation", label: "Condensation risk" },
  { key: "leakage", label: "Water leakage indicators" },
  { key: "dampness", label: "Dampness level" },
  { key: "airCirculation", label: "Air circulation rating" },
];

const moistureOptions = MOISTURE_OPTIONS;
const detectorOptions = DETECTOR_OPTIONS;

function ReadingBadge({ reading, hint }: { reading: Reading | null; hint: string }) {
  if (!reading) return <p className="mt-2 text-[11px] text-muted-foreground">{hint}</p>;
  return (
    <div className="mt-2 flex items-center gap-2">
      <span className={`rounded-full px-3 py-1 text-[11px] font-semibold ${reading.tone}`}>{reading.status}</span>
      <span className="text-[11px] font-semibold">{reading.score}%</span>
      <span className="h-2 flex-1 overflow-hidden rounded-full bg-muted">
        <span
          className="block h-full rounded-full"
          style={{ width: `${reading.score}%`, backgroundColor: reading.hex }}
        />
      </span>
    </div>
  );
}

export function severityTone(severity: string) {
  if (severity === "High") return "bg-destructive/10 text-destructive";
  if (severity === "Medium") return "bg-warning/20 text-foreground";
  return "bg-success/15 text-foreground";
}

function levelTone(level?: string) {
  if (level === "High") return "bg-destructive/10 text-destructive";
  if (level === "Medium") return "bg-warning/20 text-foreground";
  return "bg-success/15 text-foreground";
}

function Chips({
  options,
  value,
  onChange,
}: {
  options: readonly string[];
  value: string;
  onChange: (v: string) => void;
}) {
  return (
    <div className="mt-2 flex flex-wrap gap-2">
      {options.map((o) => (
        <button
          key={o}
          type="button"
          onClick={() => onChange(value === o ? "" : o)}
          className={`rounded-full border px-3 py-1.5 text-[11px] font-semibold ${
            value === o ? "border-transparent bg-brand text-primary-foreground" : "border-border text-muted-foreground"
          }`}
        >
          {o}
        </button>
      ))}
    </div>
  );
}

function CheckPage() {
  const { user } = useAuth();
  const { payment, approved, required, refetch } = useAiScanCredit();
  const fileRef = useRef<HTMLInputElement>(null);
  const cameraRef = useRef<HTMLInputElement>(null);
  const thermalRef = useRef<HTMLInputElement>(null);
  const videoRef = useRef<HTMLInputElement>(null);
  const videoCaptureRef = useRef<HTMLInputElement>(null);
  const [image, setImage] = useState<string | null>(null);
  const [thermal, setThermal] = useState<string | null>(null);
  const [frames, setFrames] = useState<string[]>([]);
  const [videoName, setVideoName] = useState<string | null>(null);
  const [duration, setDuration] = useState<number | null>(null);
  const [extracting, setExtracting] = useState(false);
  const [result, setResult] = useState<Assessment | null>(null);
  const [busy, setBusy] = useState(false);
  const [showTips, setShowTips] = useState(false);
  const [customerName, setCustomerName] = useState("");
  const [propertyAddress, setPropertyAddress] = useState("");
  const [reportNo, setReportNo] = useState<string | null>(null);
  const [pdf, setPdf] = useState<Blob | null>(null);
  const [annotated, setAnnotated] = useState<string[]>([]);
  const [buildingPdf, setBuildingPdf] = useState(false);

  const [temperatureValue, setTemperatureValue] = useState("");
  const [humidityValue, setHumidityValue] = useState("");
  const [moisture, setMoisture] = useState("");
  const [detector, setDetector] = useState("");
  const [thermalNotes, setThermalNotes] = useState("");
  const [inspectorComments, setInspectorComments] = useState("");

  const tempReading = temperatureReading(temperatureValue);
  const humReading = humidityReading(humidityValue);
  const moistReading = moistureReading(moisture);
  const detReading = detectorReading(detector);
  const overall = overallRisk({
    temperature: tempReading,
    humidity: humReading,
    moisture: moistReading,
    detector: detReading,
  });
  const temperatureLevel = tempReading?.status ?? "";
  const humidityLevel = humReading?.status ?? "";

  function readFile(file: File, cb: (dataUrl: string) => void) {
    if (file.size > 8 * 1024 * 1024) {
      toast.error("Please choose a photo under 8MB.");
      return;
    }
    const reader = new FileReader();
    reader.onload = () => cb(reader.result as string);
    reader.readAsDataURL(file);
  }

  function onPick(e: React.ChangeEvent<HTMLInputElement>) {
    const file = e.target.files?.[0];
    if (!file) return;
    readFile(file, (url) => {
      setImage(url);
      setFrames([]);
      setVideoName(null);
      setResult(null);
    });
  }

  function onPickThermal(e: React.ChangeEvent<HTMLInputElement>) {
    const file = e.target.files?.[0];
    if (!file) return;
    readFile(file, setThermal);
  }

  async function onPickVideo(e: React.ChangeEvent<HTMLInputElement>) {
    const file = e.target.files?.[0];
    e.target.value = "";
    if (!file) return;
    if (file.size > 60 * 1024 * 1024) {
      toast.error("Please choose a video under 60MB.");
      return;
    }
    setExtracting(true);
    try {
      const extracted = await extractKeyFrames(file, 5);
      setDuration(await videoDuration(file));
      setFrames(extracted);
      setImage(extracted[0] ?? null);
      setVideoName(file.name);
      setResult(null);
      toast.success(`${extracted.length} key frames extracted for analysis.`);
    } catch (error) {
      toast.error(error instanceof Error ? error.message : "Could not read that video.");
    } finally {
      setExtracting(false);
    }
  }

  async function analyze() {
    if (!image || !approved) return;
    if (required && !payment) return;
    setBusy(true);
    try {
      const res = await fetch("/api/analyze-mold", {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({
          imageDataUrl: image,
          frames: frames.slice(1),
          thermalDataUrl: thermal,
          mediaType: videoName ? "video" : "photo",
        }),
      });
      const data = await res.json();
      if (!res.ok) throw new Error(data.error ?? "Assessment failed.");
      const assessment = data as Assessment;
      setResult(assessment);
      if (required && payment) {
        await consumeCredit(payment.id);
        refetch();
      }
      try {
        await buildPdf(assessment);
      } catch (pdfError) {
        toast.error(
          pdfError instanceof Error
            ? `The assessment worked, but the PDF failed: ${pdfError.message}`
            : "The assessment worked, but the PDF could not be generated.",
        );
      }
    } catch (error) {
      toast.error(error instanceof Error ? error.message : "Assessment failed.");
    } finally {
      setBusy(false);
    }
  }

  const sourceImages = useCallback(() => (frames.length ? frames : image ? [image] : []), [frames, image]);

  function frameCaption(index: number) {
    if (!frames.length) return "Uploaded photo";
    const total = frames.length;
    const seconds = duration ? (duration * (index + 0.5)) / total : null;
    const stamp =
      seconds === null
        ? ""
        : ` · ${String(Math.floor(seconds / 60)).padStart(2, "0")}:${String(Math.floor(seconds % 60)).padStart(2, "0")}`;
    return `Key frame ${index + 1} of ${total}${stamp}`;
  }

  async function buildPdf(assessment: Assessment, quiet = false) {
    const sources = sourceImages();
    setBuildingPdf(true);
    try {
      let marks: string[] = [];
      if (sources.length) {
        try {
          marks = await annotateAll(sources, assessment.detections ?? []);
          setAnnotated(marks);
        } catch {
          marks = [];
        }
      }
      const no = reportNo ?? makeReportNo();
      setReportNo(no);
      const { blob } = await generateReport({
        reportNo: no,
        createdAt: new Date(),
        customerName: customerName || user?.email || "Not provided",
        propertyAddress,
        analysisType: frames.length ? "Video" : "Photo",
        images: sources.map((dataUrl, i) => ({ dataUrl, caption: frameCaption(i) })),
        annotated: marks.map((dataUrl, i) => ({ dataUrl, caption: `Annotated — ${frameCaption(i)}` })),
        thermalImage: thermal,
        thermalNormal: thermal ? image : null,
        video: frames.length ? { duration, framesAnalyzed: frames.length } : undefined,
        measurements: {
          temperatureLevel,
          temperatureValue,
          temperatureScore: tempReading?.score ?? null,
          humidityLevel,
          humidityValue,
          humidityScore: humReading?.score ?? null,
          moisture,
          moistureScore: moistReading?.score ?? null,
          detector,
          thermalNotes,
          inspectorComments,
          overallRisk: overall?.risk,
          overallRiskScore: overall?.score ?? null,
          overallRiskNote: overall?.explanation,
        },
        assessment,
        verifyUrl: `${COMPANY.website}/reports/${no}`,
      });
      setPdf(blob);
      if (!quiet) toast.success("Professional PDF report generated.");
      return blob;
    } catch (error) {
      console.error("PDF build failed", error);
      throw error instanceof Error ? error : new Error("The PDF could not be generated.");
    } finally {
      setBuildingPdf(false);
    }
  }

  async function saveResult() {
    if (!result) return;
    if (!user) {
      toast.error("Sign in to save this report to your history.");
      return;
    }
    const no = reportNo ?? makeReportNo();
    let pdfPath: string | null = null;
    try {
      const blob = await buildPdf(result, true);
      if (blob) pdfPath = await uploadReportPdf(blob, user.id, no);
    } catch {
      toast.error("The report PDF could not be stored, saving the findings only.");
    }
    const { error } = await supabase.from("mold_scans").insert({
      user_id: user.id,
      report_no: no,
      pdf_path: pdfPath,
      customer_name: customerName || null,
      property_address: propertyAddress || null,
      video_duration: duration,
      analysis: JSON.parse(JSON.stringify(result)),
      verdict: result.verdict,
      confidence: Math.round(result.confidence ?? 0),
      severity: result.severity ?? "Low",
      factors: result.factors ?? [],
      recommendations: result.recommendations ?? [],
      summary: result.summary,
      media_type: videoName ? "video" : "photo",
      frames_analyzed: frames.length || null,
      ventilation_risk: result.environmental?.ventilation ?? null,
      humidity_risk: result.environmental?.humidity ?? null,
      condensation_risk: result.environmental?.condensation ?? null,
      leakage_risk: result.environmental?.leakage ?? null,
      dampness_level: result.environmental?.dampness ?? null,
      air_circulation: result.environmental?.airCirculation ?? null,
      leakage_verdict: result.leakage?.verdict ?? null,
      leakage_signs: result.leakage?.signs ?? [],
      temperature_level: temperatureLevel || null,
      temperature_value: temperatureValue ? Number(temperatureValue) : null,
      humidity_level: humidityLevel || null,
      humidity_value: humidityValue ? Number(humidityValue) : null,
      moisture_reading: moisture || null,
      water_detector: detector || null,
      thermal_notes: thermalNotes || null,
      inspector_comments: inspectorComments || null,
      temperature_score: tempReading?.score ?? null,
      humidity_score: humReading?.score ?? null,
      moisture_score: moistReading?.score ?? null,
      overall_risk: overall?.risk ?? null,
      overall_risk_note: overall?.explanation ?? null,
    });
    if (error) {
      toast.error("Could not save this assessment.");
      return;
    }
    toast.success("Saved to your customer history.");
  }

  return (
    <AppShell>
      <h1 className="text-2xl font-bold">AI Mold Photo Assessment</h1>
      <p className="mt-1 text-sm text-muted-foreground">
        A preliminary visual assessment of a photo, reviewed by our AI assistant.
      </p>
      {required ? (
        <p className="mt-3 inline-flex items-center gap-2 rounded-full bg-accent px-4 py-2 text-xs font-semibold text-accent-foreground">
          <CreditCard className="h-3.5 w-3.5" /> Fee: ₦5,000 per image analysis
        </p>
      ) : (
        <p className="mt-3 inline-flex items-center gap-2 rounded-full bg-success/15 px-4 py-2 text-xs font-semibold">
          <Sparkles className="h-3.5 w-3.5 text-primary" /> Free for now (Testing Mode)
        </p>
      )}

      <div className="mt-5">
        <PaymentGate />
      </div>

      <div className="mt-5 rounded-3xl border border-border/60 bg-card p-4 shadow-card">
        {image ? (
          <img src={image} alt="Photo to assess" className="w-full rounded-2xl" />
        ) : (
          <div className="flex h-44 items-center justify-center rounded-2xl bg-soft text-sm text-muted-foreground">
            No photo selected yet
          </div>
        )}

        <div className="mt-4 grid grid-cols-2 gap-3">
          <button
            onClick={() => cameraRef.current?.click()}
            className="flex items-center justify-center gap-2 rounded-2xl bg-brand py-3 text-sm font-semibold text-primary-foreground"
          >
            <Camera className="h-4 w-4" /> Take Photo
          </button>
          <button
            onClick={() => fileRef.current?.click()}
            className="flex items-center justify-center gap-2 rounded-2xl border border-border bg-background py-3 text-sm font-semibold"
          >
            <Upload className="h-4 w-4" /> Upload Photo
          </button>
          <button
            onClick={() => videoCaptureRef.current?.click()}
            disabled={extracting}
            className="flex items-center justify-center gap-2 rounded-2xl border border-border bg-background py-3 text-sm font-semibold disabled:opacity-50"
          >
            {extracting ? <Loader2 className="h-4 w-4 animate-spin" /> : <Video className="h-4 w-4" />} Record Video
          </button>
          <button
            onClick={() => videoRef.current?.click()}
            disabled={extracting}
            className="flex items-center justify-center gap-2 rounded-2xl border border-border bg-background py-3 text-sm font-semibold disabled:opacity-50"
          >
            {extracting ? <Loader2 className="h-4 w-4 animate-spin" /> : <Upload className="h-4 w-4" />} Upload Video
          </button>
        </div>
        <input ref={cameraRef} type="file" accept="image/*" capture="environment" hidden onChange={onPick} />
        <input ref={fileRef} type="file" accept="image/*" hidden onChange={onPick} />
        <input ref={videoCaptureRef} type="file" accept="video/*" capture="environment" hidden onChange={onPickVideo} />
        <input ref={videoRef} type="file" accept="video/*" hidden onChange={onPickVideo} />

        {frames.length ? (
          <div className="mt-4">
            <p className="text-xs font-semibold">
              {frames.length} key frames from {videoName}
            </p>
            <div className="mt-2 flex gap-2 overflow-x-auto">
              {frames.map((f, i) => (
                <img key={f.slice(-24)} src={f} alt={`Key frame ${i + 1}`} className="h-16 w-24 shrink-0 rounded-lg object-cover" />
              ))}
            </div>
          </div>
        ) : null}

        <button
          onClick={() => setShowTips((s) => !s)}
          className="mt-3 flex items-center gap-2 text-xs font-semibold text-primary"
        >
          <Info className="h-3.5 w-3.5" /> Camera tips
        </button>
        {showTips ? (
          <ul className="mt-2 space-y-1.5 rounded-2xl bg-muted p-3 text-xs text-muted-foreground">
            {tips.map((tip) => (
              <li key={tip}>• {tip}</li>
            ))}
          </ul>
        ) : null}

        <div className="mt-4 grid gap-2">
          <label className="text-[11px] font-semibold text-muted-foreground" htmlFor="customer-name">
            Customer name (appears on the PDF report)
          </label>
          <input
            id="customer-name"
            value={customerName}
            onChange={(e) => setCustomerName(e.target.value)}
            className="w-full rounded-xl border border-border bg-background px-3 py-2 text-sm"
            placeholder="e.g. Mrs. Adaeze Okoro"
          />
          <label className="text-[11px] font-semibold text-muted-foreground" htmlFor="property-address">
            Property address
          </label>
          <input
            id="property-address"
            value={propertyAddress}
            onChange={(e) => setPropertyAddress(e.target.value)}
            className="w-full rounded-xl border border-border bg-background px-3 py-2 text-sm"
            placeholder="e.g. 12 Adeola Street, Lekki, Lagos"
          />
        </div>

        <button
          disabled={!image || busy || extracting || !approved}
          onClick={analyze}
          className="mt-4 flex w-full items-center justify-center gap-2 rounded-2xl bg-accent py-3.5 text-sm font-semibold text-accent-foreground shadow-card disabled:opacity-50"
        >
          {busy ? <Loader2 className="h-4 w-4 animate-spin" /> : <Sparkles className="h-4 w-4" />}
          {busy
            ? "Analyzing…"
            : !approved
              ? "Payment required to analyze"
              : frames.length
                ? "Analyze Video"
                : "Analyze Photo"}
        </button>
      </div>

      {result ? (
        <section className="mt-5 rounded-3xl border border-border/60 bg-card p-4 shadow-card">
          <div className="flex items-start justify-between gap-3">
            <h2 className="text-lg font-semibold">{result.verdict}</h2>
            <span className={`rounded-full px-3 py-1 text-[11px] font-semibold ${severityTone(result.severity)}`}>
              {result.severity} severity
            </span>
          </div>

          <div className="mt-3">
            <div className="flex justify-between text-xs text-muted-foreground">
              <span>Confidence</span>
              <span>{Math.round(result.confidence)}%</span>
            </div>
            <div className="mt-1 h-2 rounded-full bg-muted">
              <div className="h-2 rounded-full bg-brand" style={{ width: `${Math.round(result.confidence)}%` }} />
            </div>
          </div>

          <p className="mt-3 text-sm text-muted-foreground">{result.summary}</p>

          {result.factors?.length ? (
            <>
              <h3 className="mt-4 text-sm font-semibold">Possible contributing factors</h3>
              <div className="mt-2 flex flex-wrap gap-2">
                {result.factors.map((f) => (
                  <span key={f} className="rounded-full bg-muted px-3 py-1 text-[11px] font-medium">
                    {f}
                  </span>
                ))}
              </div>
            </>
          ) : null}

          <h3 className="mt-5 text-sm font-semibold">Environmental risk assessment</h3>
          <ul className="mt-2 divide-y divide-border rounded-2xl border border-border/60">
            {envLabels.map(({ key, label }) => (
              <li key={key} className="flex items-center justify-between gap-3 px-3 py-2.5 text-sm">
                <span className="text-muted-foreground">{label}</span>
                <span className={`rounded-full px-2.5 py-1 text-[11px] font-semibold ${levelTone(result.environmental?.[key])}`}>
                  {result.environmental?.[key] ?? "Not assessed"}
                </span>
              </li>
            ))}
          </ul>

          <h3 className="mt-5 text-sm font-semibold">Possible water leakage detection</h3>
          <p className="mt-2 rounded-2xl bg-muted px-3 py-2 text-sm font-semibold">
            {result.leakage?.verdict ?? "No obvious signs detected"}
          </p>
          {result.leakage?.signs?.length ? (
            <div className="mt-2 flex flex-wrap gap-2">
              {result.leakage.signs.map((s) => (
                <span key={s} className="rounded-full bg-muted px-3 py-1 text-[11px] font-medium">
                  {s}
                </span>
              ))}
            </div>
          ) : null}
          <p className="mt-2 text-[11px] text-muted-foreground">
            This is a visual assessment only and not a definitive leak detection.
          </p>

          {result.recommendations?.length ? (
            <>
              <h3 className="mt-5 text-sm font-semibold">Recommended next steps</h3>
              <ul className="mt-2 space-y-1.5 text-sm text-muted-foreground">
                {result.recommendations.map((r) => (
                  <li key={r}>• {r}</li>
                ))}
              </ul>
            </>
          ) : null}

          <AiDisclaimer className="mt-4" />

          <MoldEducationPanel assessment={result} />

          <div className="mt-5 rounded-2xl border border-border/60 p-3">
            <h3 className="flex items-center gap-2 text-sm font-semibold">
              <FileText className="h-4 w-4 text-primary" />
              {buildingPdf ? "Generating professional PDF report…" : "Professional PDF report"}
            </h3>
            <p className="mt-1 text-[11px] text-muted-foreground">
              {reportNo ? `Report ${reportNo} · ` : ""}Emma-branded inspection report with annotated images, environmental
              charts, leakage analysis, conclusion and signature blocks.
            </p>
            {annotated.length ? (
              <div className="mt-3 flex gap-2 overflow-x-auto">
                {annotated.map((src, i) => (
                  <img
                    key={src.slice(-24)}
                    src={src}
                    alt={`Annotated image ${i + 1}`}
                    className="h-20 w-28 shrink-0 rounded-lg object-cover"
                  />
                ))}
              </div>
            ) : null}
            <ul className="mt-3 space-y-1 text-[11px] text-muted-foreground">
              {LEGEND.map((l) => (
                <li key={l.label} className="flex items-center gap-2">
                  <span className="inline-block h-3 w-4 rounded-sm border-2" style={{ borderColor: l.color }} />
                  {l.label}
                </li>
              ))}
            </ul>
            <p className="mt-3 text-[11px] text-muted-foreground">
              Download and Print always rebuild the report from the readings currently on this page, so every measurement
              you enter below is included.
            </p>
            {buildingPdf ? (
              <p className="mt-3 flex items-center gap-2 text-xs text-muted-foreground">
                <Loader2 className="h-3.5 w-3.5 animate-spin" /> Building report…
              </p>
            ) : null}
            <ReportActions
              blob={pdf}
              fileName={`${reportNo ?? "emma-report"}.pdf`}
              reportNo={reportNo ?? "—"}
              verdict={result.verdict}
              getBlob={() => buildPdf(result, true)}
              onSave={user ? saveResult : undefined}
            />
            {!user ? (
              <Link to="/auth" className="mt-2 block text-center text-xs font-semibold text-primary">
                Sign in to save this report to your history
              </Link>
            ) : null}
          </div>

          <Link
            to="/book"
            search={{ service: "mold-inspection", company: undefined }}
            className="mt-3 block rounded-2xl bg-brand py-3.5 text-center text-sm font-semibold text-primary-foreground"
          >
            Book Inspection
          </Link>
        </section>
      ) : null}

      <section className="mt-5 rounded-3xl border border-border/60 bg-card p-4 shadow-card">
        <h2 className="text-sm font-semibold">Inspector measurements</h2>
        <p className="mt-1 text-xs text-muted-foreground">
          Enter the raw readings from professional equipment — status, percentage score and the overall environmental
          risk are calculated automatically.
        </p>

        <div className="mt-4">
          <h3 className="flex items-center gap-2 text-sm font-semibold">
            <Thermometer className="h-4 w-4 text-primary" /> Temperature
          </h3>
          <label className="mt-2 block text-[11px] text-muted-foreground" htmlFor="temp-value">
            Measured value (°C)
          </label>
          <input
            id="temp-value"
            type="number"
            inputMode="decimal"
            value={temperatureValue}
            onChange={(e) => setTemperatureValue(e.target.value)}
            className="mt-1 w-full rounded-xl border border-border bg-background px-3 py-2 text-sm"
            placeholder="e.g. 27"
          />
          <ReadingBadge reading={tempReading} hint="Enter a temperature to calculate the status and score." />
        </div>

        <div className="mt-5">
          <h3 className="flex items-center gap-2 text-sm font-semibold">
            <Droplets className="h-4 w-4 text-primary" /> Humidity
          </h3>
          <label className="mt-2 block text-[11px] text-muted-foreground" htmlFor="hum-value">
            Measured value (% RH)
          </label>
          <input
            id="hum-value"
            type="number"
            inputMode="decimal"
            value={humidityValue}
            onChange={(e) => setHumidityValue(e.target.value)}
            className="mt-1 w-full rounded-xl border border-border bg-background px-3 py-2 text-sm"
            placeholder="e.g. 65"
          />
          <ReadingBadge reading={humReading} hint="Enter a relative humidity to calculate the status and score." />
        </div>

        <div className="mt-5">
          <h3 className="text-sm font-semibold">Moisture reading</h3>
          <p className="text-[11px] text-muted-foreground">From a professional moisture meter.</p>
          <Chips options={moistureOptions} value={moisture} onChange={setMoisture} />
          <ReadingBadge reading={moistReading} hint="Tap a reading to generate the moisture percentage." />
        </div>

        <div className="mt-5">
          <h3 className="text-sm font-semibold">Water detector reading</h3>
          <p className="text-[11px] text-muted-foreground">Entered after using a professional water leak detector.</p>
          <Chips options={detectorOptions} value={detector} onChange={setDetector} />
          <ReadingBadge reading={detReading} hint="Tap a reading to score the leak risk." />
        </div>

        {overall ? (
          <div className="mt-5 rounded-2xl border border-border/60 bg-muted/40 p-4">
            <h3 className="text-sm font-semibold">Overall environmental risk</h3>
            <div className="mt-2 flex items-center gap-2">
              <span className={`rounded-full px-3 py-1 text-[11px] font-semibold ${overall.tone}`}>{overall.risk}</span>
              <span className="text-[11px] font-semibold">{overall.score}%</span>
              <span className="h-2 flex-1 overflow-hidden rounded-full bg-background">
                <span
                  className="block h-full rounded-full"
                  style={{ width: `${overall.score}%`, backgroundColor: overall.hex }}
                />
              </span>
            </div>
            <p className="mt-2 text-[11px] leading-relaxed text-muted-foreground">{overall.explanation}</p>
          </div>
        ) : null}

        <div className="mt-5">
          <label className="text-sm font-semibold" htmlFor="inspector-comments">
            Inspector comments
          </label>
          <textarea
            id="inspector-comments"
            value={inspectorComments}
            onChange={(e) => setInspectorComments(e.target.value)}
            rows={3}
            className="mt-1 w-full rounded-xl border border-border bg-background px-3 py-2 text-sm"
            placeholder="Site observations to include in the professional report"
          />
        </div>

        <div className="mt-5">
          <h3 className="text-sm font-semibold">Thermal inspection</h3>
          <p className="text-[11px] text-muted-foreground">
            Upload an image from a compatible thermal camera to compare against the normal photo.
          </p>
          <div className="mt-2 grid grid-cols-2 gap-3">
            <figure>
              <figcaption className="text-[11px] font-semibold uppercase tracking-widest text-primary">Normal</figcaption>
              {image ? (
                <img src={image} alt="Normal photo" className="mt-1 w-full rounded-xl" />
              ) : (
                <div className="mt-1 flex h-24 items-center justify-center rounded-xl bg-muted text-[11px] text-muted-foreground">
                  No photo
                </div>
              )}
            </figure>
            <figure>
              <figcaption className="text-[11px] font-semibold uppercase tracking-widest text-primary">Thermal</figcaption>
              {thermal ? (
                <img src={thermal} alt="Thermal photo" className="mt-1 w-full rounded-xl" />
              ) : (
                <div className="mt-1 flex h-24 items-center justify-center rounded-xl bg-muted text-[11px] text-muted-foreground">
                  No thermal image
                </div>
              )}
            </figure>
          </div>
          <button
            onClick={() => thermalRef.current?.click()}
            className="mt-3 flex w-full items-center justify-center gap-2 rounded-2xl border border-border py-3 text-sm font-semibold"
          >
            <Upload className="h-4 w-4" /> Upload thermal image
          </button>
          <input ref={thermalRef} type="file" accept="image/*" hidden onChange={onPickThermal} />
          <label className="mt-3 block text-[11px] text-muted-foreground" htmlFor="thermal-notes">
            Observed cold spots or temperature differences
          </label>
          <textarea
            id="thermal-notes"
            value={thermalNotes}
            onChange={(e) => setThermalNotes(e.target.value)}
            rows={3}
            className="mt-1 w-full rounded-xl border border-border bg-background px-3 py-2 text-sm"
            placeholder="e.g. cooler band along the lower wall near the window"
          />
          <p className="mt-2 text-[11px] text-muted-foreground">
            Temperature differences are only reported when a thermal image is provided; they do not confirm hidden leaks.
          </p>
        </div>
      </section>

      <AiDisclaimer className="mt-5" />
    </AppShell>
  );
}
