import { createFileRoute } from "@tanstack/react-router";
import { useRef, useState } from "react";
import { toast } from "sonner";
import { Loader2, Thermometer, Upload } from "lucide-react";
import { AppShell } from "@/components/AppShell";
import { AiDisclaimer } from "@/components/AiDisclaimer";
import { ReportActions } from "@/components/ReportActions";
import { supabase } from "@/integrations/supabase/client";
import { useAuth } from "@/lib/use-auth";
import { generateReport, makeReportNo, uploadReportPdf } from "@/lib/report-actions";
import { COMPANY } from "@/lib/company";
import type { Assessment } from "@/lib/report-types";

export const Route = createFileRoute("/_authenticated/thermal")({
  head: () => ({
    meta: [
      { title: "Thermal Inspection | Emma Mold Inspection Services" },
      {
        name: "description",
        content:
          "Upload thermal camera images to review heat maps, cold spots and possible moisture intrusion behind walls and ceilings.",
      },
      { property: "og:title", content: "Thermal Inspection" },
      { property: "og:description", content: "Heat maps, cold spots and possible hidden damp areas from thermal images." },
      { property: "og:type", content: "website" },
      { name: "twitter:card", content: "summary_large_image" },
    ],
  }),
  component: ThermalPage,
});

type ThermalResult = Assessment;

