"use client";

import { useRef, useState } from "react";
import { Button } from "@/components/ui/Button";
import { CARD_CLASS } from "@/components/ui/Card";

// Der Ablauf hat bewusst zwei Schritte: prüfen, dann übernehmen.
//
// Ein Import ist nicht rückgängig zu machen. Wer 800 Zeilen schickt, soll
// vorher sehen, was entstehen würde — und bei einem Fehler die Zeilennummer
// lesen, nicht „Import fehlgeschlagen".

type Befund = { blatt: string; zeile: number | null; spalte: string | null; wert?: string; meldung: string };

type Antwort = {
  ok: boolean;
  geprueft: boolean;
  blaetter: string[];
  fehler: Befund[];
  hinweise: Befund[];
  anzahl: Record<string, number>;
  bericht?: Record<string, number>;
  meldung?: string;
};

/** Mehr als das zeigt niemand durch; der Rest steht in der Anzahl. */
const MAX_ANZEIGE = 200;

export function ImportWorkbench() {
  const [dateien, setDateien] = useState<File[]>([]);
  const [antwort, setAntwort] = useState<Antwort | null>(null);
  const [laeuft, setLaeuft] = useState<"pruefen" | "uebernehmen" | null>(null);
  const [fehlschlag, setFehlschlag] = useState<string | null>(null);
  const eingabe = useRef<HTMLInputElement>(null);

  async function senden(nurPruefen: boolean) {
    if (dateien.length === 0) return;
    setLaeuft(nurPruefen ? "pruefen" : "uebernehmen");
    setFehlschlag(null);
    try {
      const daten = new FormData();
      for (const d of dateien) daten.append("datei", d);
      if (nurPruefen) daten.append("pruefen", "1");
      const antwort = await fetch("/api/import", { method: "POST", body: daten });
      const inhalt = (await antwort.json()) as Antwort;
      setAntwort(inhalt);
    } catch {
      setFehlschlag("Die Datei konnte nicht übertragen werden. Bitte erneut versuchen.");
    } finally {
      setLaeuft(null);
    }
  }

  function neueAuswahl(liste: FileList | null) {
    setDateien(liste ? Array.from(liste) : []);
    // Ein alter Bericht zu einer neuen Datei ist schlimmer als keiner.
    setAntwort(null);
    setFehlschlag(null);
  }

  const uebernommen = antwort?.bericht !== undefined;
  const bereit = antwort?.ok === true && antwort.geprueft && !uebernommen;

  return (
    <div className="flex flex-col gap-4">
      <section className={`${CARD_CLASS} p-5`}>
        <div className="flex flex-wrap items-start justify-between gap-4">
          <div>
            <h2 className="text-sm font-bold text-ink">Datei wählen</h2>
            <p className="mt-1 max-w-prose text-sm text-ink-muted">
              Eine Excel-Mappe mit den Blättern <strong>Standorte</strong>, <strong>Organisation</strong>,{" "}
              <strong>Jobkatalog</strong>, <strong>Planstellen</strong>, <strong>Personen</strong>,{" "}
              <strong>Historie</strong> und <strong>Angehörige</strong> — oder je Blatt eine CSV-Datei, deren Name dem
              Blatt entspricht. Nicht jedes Blatt muss dabei sein.
            </p>
          </div>
          <a
            href="/api/import/template"
            className="shrink-0 rounded-md border border-border px-3 py-2 text-sm font-semibold text-ink hover:bg-brand-50
                       focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-brand-500"
          >
            Vorlage herunterladen
          </a>
        </div>

        <div className="mt-4 flex flex-wrap items-center gap-3">
          <input
            ref={eingabe}
            type="file"
            multiple
            accept=".xlsx,.xlsm,.csv"
            onChange={(e) => neueAuswahl(e.target.files)}
            className="block w-full max-w-md text-sm text-ink-muted file:mr-3 file:rounded-md file:border file:border-border
                       file:bg-surface file:px-3 file:py-2 file:text-sm file:font-semibold file:text-ink hover:file:bg-brand-50"
          />
          <Button onClick={() => senden(true)} disabled={dateien.length === 0 || laeuft !== null}>
            {laeuft === "pruefen" ? "Wird geprüft…" : "Prüfen"}
          </Button>
        </div>
        {dateien.length > 0 && (
          <p className="mt-2 text-xs text-ink-muted">
            {dateien.length === 1 ? dateien[0].name : `${dateien.length} Dateien`} ausgewählt
          </p>
        )}
      </section>

      {fehlschlag && (
        <p role="alert" className="rounded-md border border-danger-text/20 bg-danger-bg px-4 py-3 text-sm text-danger-text">
          {fehlschlag}
        </p>
      )}

      {antwort?.meldung && (
        <p role="alert" className="rounded-md border border-danger-text/20 bg-danger-bg px-4 py-3 text-sm text-danger-text">
          {antwort.meldung}
        </p>
      )}

      {antwort && !antwort.meldung && (
        <section className={`${CARD_CLASS} p-5`}>
          <h2 className="text-sm font-bold text-ink">{uebernommen ? "Übernommen" : "Ergebnis der Prüfung"}</h2>

          <table className="mt-3 w-full max-w-md text-sm">
            <tbody>
              {Object.entries(uebernommen ? antwort.bericht! : antwort.anzahl)
                .filter(([, n]) => n > 0)
                .map(([blatt, n]) => (
                  <tr key={blatt} className="border-b border-border-subtle last:border-0">
                    <td className="py-1.5 text-ink-body">{blatt}</td>
                    <td className="py-1.5 text-right font-semibold tabular-nums text-ink">{n}</td>
                  </tr>
                ))}
            </tbody>
          </table>

          {uebernommen ? (
            <p className="mt-4 text-sm text-ink-muted">
              Die Daten stehen jetzt in der Anwendung. Der Vorgang ist im Audit-Log vermerkt.
            </p>
          ) : antwort.ok ? (
            <>
              <p className="mt-4 text-sm text-ink-body">
                Keine Beanstandung. Beim Übernehmen entsteht genau das oben Gezeigte — alles in einem Zug oder gar
                nichts.
              </p>
              <div className="mt-3">
                <Button onClick={() => senden(false)} disabled={laeuft !== null || !bereit}>
                  {laeuft === "uebernehmen" ? "Wird übernommen…" : "Übernehmen"}
                </Button>
              </div>
            </>
          ) : (
            <p className="mt-4 text-sm font-semibold text-danger-text">
              {antwort.fehler.length} Beanstandung{antwort.fehler.length === 1 ? "" : "en"} — es wurde nichts
              geschrieben.
            </p>
          )}
        </section>
      )}

      {antwort && antwort.fehler.length > 0 && (
        <BefundListe titel="Zu beheben" befunde={antwort.fehler} art="fehler" />
      )}
      {antwort && antwort.hinweise.length > 0 && (
        <BefundListe titel="Hinweise" befunde={antwort.hinweise} art="hinweis" />
      )}
    </div>
  );
}

