import { createFileRoute } from "@tanstack/react-router";
import { useMemo, useState } from "react";
import { Calculator, Plus, Trash2, Info } from "lucide-react";
import { PageHero } from "@/components/PageHero";
import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label";
import { Button } from "@/components/ui/button";

export const Route = createFileRoute("/calculator")({
  head: () => ({
    meta: [
      { title: "Paint Calculator — Estimate Paint Quantity & Cost | Classic Paints" },
      { name: "description", content: "Calculate exactly how many litres of paint you need and the total cost based on wall area, paint type and number of coats." },
      { property: "og:title", content: "Classic Paints — Paint Calculator" },
      { property: "og:description", content: "Estimate paint quantity and cost in seconds. Add multiple surfaces and compare finishes." },
    ],
  }),
  component: CalculatorPage,
});

type PaintType = {
  id: string;
  name: string;
  coverage: number; // sqm per litre per coat
  pricePerLitre: number; // BDT
  finish: string;
};

const paintTypes: PaintType[] = [
  { id: "interior-emulsion", name: "Classic Interior Emulsion", coverage: 12, pricePerLitre: 520, finish: "Matt / Velvet" },
  { id: "premium-emulsion", name: "Classic Premium Silk", coverage: 13, pricePerLitre: 720, finish: "Silk" },
  { id: "exterior-weatherproof", name: "Classic Weatherproof Exterior", coverage: 10, pricePerLitre: 880, finish: "Smooth Matt" },
  { id: "distemper", name: "Classic Acrylic Distemper", coverage: 14, pricePerLitre: 320, finish: "Matt" },
  { id: "enamel", name: "Classic Synthetic Enamel", coverage: 14, pricePerLitre: 950, finish: "Gloss" },
  { id: "primer", name: "Classic Wall Primer", coverage: 11, pricePerLitre: 380, finish: "Matt" },
];

type Surface = {
  id: string;
  label: string;
  unit: "sqm" | "sqft";
  length: number;
  height: number;
  deductions: number; // doors/windows area in chosen unit
  paintId: string;
  coats: number;
};

const SQFT_PER_SQM = 10.7639;

const newSurface = (i: number): Surface => ({
  id: crypto.randomUUID(),
  label: `Surface ${i}`,
  unit: "sqft",
  length: 12,
  height: 10,
  deductions: 21,
  paintId: paintTypes[0].id,
  coats: 2,
});