function ThermalPage() {
  const { user } = useAuth();
  const thermalRef = useRef<HTMLInputElement>(null);
  const normalRef = useRef<HTMLInputElement>(null);
  const [thermal, setThermal] = useState<string | null>(null);
  const [normal, setNormal] = useState<string | null>(null);
  const [notes, setNotes] = useState("");
  const [busy, setBusy] = useState(false);
  const [result, setResult] = useState<ThermalResult | null>(null);
  const [reportNo, setReportNo] = useState<string | null>(null);
  const [pdf, setPdf] = useState<Blob | null>(null);

  function pick(e: React.ChangeEvent<HTMLInputElement>, set: (v: string) => void) {
    const file = e.target.files?.[0];
    e.target.value = "";
    if (!file) return;
    if (file.size > 8 * 1024 * 1024) return toast.error("Please choose an image under 8MB.");
    const reader = new FileReader();
    reader.onload = () => set(reader.result as string);
    reader.readAsDataURL(file);
  }

  async function analyze() {
    if (!thermal) return;
    setBusy(true);
    try {
      const res = await fetch("/api/analyze-mold", {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({ imageDataUrl: normal ?? thermal, thermalDataUrl: thermal, mediaType: "thermal" }),
      });
      const data = await res.json();
      if (!res.ok) throw new Error(data.error ?? "Thermal analysis failed.");
      const assessment = data as ThermalResult;
      setResult(assessment);
      await buildPdf(assessment);
    } catch (error) {
      toast.error(error instanceof Error ? error.message : "Thermal analysis failed.");
    } finally {
      setBusy(false);
    }
  }

  async function buildPdf(assessment: ThermalResult) {
    const no = reportNo ?? makeReportNo();
    setReportNo(no);
    try {
      const { blob } = await generateReport({
        reportNo: no,
        createdAt: new Date(),
        customerName: user?.email ?? "Not provided",
        propertyAddress: "",
        analysisType: "Photo",
        images: normal ? [{ dataUrl: normal, caption: "Normal image of the inspected area" }] : [],
        annotated: [],
        thermalImage: thermal,
        thermalNormal: normal,
        measurements: { thermalNotes: notes, inspectorComments: notes },
        assessment,
        verifyUrl: `${COMPANY.website}/reports/${no}`,
      });
      setPdf(blob);
      return blob;
    } catch (error) {
      console.error("Thermal PDF build failed", error);
      throw error instanceof Error ? error : new Error("The thermal PDF report could not be generated.");
    }
  }

  async function save() {
    if (!result || !user) return;
    const no = reportNo ?? makeReportNo();
    let pdfPath: string | null = null;
    try {
      const blob = pdf ?? (await buildPdf(result));
      if (blob) pdfPath = await uploadReportPdf(blob, user.id, no);
    } catch {
      pdfPath = null;
    }
    const { error } = await supabase.from("mold_scans").insert({
      user_id: user.id,
      media_type: "thermal",
      report_no: no,
      pdf_path: pdfPath,
      analysis: JSON.parse(JSON.stringify(result)),
      verdict: result.verdict,
      confidence: 0,
      severity: result.severity ?? "Low",
      factors: result.factors ?? [],
      recommendations: result.recommendations ?? [],
      summary: result.summary,
      leakage_verdict: result.leakage?.verdict ?? null,
      leakage_signs: result.leakage?.signs ?? [],
      thermal_notes: [result.thermal?.notes, notes].filter(Boolean).join(" — ") || null,
    });
    if (error) return toast.error("Could not save this thermal inspection.");
    toast.success("Thermal inspection saved to your reports.");
  }

  return (
    <AppShell>
      <h1 className="flex items-center gap-2 text-2xl font-bold">
        <Thermometer className="h-6 w-6 text-primary" /> Thermal Inspection
      </h1>
      <p className="mt-1 text-sm text-muted-foreground">
        Upload an image from a thermal camera to review heat patterns, cold spots and possible moisture intrusion.
      </p>
      <p className="mt-3 rounded-2xl bg-muted p-3 text-[11px] text-muted-foreground">
        Standard smartphone cameras do not produce true thermal images. Use a FLIR-compatible or other thermal device and
        upload the resulting image here.
      </p>

      <section className="mt-5 rounded-3xl border border-border/60 bg-card p-4 shadow-card">
        <div className="grid grid-cols-2 gap-3">
          <figure>
            <figcaption className="text-[11px] font-semibold uppercase tracking-widest text-primary">Normal</figcaption>
            {normal ? (
              <img src={normal} alt="Normal photo of the area" className="mt-1 w-full rounded-xl" />
            ) : (
              <div className="mt-1 flex h-28 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 heat map of the area" className="mt-1 w-full rounded-xl" />
            ) : (
              <div className="mt-1 flex h-28 items-center justify-center rounded-xl bg-muted text-[11px] text-muted-foreground">
                No thermal image
              </div>
            )}
          </figure>
        </div>

        <div className="mt-3 grid grid-cols-2 gap-3">
          <button
            onClick={() => normalRef.current?.click()}
            className="flex items-center justify-center gap-2 rounded-2xl border border-border py-3 text-sm font-semibold"
          >
            <Upload className="h-4 w-4" /> Normal image
          </button>
          <button
            onClick={() => thermalRef.current?.click()}
            className="flex items-center justify-center gap-2 rounded-2xl bg-brand py-3 text-sm font-semibold text-primary-foreground"
          >
            <Upload className="h-4 w-4" /> Thermal image
          </button>
        </div>
        <input ref={normalRef} type="file" accept="image/*" hidden onChange={(e) => pick(e, setNormal)} />
        <input ref={thermalRef} type="file" accept="image/*" hidden onChange={(e) => pick(e, setThermal)} />

        <label className="mt-4 block text-[11px] text-muted-foreground" htmlFor="inspector-notes">
          Inspector notes on cold spots or temperature differences
        </label>
        <textarea
          id="inspector-notes"
          rows={3}
          value={notes}
          onChange={(e) => setNotes(e.target.value)}
          className="mt-1 w-full rounded-xl border border-border bg-background px-3 py-2 text-sm"
          placeholder="e.g. cool band along the lower wall beneath the window"
        />

        <button
          onClick={analyze}
          disabled={!thermal || busy}
          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 disabled:opacity-50"
        >
          {busy ? <Loader2 className="h-4 w-4 animate-spin" /> : <Thermometer className="h-4 w-4" />}
          {busy ? "Analyzing…" : "Analyze thermal image"}
        </button>
      </section>

      {result ? (
        <section className="mt-5 rounded-3xl border border-border/60 bg-card p-4 shadow-card">
          <h2 className="text-lg font-semibold">{result.verdict}</h2>
          <p className="mt-2 text-sm text-muted-foreground">{result.summary}</p>
          <dl className="mt-3 divide-y divide-border rounded-2xl border border-border/60 text-sm">
            <div className="flex justify-between gap-3 px-3 py-2.5">
              <dt className="text-muted-foreground">Cold spots</dt>
              <dd className="font-semibold">{result.thermal?.coldSpots ?? "Not assessed"}</dd>
            </div>
            <div className="flex justify-between gap-3 px-3 py-2.5">
              <dt className="text-muted-foreground">Possible water leakage</dt>
              <dd className="font-semibold">{result.leakage?.verdict ?? "No obvious signs detected"}</dd>
            </div>
          </dl>
          {result.thermal?.notes ? <p className="mt-2 text-sm text-muted-foreground">{result.thermal.notes}</p> : null}
          {result.recommendations?.length ? (
            <ul className="mt-3 space-y-1.5 text-sm text-muted-foreground">
              {result.recommendations.map((r) => (
                <li key={r}>• {r}</li>
              ))}
            </ul>
          ) : null}
          <ReportActions
            blob={pdf}
            fileName={`${reportNo ?? "emma-thermal-report"}.pdf`}
            reportNo={reportNo ?? "—"}
            verdict={result.verdict}
            getBlob={() => buildPdf(result)}
            onSave={async () => {
              await save();
            }}
            saveLabel="Save to my reports"
          />
        </section>
      ) : null}

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