"use client";
import { useMemo, useState } from "react";
import {
  onderdeelCategorieLabels,
  nazichtStatusLabels,
  taalLabels,
  vindOnderdeelTegenhanger,
  vulOnderdeelVoorbeeldPlatIn,
  extraheerParameters,
  bouwParameterCatalogus,
  vindParameterInfo,
  type Modelonderdeel,
  type NazichtStatus,
  type OnderdeelCategorie,
  type OnderdeelHistoriek,
  type Wijzigingsvoorstel,
} from "@/data/modeldocumenten";
import { OnderdeelEditor } from "./OnderdeelEditor";
import { VoorstelFormulier } from "./VoorstelFormulier";
import { VoorbeeldTweeKolommen } from "./VoorbeeldTweeKolommen";
import { useMeervoudigeSelectie } from "@/lib/hooks/useMeervoudigeSelectie";

export function OnderdelenTab({
  alleOnderdelen,
  slaOp,
  verwijder,
  slaVoorstelOp,
  naarValideren,
  historiek,
  herstelVersie,
}: {
  alleOnderdelen: Modelonderdeel[];
  slaOp: (o: Modelonderdeel) => Promise<void>;
  verwijder: (id: string) => Promise<void>;
  slaVoorstelOp: (v: Wijzigingsvoorstel) => Promise<void>;
  naarValideren: () => void;
  historiek: OnderdeelHistoriek[];
  herstelVersie: (oudeVersie: Modelonderdeel) => Promise<void>;
}) {
  const [zoek, setZoek] = useState("");
  const [categorie, setCategorie] = useState<OnderdeelCategorie | "alle">("alle");
  const [nazicht, setNazicht] = useState<NazichtStatus | "alle">("alle");
  const [openId, setOpenId] = useState<string | null>(null);
  const [editor, setEditor] = useState<{ basis?: Modelonderdeel; modus: "nieuw" | "bewerk" } | null>(null);
  const [voorstel, setVoorstel] = useState<{ basis?: Modelonderdeel } | null>(null);

  const gefilterd = useMemo(() => {
    const term = zoek.trim().toLowerCase();
    return alleOnderdelen.filter((o) => {
      if (categorie !== "alle" && o.categorie !== categorie) return false;
      if (nazicht !== "alle" && (o.nazicht?.status ?? "actueel") !== nazicht) return false;
      if (!term) return true;
      const inhoud = [o.titel, o.omschrijving, o.tekst, ...o.varianten.map((v) => v.hypothese + " " + v.tekst), ...o.toepasbaarOp]
        .join(" ")
        .toLowerCase();
      return inhoud.includes(term);
    });
  }, [alleOnderdelen, zoek, categorie, nazicht]);

  // Groeperen per categorie (in de vaste volgorde van onderdeelCategorieLabels)
  // en binnen elke groep alfabetisch op titel, zodat de bibliotheek
  // overzichtelijk blijft naarmate ze groeit, los van de insertievolgorde
  // in de seed-bestanden.
  const gegroepeerd = useMemo(() => {
    const groepen = new Map<OnderdeelCategorie, Modelonderdeel[]>();
    for (const o of gefilterd) {
      const groep = groepen.get(o.categorie) ?? [];
      groep.push(o);
      groepen.set(o.categorie, groep);
    }
    return (Object.keys(onderdeelCategorieLabels) as OnderdeelCategorie[])
      .filter((c) => groepen.has(c))
      .map((c) => ({
        categorie: c,
        onderdelen: [...groepen.get(c)!].sort((a, b) => a.titel.localeCompare(b.titel)),
      }));
  }, [gefilterd]);

  // Enkel eigen onderdelen zijn rechtstreeks verwijderbaar (de kantoorbibliotheek
  // wordt nooit rechtstreeks gewijzigd, zie AGENTS.md); de selectie blijft
  // daarom beperkt tot die id's, ook al toont de lijst alle onderdelen.
  const verwijderbareIds = useMemo(
    () => gefilterd.filter((o) => o.isGebruiker).map((o) => o.id),
    [gefilterd]
  );
  const { geselecteerd, klik, wisSelectie } = useMeervoudigeSelectie(verwijderbareIds);

  async function verwijderGeselecteerde() {
    const aantal = geselecteerd.size;
    if (!confirm(`${aantal} onderdeel${aantal > 1 ? "en" : ""} verwijderen?`)) return;
    for (const id of geselecteerd) await verwijder(id);
    wisSelectie();
  }

  if (editor) {
    return (
      <OnderdeelEditor
        basis={editor.basis}
        modus={editor.modus}
        onAnnuleer={() => setEditor(null)}
        onBewaar={async (o) => {
          await slaOp(o);
          setEditor(null);
          setOpenId(o.id);
        }}
      />
    );
  }

  if (voorstel) {
    return (
      <VoorstelFormulier
        basisOnderdeel={voorstel.basis}
        onAnnuleer={() => setVoorstel(null)}
        onIngediend={async (v) => {
          await slaVoorstelOp(v);
          setVoorstel(null);
          naarValideren();
        }}
      />
    );
  }

  return (
    <div className="space-y-4">
      <div className="flex flex-wrap gap-2 items-center">
        <input
          type="text"
          value={zoek}
          onChange={(e) => setZoek(e.target.value)}
          placeholder="Zoek in titel, tekst, hypotheses…"
          className="flex-1 min-w-48 text-sm border border-slate-300 rounded-lg px-3 py-2"
        />
        <select
          value={categorie}
          onChange={(e) => setCategorie(e.target.value as OnderdeelCategorie | "alle")}
          className="text-sm border border-slate-300 rounded-lg px-3 py-2 bg-white"
        >
          <option value="alle">Alle categorieën</option>
          {Object.entries(onderdeelCategorieLabels).map(([id, label]) => (
            <option key={id} value={id}>
              {label}
            </option>
          ))}
        </select>
        <select
          value={nazicht}
          onChange={(e) => setNazicht(e.target.value as NazichtStatus | "alle")}
          className="text-sm border border-slate-300 rounded-lg px-3 py-2 bg-white"
        >
          <option value="alle">Alle nazicht-statussen</option>
          {Object.entries(nazichtStatusLabels).map(([id, label]) => (
            <option key={id} value={id}>
              {label}
            </option>
          ))}
        </select>
        <button
          onClick={() => setEditor({ modus: "nieuw" })}
          className="text-sm px-4 py-2 rounded-lg font-medium bg-brand-600 text-white hover:bg-brand-700"
        >
          + Nieuw onderdeel
        </button>
      </div>

      {geselecteerd.size > 0 && (
        <div className="flex items-center gap-3 bg-red-50 border border-red-200 rounded-lg px-4 py-2">
          <span className="text-sm text-red-800">
            {geselecteerd.size} onderdeel{geselecteerd.size > 1 ? "en" : ""} geselecteerd
          </span>
          <button
            onClick={verwijderGeselecteerde}
            className="text-xs px-3 py-1.5 rounded-lg bg-red-600 text-white hover:bg-red-700"
          >
            Verwijder geselecteerde
          </button>
          <button
            onClick={wisSelectie}
            className="text-xs px-3 py-1.5 rounded-lg border border-slate-300 text-slate-600 hover:border-slate-400"
          >
            Annuleer selectie
          </button>
        </div>
      )}

      {gefilterd.length === 0 && (
        <p className="text-sm text-slate-400 py-8 text-center">Geen onderdelen gevonden.</p>
      )}

      {gegroepeerd.map(({ categorie: c, onderdelen }) => (
        <div key={c} className="space-y-3">
          <h3 className="text-xs font-semibold text-slate-500 uppercase tracking-wide flex items-center gap-2">
            {onderdeelCategorieLabels[c]}
            <span className="text-slate-300 font-normal">· {onderdelen.length}</span>
          </h3>
          <div className="space-y-3">
            {onderdelen.map((o) => (
              <OnderdeelKaart
                key={o.id}
                onderdeel={o}
                alleOnderdelen={alleOnderdelen}
                open={openId === o.id}
                onToggle={() => setOpenId(openId === o.id ? null : o.id)}
                geselecteerd={geselecteerd.has(o.id)}
                onSelectieKlik={
                  o.isGebruiker ? (e: React.MouseEvent) => klik(o.id, e) : undefined
                }
                onBewerk={() => setEditor({ basis: o, modus: "bewerk" })}
                onDupliceer={() =>
                  setEditor({
                    modus: "nieuw",
                    basis: {
                      ...o,
                      id: crypto.randomUUID(),
                      titel: `${o.titel} (kopie)`,
                      bron: o.bron ? `Gebaseerd op: ${o.bron}` : `Gebaseerd op: ${o.titel}`,
                      isGebruiker: true,
                    },
                  })
                }
                onVerwijder={
                  o.isGebruiker
                    ? () => {
                        if (confirm(`Onderdeel "${o.titel}" verwijderen?`)) verwijder(o.id);
                      }
                    : undefined
                }
                onStelVoorstel={() => setVoorstel({ basis: o })}
                versies={historiek.find((h) => h.id === o.id)?.versies ?? []}
                onHerstel={o.isGebruiker ? herstelVersie : undefined}
              />
            ))}
          </div>
        </div>
      ))}
    </div>
  );
}

