// Auteur : Simon-Pierre Boucher — contact@spboucher.ai
"use client";
import { useEffect, useState } from "react";
import Link from "next/link";
import SearchBox, { type Suggestion } from "@/components/SearchBox";
import { CountUp, locNum, Sparkline, ValueSplit } from "@/components/MetricViz";
import { useLang } from "@/components/LangContext";
import type { PortfolioResult } from "@/lib/estimator";
import type { TKey } from "@/lib/i18n";

const KEY = "vp-parc";

interface Saved {
  id: string;
  adresse: string;
  municipalite: string;
}

const fmt = (v: number | null | undefined, lang: string) =>
  v == null
    ? "—"
    : new Intl.NumberFormat(lang === "fr" ? "fr-CA" : "en-CA", {
        style: "currency",
        currency: "CAD",
        maximumFractionDigits: 0,
      }).format(v);

const CONF: Record<string, string> = {
  A: "pill-conf-A",
  B: "pill-conf-B",
  C: "pill-conf-C",
  D: "pill-conf-D",
};

export default function ParcPage() {
  const { lang, t } = useLang();
  const fr = lang === "fr";
  const [list, setList] = useState<Saved[]>([]);
  const [data, setData] = useState<PortfolioResult | null>(null);
  const [loading, setLoading] = useState(false);
  const [hydrated, setHydrated] = useState(false);

  useEffect(() => {
    const id = setTimeout(() => {
      try {
        const raw = window.localStorage.getItem(KEY);
        if (raw) setList(JSON.parse(raw) as Saved[]);
      } catch {}
      setHydrated(true);
    }, 0);
    return () => clearTimeout(id);
  }, []);

  const persist = (l: Saved[]) => {
    setList(l);
    window.localStorage.setItem(KEY, JSON.stringify(l));
    setData(null);
  };

  const add = (s: Suggestion) => {
    if (list.some((x) => x.id === s.id) || list.length >= 40) return;
    persist([
      ...list,
      {
        id: s.id,
        adresse: `${s.adresse ?? ""}${s.apt ? ` app. ${s.apt}` : ""}`,
        municipalite: s.municipalite ?? "",
      },
    ]);
  };

  const evaluate = async () => {
    setLoading(true);
    try {
      const res = await fetch("/api/portfolio", {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({ ids: list.map((x) => x.id) }),
      });
      if (res.ok) setData((await res.json()) as PortfolioResult);
    } finally {
      setLoading(false);
    }
  };

  const a = data?.aggregates;

  return (
    <div className="pb-6 pt-10 sm:pt-14">
      {/* héros */}
      <section>
        <span className="kicker">{fr ? "Investisseurs · propriétaires multiples" : "Investors · multi-owners"}</span>
        <h1 className="vp-display mt-3 max-w-4xl text-[clamp(30px,5.6vw,62px)] font-bold uppercase leading-[0.98] tracking-[-0.035em]">
          {fr ? (
            <>
              La valeur de votre <span className="hl">parc immobilier</span>,
              <br />
              <span className="outline-txt">au complet.</span>
            </>
          ) : (
            <>
              Your <span className="hl">property portfolio</span>,
              <br />
              <span className="outline-txt">fully valued.</span>
            </>
          )}
        </h1>
        <p className="mt-4 max-w-xl text-[16px] text-ink-2">
          {fr
            ? "Ajoutez chacune de vos adresses. Vrai-Prix évalue chaque propriété, agrège votre parc — valeur totale, fourchette, croissance 2021→2026 — et produit un rapport PDF consolidé."
            : "Add each of your addresses. Vrai-Prix values every property, aggregates your portfolio — total value, range, 2021→2026 growth — and produces a consolidated PDF report."}
        </p>
      </section>

      {/* constructeur de parc */}
      <section className="mt-9">
        <div className="vp-card p-4 sm:p-5">
          <p className="klabel mb-2 pl-0.5">
            {fr ? `Ajouter une propriété (${list.length}/40)` : `Add a property (${list.length}/40)`}
          </p>
          <SearchBox
            onPick={add}
            placeholder={fr ? "Tapez une adresse puis choisissez-la…" : "Type an address, then pick it…"}
          />
          {hydrated && list.length > 0 && (
            <div className="mt-4 flex flex-wrap gap-2">
              {list.map((p, i) => (
                <span
                  key={p.id}
                  className="stat-chip !py-1.5"
                  style={{ animationDelay: `${i * 40}ms` }}
                >
                  <b>{i + 1}</b> {p.adresse} · {p.municipalite}
                  <button
                    aria-label={fr ? "Retirer" : "Remove"}
                    onClick={() => persist(list.filter((x) => x.id !== p.id))}
                    className="vp-mono ml-1 cursor-pointer rounded-full border-[1.5px] border-ink px-1.5 text-[10px] font-bold hover:bg-ink hover:text-lime"
                  >
                    ✕
                  </button>
                </span>
              ))}
            </div>
          )}
          <div className="mt-4 flex flex-wrap gap-2.5">
            <button
              className="btn btn-primary"
              disabled={list.length === 0 || loading}
              onClick={evaluate}
            >
              {loading
                ? fr ? "Évaluation en cours…" : "Valuing…"
                : fr ? `Évaluer mon parc (${list.length})` : `Value my portfolio (${list.length})`}
            </button>
            {list.length > 0 && (
              <button className="btn btn-ghost" onClick={() => persist([])}>
                {fr ? "Vider la liste" : "Clear list"}
              </button>
            )}
          </div>
        </div>
      </section>

      {/* résultats */}
      {data && a && (
        <div className="mt-12 space-y-10">
          {/* total */}
          <section className="vp-card p-6 sm:p-8">
            <span className="kicker">{fr ? "Valeur totale estimée du parc" : "Total estimated portfolio value"}</span>
            <p className="vp-display mt-3 text-[clamp(40px,7vw,68px)] font-bold leading-none tracking-[-0.04em]">
              <CountUp
                value={a.totalEstimate}
                format={(v) =>
                  new Intl.NumberFormat(fr ? "fr-CA" : "en-CA", {
                    style: "currency",
                    currency: "CAD",
                    maximumFractionDigits: 0,
                  }).format(Math.round(v / 100) * 100)
                }
              />
            </p>
            <div className="mt-5 flex flex-wrap items-center gap-x-6 gap-y-3">
              <div>
                <p className="klabel">{fr ? "Fourchette cumulée" : "Cumulative range"}</p>
                <p className="vp-display text-[18px] font-bold">
                  {fmt(a.totalLow, lang)} <span className="text-ink-3">→</span> {fmt(a.totalHigh, lang)}
                </p>
              </div>
              <div>
                <p className="klabel">{fr ? "Confiance pondérée" : "Weighted confidence"}</p>
                <span className={`pill ${CONF[a.confidenceLevel]}`}>
                  {a.confidenceLevel} · {a.confidencePct} %
                </span>
              </div>
              <div>
                <p className="klabel">{fr ? "Évaluation municipale" : "Municipal assessment"}</p>
                <p className="vp-display text-[18px] font-bold text-ink-2">{fmt(a.totalRole, lang)}</p>
              </div>
            </div>
            <a
              href={`/api/report/portfolio?ids=${data.items.map((i) => i.unit!.id).join(",")}`}
              className="btn btn-primary mt-6"
              download
            >
              {fr
                ? `Télécharger le rapport de parc (${1 + data.items.length} pages PDF)`
                : `Download the portfolio report (${1 + data.items.length} PDF pages)`}{" "}
              ↓
            </a>
          </section>

          {/* tuiles registre */}
          <section>
            <span className="kicker">{fr ? "Votre parc, en chiffres du registre" : "Your portfolio, in registry numbers"}</span>
            <div className="mt-4 grid grid-cols-2 gap-3.5 sm:grid-cols-4">
              {(
                [
                  [fr ? "Propriétés" : "Properties", String(a.count), true],
                  [fr ? "Écart vs rôle" : "vs assessment", a.ecartRolePct != null ? `${a.ecartRolePct >= 0 ? "+" : ""}${a.ecartRolePct.toFixed(0)} %` : "—", false],
                  [fr ? "Croissance 2021→2026" : "Growth 2021→2026", a.growthPct != null ? `${a.growthPct >= 0 ? "+" : ""}${a.growthPct.toFixed(0)} %` : "—", true],
                  [fr ? "Logements" : "Dwellings", String(a.totalDwellings), false],
                  [fr ? "Aire habitable" : "Living area", `${a.totalFloorArea.toLocaleString(fr ? "fr-CA" : "en-CA")} m²`, false],
                  [fr ? "Terrain total" : "Total land", `${a.totalLandArea.toLocaleString(fr ? "fr-CA" : "en-CA")} m²`, false],
                  [fr ? "Année moyenne" : "Avg. year built", a.avgYearBuilt ? String(a.avgYearBuilt) : "—", false],
                  [fr ? "Municipalités" : "Municipalities", String(a.municipalities.length), false],
                ] as [string, string, boolean][]
              ).map(([k, v, hero]) => (
                <div
                  key={k}
                  className={`vp-card vp-card-hover p-4 ${hero ? "!bg-ink" : ""}`}
                >
                  <p className={`vp-display text-[clamp(20px,2.6vw,28px)] font-bold leading-tight tracking-[-0.03em] ${hero ? "text-lime" : "text-ink"}`}>
                    {v}
                  </p>
                  <p className={`vp-mono mt-1.5 text-[10px] font-bold uppercase tracking-[0.1em] ${hero ? "text-[rgba(255,81,72,0.7)]" : "text-ink-3"}`}>
                    {k}
                  </p>
                </div>
              ))}
            </div>
          </section>

          {/* historique du parc + répartitions */}
          <section className="grid gap-4 lg:grid-cols-[1.4fr_1fr]">
            <div className="vp-card p-5 sm:p-6">
              <p className="klabel mb-3">{fr ? "Valeur du parc par année" : "Portfolio value by year"}</p>
              <div className="flex flex-col gap-2">
                {a.history.map((h) => {
                  const max = Math.max(...a.history.map((x) => x.total), 1);
                  return (
                    <div key={h.year} className="hbar-row grid grid-cols-[46px_1fr_auto] items-center gap-3">
                      <span className="vp-mono text-[12px] font-bold">{h.year}</span>
                      <span className="hbar-track !h-[22px]">
                        <span
                          className="hbar-fill !rounded-r-[6px]"
                          style={{ width: `${(h.total / max) * 100}%`, background: h.year === 2026 ? "var(--ink)" : undefined }}
                        />
                      </span>
                      <span className="vp-mono text-[12px] font-bold">
                        {fmt(h.total, lang)}
                        {h.nCovered < a.count && (
                          <span className="text-ink-3"> ({h.nCovered}/{a.count})</span>
                        )}
                      </span>
                    </div>
                  );
                })}
              </div>
            </div>
            <div className="vp-card p-5 sm:p-6">
              <p className="klabel mb-3">{fr ? "Répartition" : "Breakdown"}</p>
              <div className="space-y-2">
                {a.municipalities.slice(0, 4).map((m) => (
                  <div key={m.name} className="flex items-baseline justify-between gap-3 border-b border-dashed border-[rgba(20,24,20,0.14)] pb-1.5">
                    <span className="vp-display text-[14px] font-bold">{m.name}</span>
                    <span className="vp-mono text-[11px] text-ink-2">
                      {m.count} · {fmt(m.total, lang)}
                    </span>
                  </div>
                ))}
                {a.types.map((tp) => (
                  <div key={tp.type} className="flex items-baseline justify-between gap-3 border-b border-dashed border-[rgba(20,24,20,0.14)] pb-1.5 last:border-0">
                    <span className="text-[13px] font-semibold text-ink-2">{t(tp.type as TKey)}</span>
                    <span className="vp-mono text-[11px] text-ink-2">
                      {tp.count} · {fmt(tp.total, lang)}
                    </span>
                  </div>
                ))}
              </div>
            </div>
          </section>

          {/* cartes propriétés */}
          <section>
            <span className="kicker">{fr ? "Chaque propriété du parc" : "Every property in the portfolio"}</span>
            <div className="mt-4 grid gap-4 sm:grid-cols-2">
              {data.items.map((it, i) => {
                const u = it.unit!;
                const r = it.result;
                return (
                  <Link
                    key={u.id}
                    href={`/estimation/${u.id}`}
                    className="vp-card vp-card-hover rise block p-5"
                    style={{ animationDelay: `${i * 70}ms` }}
                  >
                    <div className="flex items-start justify-between gap-3">
                      <div>
                        <p className="vp-mono text-[10px] font-bold text-green">
                          {String(i + 1).padStart(2, "0")}
                        </p>
                        <p className="vp-display mt-0.5 text-[16px] font-bold uppercase leading-tight">
                          {u.adresse}
                        </p>
                        <p className="vp-mono mt-0.5 text-[10.5px] uppercase tracking-[0.05em] text-ink-3">
                          {u.municipalite} · {u.anneeConstruction ?? "—"} ·{" "}
                          {u.aireEtagesM2 ? locNum(u.aireEtagesM2, lang, { unit: "m²" }) : "—"}
                        </p>
                      </div>
                      <span className={`pill ${CONF[r.confidenceLevel]} shrink-0`}>
                        {r.confidenceLevel}
                      </span>
                    </div>
                    <div className="mt-3 flex items-end justify-between gap-3 border-t-[1.5px] border-dashed border-[rgba(20,24,20,0.14)] pt-3">
                      <div>
                        <p className="vp-display text-[22px] font-bold tracking-[-0.02em]">
                          {fmt(r.estimate, lang)}
                        </p>
                        <p className="vp-mono text-[10.5px] text-ink-3">
                          {fr ? "rôle" : "roll"} {fmt(u.valeurRole, lang)}
                        </p>
                      </div>
                      <Sparkline history={u.history} />
                    </div>
                    <div className="mt-3">
                      <ValueSplit
                        land={u.specs.valeurTerrain}
                        building={u.specs.valeurBatiment}
                        previous={null}
                        total={u.valeurRole}
                        lang={lang}
                        labels={{
                          land: fr ? "Terrain" : "Land",
                          building: fr ? "Bâtiment" : "Building",
                          previous: "",
                        }}
                      />
                    </div>
                  </Link>
                );
              })}
            </div>
          </section>
        </div>
      )}
    </div>
  );
}
