"use client";

import { useCallback, useEffect, useState } from "react";
import { ArrowLeft, Download, FileText, Plus, Trash2 } from "lucide-react";
import { Button, useConfirm, useToast } from "@/components/ui";
import { InfoBubble } from "@/components/InfoBubble";
import { api } from "@/lib/api-client";
import { ANALYSIS_TYPE_LABEL, type AnalysisType, type SavedAnalysisMeta } from "@/lib/analyses";
import { MAX_REPORT_SCENARIOS, type ReportMetric, type ReportSource } from "@/lib/report";

interface StoredReport {
  id: string;
  title: string;
  config: { metric?: string; source?: string; scenarioIds?: string[]; analysisIds?: string[]; comment?: string | null };
  pdfBytes: number;
  createdAt: string;
  author: string;
}

const dt = (iso: string) =>
  new Date(iso).toLocaleString("de-CH", { day: "2-digit", month: "2-digit", year: "numeric", hour: "2-digit", minute: "2-digit" });

export function ReportsView({
  planId,
  scenarios,
  hasActuals,
}: {
  planId: string;
  scenarios: { id: string; name: string; isBase: boolean }[];
  hasActuals: boolean;
}) {
  const [reports, setReports] = useState<StoredReport[] | null>(null);
  const [analyses, setAnalyses] = useState<SavedAnalysisMeta[]>([]);
  const [error, setError] = useState<string | null>(null);
  const [mode, setMode] = useState<"list" | "new">("list");
  const [busy, setBusy] = useState(false);
  const confirm = useConfirm();
  const toast = useToast();

  // Formular
  const [title, setTitle] = useState("");
  const [comment, setComment] = useState("");
  const [metric, setMetric] = useState<ReportMetric>("nominal");
  const [source, setSource] = useState<ReportSource>("PLAN");
  const [scenarioIds, setScenarioIds] = useState<string[]>([]);
  const [analysisIds, setAnalysisIds] = useState<string[]>([]);

  const load = useCallback(async () => {
    const [r, a] = await Promise.all([
      api.get<{ reports: StoredReport[] }>(`/api/plans/${planId}/reports`),
      api.get<{ analyses: SavedAnalysisMeta[] }>(`/api/plans/${planId}/analyses`),
    ]);
    setReports(r.reports);
    setAnalyses(a.analyses);
  }, [planId]);

  useEffect(() => {
    let cancelled = false;
    (async () => {
      try {
        const [r, a] = await Promise.all([
          api.get<{ reports: StoredReport[] }>(`/api/plans/${planId}/reports`),
          api.get<{ analyses: SavedAnalysisMeta[] }>(`/api/plans/${planId}/analyses`),
        ]);
        if (cancelled) return;
        setReports(r.reports);
        setAnalyses(a.analyses);
      } catch (e) {
        if (!cancelled) setError(e instanceof Error ? e.message : "Konnte nicht geladen werden.");
      }
    })();
    return () => {
      cancelled = true;
    };
  }, [planId]);

  function startNew() {
    const base = scenarios.find((s) => s.isBase) ?? scenarios[0];
    setTitle(`Finanzplanung ${new Date().getFullYear()}`);
    setComment("");
    setMetric("nominal");
    setSource("PLAN");
    setScenarioIds(base ? [base.id] : []);
    setAnalysisIds([]);
    setMode("new");
  }

  function toggleScenario(id: string) {
    setScenarioIds((prev) =>
      prev.includes(id) ? prev.filter((x) => x !== id) : prev.length >= MAX_REPORT_SCENARIOS ? prev : [...prev, id]
    );
  }

  async function create() {
    setBusy(true);
    try {
      await api.post(`/api/plans/${planId}/reports`, {
        title: title.trim() || "Finanzplanung",
        metric,
        source,
        scenarioIds,
        analysisIds,
        comment: comment.trim() || undefined,
      });
      await load();
      setMode("list");
      toast("success", "Bericht erstellt.");
    } catch (e) {
      toast("error", e instanceof Error ? e.message : "Bericht konnte nicht erstellt werden.");
    } finally {
      setBusy(false);
    }
  }

  async function remove(r: StoredReport) {
    const ok = await confirm({
      title: "Bericht löschen?",
      message: `«${r.title}» wird endgültig entfernt. Die Datei lässt sich danach nicht mehr herunterladen.`,
      confirmLabel: "Löschen",
      danger: true,
    });
    if (!ok) return;
    try {
      await api.delete(`/api/plans/${planId}/reports/${r.id}`);
      await load();
      toast("success", "Bericht gelöscht.");
    } catch (e) {
      toast("error", e instanceof Error ? e.message : "Löschen fehlgeschlagen.");
    }
  }

  if (mode === "new") {
    return (
      <div className="flex flex-col gap-4">
        <div>
          <h2 className="text-lg font-semibold text-fg">Neuer Bericht</h2>
          <p className="text-sm text-muted">
            Der Bericht wird als PDF erzeugt und abgelegt. Er hält den Stand von heute fest – spätere Änderungen am
            Plan verändern ihn nicht mehr.
          </p>
        </div>

        <div className="grid grid-cols-1 gap-3 sm:grid-cols-2">
          <div>
            <label className="mb-1 block text-xs font-medium text-muted">Titel</label>
            <input
              value={title}
              onChange={(e) => setTitle(e.target.value)}
              className="w-full rounded-lg border border-border bg-surface px-2.5 py-1.5 text-sm text-fg"
            />
          </div>
          <div>
            <label className="mb-1 block text-xs font-medium text-muted">Notiz auf dem Deckblatt (optional)</label>
            <input
              value={comment}
              onChange={(e) => setComment(e.target.value)}
              placeholder="z. B. «Stand nach Beratungsgespräch»"
              className="w-full rounded-lg border border-border bg-surface px-2.5 py-1.5 text-sm text-fg"
            />
          </div>
        </div>

        <div className="flex flex-wrap items-center gap-x-6 gap-y-2 rounded-xl border border-border bg-surface-2 px-3 py-2">
          <label className="flex items-center gap-1.5 text-xs text-muted">
            <span className="font-medium">Werte</span>
            <div className="inline-flex rounded-lg border border-border bg-surface p-0.5">
              {(["nominal", "real"] as ReportMetric[]).map((m) => (
                <button
                  key={m}
                  type="button"
                  onClick={() => setMetric(m)}
                  className={`rounded-md px-2 py-0.5 font-medium ${metric === m ? "bg-accent text-accent-fg" : "text-muted hover:text-fg"}`}
                >
                  {m === "real" ? "Real" : "Nominal"}
                </button>
              ))}
            </div>
            <InfoBubble text="Der Bericht führt durchgängig EINE Leitgrösse. Beides nebeneinander würde jede Tabellenspalte verdoppeln." />
          </label>

          <label className="flex items-center gap-1.5 text-xs text-muted">
            <span className="font-medium">Grundlage</span>
            <div className="inline-flex rounded-lg border border-border bg-surface p-0.5">
              {(["PLAN", "ACTUAL"] as ReportSource[]).map((s) => (
                <button
                  key={s}
                  type="button"
                  disabled={s === "ACTUAL" && !hasActuals}
                  onClick={() => setSource(s)}
                  title={s === "ACTUAL" && !hasActuals ? "Für diesen Plan sind keine effektiven Werte erfasst." : undefined}
                  className={`rounded-md px-2 py-0.5 font-medium disabled:opacity-40 ${
                    source === s ? "bg-accent text-accent-fg" : "text-muted hover:text-fg"
                  }`}
                >
                  {s === "ACTUAL" ? "Effektiv" : "Plan"}
                </button>
              ))}
            </div>
          </label>
        </div>

        <div>
          <div className="mb-2 flex items-center text-xs font-semibold uppercase tracking-wide text-faint">
            Szenarien (max. {MAX_REPORT_SCENARIOS})
            <InfoBubble text="Mehr als drei Szenarien machen die Vergleichstabelle unlesbar. Das Basisszenario führt den Bericht an und liefert die Zusammenfassung." />
          </div>
          <div className="flex flex-col gap-2">
            {scenarios.map((s) => {
              const checked = scenarioIds.includes(s.id);
              const full = !checked && scenarioIds.length >= MAX_REPORT_SCENARIOS;
              return (
                <label
                  key={s.id}
                  className={`flex items-center gap-2 rounded-xl border p-3 text-sm ${
                    checked ? "border-accent bg-accent-soft/20" : "border-border bg-surface-2"
                  } ${full ? "opacity-40" : ""}`}
                >
                  <input type="checkbox" checked={checked} disabled={full} onChange={() => toggleScenario(s.id)} />
                  <span className="font-medium text-fg">{s.name}</span>
                  {s.isBase && <span className="rounded bg-accent px-1.5 py-0.5 text-[10px] font-semibold text-accent-fg">Basis</span>}
                </label>
              );
            })}
          </div>
        </div>

        <div>
          <div className="mb-2 flex items-center text-xs font-semibold uppercase tracking-wide text-faint">
            Gespeicherte Analysen einbinden
            <InfoBubble text="Übernommen werden die beim Speichern eingefrorenen Zahlen – es wird nichts neu gerechnet." />
          </div>
          {analyses.length === 0 ? (
            <p className="rounded-lg border border-dashed border-border bg-surface-2 p-3 text-xs text-muted">
              Noch keine Analysen gespeichert. Unter «Analysen» kannst du Ergebnisse festhalten.
            </p>
          ) : (
            <div className="flex flex-col gap-1.5">
              {analyses.map((a) => (
                <label key={a.id} className="flex items-center gap-2 rounded-lg border border-border bg-surface-2 px-3 py-2 text-xs">
                  <input
                    type="checkbox"
                    checked={analysisIds.includes(a.id)}
                    onChange={() =>
                      setAnalysisIds((prev) => (prev.includes(a.id) ? prev.filter((x) => x !== a.id) : [...prev, a.id]))
                    }
                  />
                  <span className="font-medium text-fg">{a.name}</span>
                  <span className="text-faint">{ANALYSIS_TYPE_LABEL[a.type as AnalysisType]}</span>
                </label>
              ))}
            </div>
          )}
        </div>

        <div className="flex items-center gap-2">
          <Button variant="secondary" onClick={() => setMode("list")}>
            <ArrowLeft className="h-4 w-4" /> Zurück
          </Button>
          <Button disabled={busy || scenarioIds.length === 0} onClick={create}>
            {busy ? "Wird erstellt…" : "Bericht erstellen"}
          </Button>
        </div>
      </div>
    );
  }

  return (
    <div className="flex flex-col gap-4">
      <div className="flex items-center justify-between">
        <h2 className="text-lg font-semibold text-fg">Berichte</h2>
        <Button onClick={startNew} disabled={scenarios.length === 0}>
          <Plus className="h-4 w-4" /> Neuer Bericht
        </Button>
      </div>

      <p className="rounded-xl border border-border bg-surface-2 p-3 text-xs leading-relaxed text-muted">
        Ein Bericht ist ein <strong className="text-fg">festes Dokument</strong>: Die erzeugte PDF-Datei wird abgelegt
        und lässt sich jederzeit unverändert wieder herunterladen – auch wenn du den Plan danach weiterentwickelst.
      </p>

      {error && <p className="text-xs text-danger">{error}</p>}
      {!reports && !error && <p className="text-xs text-muted">Wird geladen…</p>}

      {reports && reports.length === 0 && (
        <p className="rounded-lg border border-dashed border-border bg-surface-2 p-4 text-xs text-muted">
          Noch kein Bericht erstellt.
        </p>
      )}

      {reports && reports.length > 0 && (
        <div className="flex flex-col gap-2">
          {reports.map((r) => (
            <div key={r.id} className="flex flex-wrap items-center gap-3 rounded-xl border border-border bg-surface-2 p-3">
              <FileText className="h-4 w-4 shrink-0 text-accent" />
              <div className="min-w-0 flex-1">
                <div className="truncate text-sm font-medium text-fg">{r.title}</div>
                <div className="text-[11px] text-muted">
                  {dt(r.createdAt)} · {r.author} · {r.config.metric === "real" ? "real" : "nominal"} ·{" "}
                  {r.config.source === "ACTUAL" ? "effektiv" : "Plan"} · {(r.config.scenarioIds ?? []).length} Szenario
                  {(r.config.scenarioIds ?? []).length === 1 ? "" : "s"} · {Math.round(r.pdfBytes / 1024)} KB
                </div>
              </div>
              <a
                href={`/api/plans/${planId}/reports/${r.id}`}
                className="flex items-center gap-1 rounded-lg border border-border px-2 py-1 text-[11px] text-muted hover:bg-surface hover:text-fg"
              >
                <Download className="h-3.5 w-3.5" /> PDF
              </a>
              <button
                type="button"
                onClick={() => remove(r)}
                className="rounded-lg border border-border px-2 py-1 text-[11px] text-muted hover:border-danger hover:bg-danger-soft hover:text-danger"
              >
                <Trash2 className="h-3.5 w-3.5" />
              </button>
            </div>
          ))}
        </div>
      )}
    </div>
  );
}