function CalculatorPage() {
  const [surfaces, setSurfaces] = useState<Surface[]>([newSurface(1)]);
  const [wastePct, setWastePct] = useState(10);

  const update = (id: string, patch: Partial<Surface>) =>
    setSurfaces((s) => s.map((x) => (x.id === id ? { ...x, ...patch } : x)));
  const remove = (id: string) => setSurfaces((s) => s.filter((x) => x.id !== id));
  const add = () => setSurfaces((s) => [...s, newSurface(s.length + 1)]);

  const rows = useMemo(() => surfaces.map((s) => {
    const grossUnit = Math.max(0, s.length * s.height);
    const netUnit = Math.max(0, grossUnit - s.deductions);
    const netSqm = s.unit === "sqm" ? netUnit : netUnit / SQFT_PER_SQM;
    const paint = paintTypes.find((p) => p.id === s.paintId) ?? paintTypes[0];
    const litres = (netSqm * s.coats) / paint.coverage;
    const litresWithWaste = litres * (1 + wastePct / 100);
    const cost = litresWithWaste * paint.pricePerLitre;
    return { s, paint, netSqm, litres: litresWithWaste, cost };
  }), [surfaces, wastePct]);

  const totals = rows.reduce(
    (acc, r) => ({ litres: acc.litres + r.litres, cost: acc.cost + r.cost, area: acc.area + r.netSqm }),
    { litres: 0, cost: 0, area: 0 }
  );

  const fmtBDT = (n: number) => `৳${Math.round(n).toLocaleString("en-IN")}`;

  return (
    <>
      <PageHero
        eyebrow="Paint Calculator"
        title={<>Estimate paint, <span className="text-brand-red">accurately</span></>}
        description="Enter your wall dimensions, choose a Classic Paints product and number of coats — we'll calculate litres needed and total cost."
      />

      <section className="pb-24">
        <div className="container-regent grid lg:grid-cols-[1fr_360px] gap-8">
          {/* Inputs */}
          <div className="space-y-4">
            {surfaces.map((s, i) => {
              const paint = paintTypes.find((p) => p.id === s.paintId) ?? paintTypes[0];
              return (
                <div key={s.id} className="border border-border bg-card p-5 md:p-6">
                  <div className="flex items-center justify-between mb-4">
                    <div className="flex items-center gap-3">
                      <span className="h-7 w-7 grid place-items-center bg-brand-red text-white text-xs">{i + 1}</span>
                      <Input
                        value={s.label}
                        onChange={(e) => update(s.id, { label: e.target.value })}
                        className="h-8 text-sm border-0 bg-transparent px-0 focus-visible:ring-0"
                      />
                    </div>
                    {surfaces.length > 1 && (
                      <button onClick={() => remove(s.id)} className="text-muted-foreground hover:text-brand-red" aria-label="Remove surface">
                        <Trash2 className="h-4 w-4" />
                      </button>
                    )}
                  </div>

                  <div className="grid sm:grid-cols-3 gap-4">
                    <div>
                      <Label className="text-[10px] uppercase tracking-wider-x text-muted-foreground">Unit</Label>
                      <select
                        value={s.unit}
                        onChange={(e) => update(s.id, { unit: e.target.value as "sqm" | "sqft" })}
                        className="mt-1.5 w-full h-10 px-3 bg-background border border-border text-sm"
                      >
                        <option value="sqft">Feet</option>
                        <option value="sqm">Metres</option>
                      </select>
                    </div>
                    <div>
                      <Label className="text-[10px] uppercase tracking-wider-x text-muted-foreground">Length / Perimeter</Label>
                      <Input type="number" min={0} value={s.length} onChange={(e) => update(s.id, { length: +e.target.value })} className="mt-1.5" />
                    </div>
                    <div>
                      <Label className="text-[10px] uppercase tracking-wider-x text-muted-foreground">Height</Label>
                      <Input type="number" min={0} value={s.height} onChange={(e) => update(s.id, { height: +e.target.value })} className="mt-1.5" />
                    </div>
                    <div className="sm:col-span-3">
                      <Label className="text-[10px] uppercase tracking-wider-x text-muted-foreground flex items-center gap-1.5">
                        Deduct doors / windows ({s.unit})
                        <span title="Subtract total area of doors and windows" className="text-muted-foreground/60"><Info className="h-3 w-3" /></span>
                      </Label>
                      <Input type="number" min={0} value={s.deductions} onChange={(e) => update(s.id, { deductions: +e.target.value })} className="mt-1.5" />
                    </div>
                    <div className="sm:col-span-2">
                      <Label className="text-[10px] uppercase tracking-wider-x text-muted-foreground">Paint product</Label>
                      <select
                        value={s.paintId}
                        onChange={(e) => update(s.id, { paintId: e.target.value })}
                        className="mt-1.5 w-full h-10 px-3 bg-background border border-border text-sm"
                      >
                        {paintTypes.map((p) => (
                          <option key={p.id} value={p.id}>{p.name} — {fmtBDT(p.pricePerLitre)}/L</option>
                        ))}
                      </select>
                      <div className="mt-1.5 text-[10px] text-muted-foreground uppercase tracking-wider-x">
                        {paint.finish} • Coverage {paint.coverage} m²/L/coat
                      </div>
                    </div>
                    <div>
                      <Label className="text-[10px] uppercase tracking-wider-x text-muted-foreground">Coats</Label>
                      <select
                        value={s.coats}
                        onChange={(e) => update(s.id, { coats: +e.target.value })}
                        className="mt-1.5 w-full h-10 px-3 bg-background border border-border text-sm"
                      >
                        {[1, 2, 3, 4].map((n) => <option key={n} value={n}>{n} coat{n > 1 ? "s" : ""}</option>)}
                      </select>
                    </div>
                  </div>
                </div>
              );
            })}

            <Button variant="outline" onClick={add} className="w-full">
              <Plus className="h-4 w-4 mr-1.5" />Add another surface
            </Button>
          </div>

          {/* Summary */}
          <aside className="lg:sticky lg:top-28 self-start space-y-4">
            <div className="border border-border bg-card p-6">
              <div className="flex items-center gap-2 mb-4">
                <Calculator className="h-4 w-4 text-brand-red" />
                <h2 className="text-[11px] uppercase tracking-wider-x">Estimate</h2>
              </div>

              <div className="space-y-3 mb-5">
                {rows.map((r, i) => (
                  <div key={r.s.id} className="flex justify-between text-sm border-b border-border/60 pb-2 last:border-0">
                    <div>
                      <div>{r.s.label || `Surface ${i + 1}`}</div>
                      <div className="text-[10px] uppercase tracking-wider-x text-muted-foreground">{r.netSqm.toFixed(1)} m² • {r.s.coats} coats</div>
                    </div>
                    <div className="text-right">
                      <div>{r.litres.toFixed(1)} L</div>
                      <div className="text-[10px] uppercase tracking-wider-x text-muted-foreground">{fmtBDT(r.cost)}</div>
                    </div>
                  </div>
                ))}
              </div>

              <div>
                <Label className="text-[10px] uppercase tracking-wider-x text-muted-foreground">Wastage allowance: {wastePct}%</Label>
                <input type="range" min={0} max={25} step={1} value={wastePct} onChange={(e) => setWastePct(+e.target.value)} className="w-full mt-2 accent-brand-red" />
              </div>

              <div className="mt-5 pt-5 border-t border-border space-y-1">
                <div className="flex justify-between text-sm text-muted-foreground">
                  <span>Total area</span><span>{totals.area.toFixed(1)} m²</span>
                </div>
                <div className="flex justify-between text-sm text-muted-foreground">
                  <span>Total paint</span><span>{totals.litres.toFixed(1)} L</span>
                </div>
                <div className="flex justify-between mt-3 pt-3 border-t border-border">
                  <span className="text-[11px] uppercase tracking-wider-x">Estimated cost</span>
                  <span className="text-2xl extralight text-brand-red tabular-nums">{fmtBDT(totals.cost)}</span>
                </div>
              </div>

              <Button asChild className="w-full mt-5 bg-brand-red text-white hover:bg-brand-red/90">
                <a href="/find-dealer">Find nearest dealer</a>
              </Button>
            </div>
            <p className="text-[10px] uppercase tracking-wider-x text-muted-foreground leading-relaxed">
              Estimates assume average surface absorbency. Actual usage may vary by texture, porosity and application method.
            </p>
          </aside>
        </div>
      </section>
    </>
  );
}