function BefundListe({ titel, befunde, art }: { titel: string; befunde: Befund[]; art: "fehler" | "hinweis" }) {
  const sichtbar = befunde.slice(0, MAX_ANZEIGE);
  return (
    <section className={`overflow-x-auto ${CARD_CLASS}`}>
      <h2 className="px-5 pt-5 text-sm font-bold text-ink">
        {titel} <span className="font-normal text-ink-muted">({befunde.length})</span>
      </h2>
      <table className="mt-3 w-full min-w-[640px] text-sm">
        <thead>
          <tr className="border-y border-border bg-surface text-left text-[11px] font-bold uppercase tracking-wider text-ink-muted">
            <th className="px-5 py-2">Blatt</th>
            <th className="px-3 py-2">Zeile</th>
            <th className="px-3 py-2">Spalte</th>
            <th className="px-3 py-2">Wert</th>
            <th className="px-5 py-2">Was zu tun ist</th>
          </tr>
        </thead>
        <tbody>
          {sichtbar.map((b, i) => (
            <tr key={i} className="border-b border-border-subtle last:border-0">
              <td className="whitespace-nowrap px-5 py-2 text-ink-body">{b.blatt}</td>
              <td className="px-3 py-2 tabular-nums text-ink-muted">{b.zeile ?? "–"}</td>
              <td className="px-3 py-2 text-ink-body">{b.spalte ?? "–"}</td>
              <td className="max-w-[16rem] truncate px-3 py-2 text-ink-muted" title={b.wert}>
                {b.wert ?? ""}
              </td>
              <td className={`px-5 py-2 ${art === "fehler" ? "text-danger-text" : "text-ink-muted"}`}>{b.meldung}</td>
            </tr>
          ))}
        </tbody>
      </table>
      {befunde.length > sichtbar.length && (
        <p className="px-5 py-3 text-xs text-ink-muted">
          Weitere {befunde.length - sichtbar.length} nicht angezeigt. Oft hängen viele Meldungen an einer Ursache —
          nach der Korrektur erneut prüfen.
        </p>
      )}
    </section>
  );
}