function OnderdeelKaart({
  onderdeel,
  alleOnderdelen,
  open,
  onToggle,
  geselecteerd,
  onSelectieKlik,
  onBewerk,
  onDupliceer,
  onVerwijder,
  onStelVoorstel,
  versies,
  onHerstel,
}: {
  onderdeel: Modelonderdeel;
  alleOnderdelen: Modelonderdeel[];
  open: boolean;
  onToggle: () => void;
  geselecteerd?: boolean;
  onSelectieKlik?: (e: React.MouseEvent) => void;
  onBewerk: () => void;
  onDupliceer: () => void;
  onVerwijder?: () => void;
  onStelVoorstel?: () => void;
  versies?: Modelonderdeel[];
  onHerstel?: (oudeVersie: Modelonderdeel) => Promise<void>;
}) {
  const [toonHistoriek, setToonHistoriek] = useState(false);
  const [toonVoorbeeld, setToonVoorbeeld] = useState(false);
  const voorbeeld = useMemo(() => {
    if (!toonVoorbeeld) return null;
    const tegenhanger = vindOnderdeelTegenhanger(onderdeel, alleOnderdelen);
    const eigenTekst = vulOnderdeelVoorbeeldPlatIn(onderdeel);
    const tegenhangerTekst = tegenhanger ? vulOnderdeelVoorbeeldPlatIn(tegenhanger) : undefined;
    return onderdeel.taal === "fr"
      ? { nl: tegenhangerTekst, fr: eigenTekst }
      : { nl: eigenTekst, fr: tegenhangerTekst };
  }, [toonVoorbeeld, onderdeel, alleOnderdelen]);
  // Alle parameters die de clausule effectief gebruikt, met omschrijving/
  // voorbeeld uit de eigen declaraties of — via de bibliotheekbrede
  // catalogus — uit een declaratie elders in de bibliotheek.
  const catalogus = useMemo(() => bouwParameterCatalogus(alleOnderdelen), [alleOnderdelen]);
  const gebruikteParameters = useMemo(
    () =>
      extraheerParameters(onderdeel.tekst, ...onderdeel.varianten.map((v) => v.tekst))
        .filter((naam) => !/^[Rr]ol_/.test(naam))
        .map((naam) => ({ naam, info: vindParameterInfo(naam, onderdeel.parameters, catalogus) })),
    [onderdeel, catalogus]
  );
  return (
    <div
      className={`bg-white border rounded-xl shadow-sm overflow-hidden ${
        geselecteerd ? "border-red-300 ring-1 ring-red-200" : "border-slate-200"
      }`}
    >
      <div className="w-full text-left px-5 py-3 flex items-center gap-3">
        {onSelectieKlik && (
          <input
            type="checkbox"
            checked={!!geselecteerd}
            onClick={(e) => {
              e.stopPropagation();
              onSelectieKlik(e);
            }}
            onChange={() => {}}
            title="Selecteer (Shift = bereik, Ctrl/Cmd = toevoegen)"
            className="shrink-0 size-4 accent-red-600"
          />
        )}
        <button onClick={onToggle} className="flex-1 flex items-center gap-3 text-left">
        <div className="flex-1">
          <p className="text-sm font-semibold text-slate-800 flex items-center gap-2 flex-wrap">
            {onderdeel.titel}
            {onderdeel.nazicht && onderdeel.nazicht.status !== "actueel" && (
              <span
                className={`text-xs px-1.5 py-0.5 rounded font-normal ${
                  onderdeel.nazicht.status === "verouderd"
                    ? "bg-red-50 text-red-700"
                    : "bg-amber-50 text-amber-700"
                }`}
              >
                {nazichtStatusLabels[onderdeel.nazicht.status]}
              </span>
            )}
            {onderdeel.taal === "fr" && (
              <span className="text-xs px-1.5 py-0.5 rounded font-normal bg-sky-50 text-sky-700">
                {taalLabels.fr}
              </span>
            )}
          </p>
          <p className="text-xs text-slate-400 mt-0.5">
            {onderdeelCategorieLabels[onderdeel.categorie]} · v{onderdeel.versie} ·{" "}
            {onderdeel.varianten.length > 0
              ? `${onderdeel.varianten.length} hypothese${onderdeel.varianten.length > 1 ? "s" : ""}`
              : "vaste tekst"}
            {onderdeel.isGebruiker && " · eigen onderdeel"}
          </p>
        </div>
        <span className="text-slate-400 text-sm">{open ? "▴" : "▾"}</span>
        </button>
      </div>

      {open && (
        <div className="border-t border-slate-100 px-5 py-4 space-y-4">
          <p className="text-sm text-slate-600">{onderdeel.omschrijving}</p>

          {onderdeel.nazicht && onderdeel.nazicht.status !== "actueel" && (
            <div
              className={`text-xs rounded-lg px-3 py-2 ${
                onderdeel.nazicht.status === "verouderd"
                  ? "bg-red-50 text-red-800"
                  : "bg-amber-50 text-amber-800"
              }`}
            >
              <p className="font-semibold">
                {nazichtStatusLabels[onderdeel.nazicht.status]} (laatst nagekeken op{" "}
                {onderdeel.nazicht.datum})
              </p>
              {onderdeel.nazicht.aandachtspunten && <p className="mt-1">{onderdeel.nazicht.aandachtspunten}</p>}
            </div>
          )}

          <div>
            <button
              onClick={() => setToonVoorbeeld((v) => !v)}
              className="text-xs px-3 py-1.5 rounded-lg border border-slate-300 text-slate-600 hover:border-brand-300"
            >
              {toonVoorbeeld ? "Verberg ingevuld voorbeeld (NL/FR)" : "Toon ingevuld voorbeeld (NL/FR)"}
            </button>
          </div>

          {voorbeeld && <VoorbeeldTweeKolommen nl={voorbeeld.nl} fr={voorbeeld.fr} />}

          {onderdeel.tekst.trim() && (
            <pre className="text-xs text-slate-700 whitespace-pre-wrap font-mono leading-relaxed p-4 bg-slate-50 rounded-lg">
              {onderdeel.tekst}
            </pre>
          )}

          {onderdeel.varianten.map((v) => (
            <div key={v.id} className="border border-slate-200 rounded-lg overflow-hidden">
              <p className="text-xs font-medium text-amber-800 bg-amber-50 px-4 py-2">
                ▸ Hypothese — {v.hypothese}
              </p>
              <pre className="text-xs text-slate-700 whitespace-pre-wrap font-mono leading-relaxed p-4 bg-slate-50">
                {v.tekst}
              </pre>
            </div>
          ))}

          {gebruikteParameters.length > 0 && (
            <div>
              <p className="text-xs font-semibold text-slate-500 uppercase tracking-wide mb-1.5">
                Parameters ({gebruikteParameters.length})
              </p>
              <div className="flex flex-wrap gap-1.5">
                {gebruikteParameters.map(({ naam, info }) => (
                  <span
                    key={naam}
                    title={
                      info
                        ? info.omschrijving + (info.voorbeeld ? ` (bv. ${info.voorbeeld})` : "")
                        : "Nog nergens in de bibliotheek gedeclareerd (geen omschrijving)"
                    }
                    className={`text-xs px-2 py-0.5 rounded font-mono ${
                      info ? "bg-brand-50 text-brand-700" : "bg-amber-50 text-amber-700"
                    }`}
                  >
                    {"{{" + naam + "}}"}
                  </span>
                ))}
              </div>
            </div>
          )}

          <div>
            <p className="text-xs font-semibold text-slate-500 uppercase tracking-wide mb-1.5">
              Toepasbaar in
            </p>
            <div className="flex flex-wrap gap-1.5">
              {onderdeel.toepasbaarOp.map((t) => (
                <span key={t} className="text-xs bg-emerald-50 text-emerald-700 px-2 py-0.5 rounded">
                  {t}
                </span>
              ))}
            </div>
          </div>

          {onderdeel.bron && <p className="text-xs text-slate-400">Bron: {onderdeel.bron}</p>}

          {onHerstel && versies && versies.length > 0 && (
            <div>
              <button
                onClick={() => setToonHistoriek((v) => !v)}
                className="text-xs font-semibold text-slate-500 uppercase tracking-wide mb-1.5 hover:text-brand-700"
              >
                {toonHistoriek ? "▴" : "▾"} Eerdere versies ({versies.length})
              </button>
              {toonHistoriek && (
                <ul className="divide-y divide-slate-100 border border-slate-200 rounded-lg">
                  {[...versies].reverse().map((v, i) => (
                    <li key={`${v.versie}-${i}`} className="flex items-center justify-between gap-3 px-3 py-2">
                      <span className="text-xs text-slate-600">
                        v{v.versie} · {v.datum}
                      </span>
                      <button
                        onClick={() => {
                          if (confirm(`Versie ${v.versie} (${v.datum}) terugzetten als huidige tekst?`)) {
                            onHerstel(v);
                          }
                        }}
                        className="text-xs px-3 py-1 rounded-lg border border-amber-300 text-amber-700 hover:bg-amber-50"
                      >
                        Herstel
                      </button>
                    </li>
                  ))}
                </ul>
              )}
            </div>
          )}

          <div className="flex gap-2 pt-1">
            <button
              onClick={onDupliceer}
              className="text-xs px-3 py-1.5 rounded-lg border border-slate-300 text-slate-600 hover:border-brand-300"
            >
              Dupliceer als eigen onderdeel
            </button>
            {onderdeel.isGebruiker && (
              <button
                onClick={onBewerk}
                className="text-xs px-3 py-1.5 rounded-lg border border-slate-300 text-slate-600 hover:border-brand-300"
              >
                Bewerk
              </button>
            )}
            {onStelVoorstel && (
              <button
                onClick={onStelVoorstel}
                className="text-xs px-3 py-1.5 rounded-lg border border-amber-300 text-amber-700 hover:bg-amber-50"
              >
                Stel wijziging voor ter validatie
              </button>
            )}
            {onVerwijder && (
              <button
                onClick={onVerwijder}
                className="text-xs px-3 py-1.5 rounded-lg border border-red-200 text-red-600 hover:bg-red-50"
              >
                Verwijder
              </button>
            )}
          </div>
        </div>
      )}
    </div>
  );
}
