"use client";

import { useCallback, useEffect, useState } from "react";
import {
  BarChart3,
  CalendarClock,
  Check,
  Dices,
  Eye,
  FileSpreadsheet,
  GitBranch,
  History,
  Layers,
  LineChart as LineChartIcon,
  Pencil,
  Plus,
  SlidersHorizontal,
  Tornado,
  Trash2,
  X,
} from "lucide-react";
import { Button, useConfirm, useToast } from "@/components/ui";
import { api } from "@/lib/api-client";
import { formatChf } from "@/lib/format";
import { ANALYSIS_TYPE_LABEL, sourceLabel, type AnalysisType, type SavedAnalysisMeta } from "@/lib/analyses";
import type { PersonRole } from "@/lib/types";

export type PlanTab = "dashboard" | "scenarios" | "actuals" | "analyses" | "reports";

// --- Typen der Dashboard-Antwort ---
interface DashboardResponse {
  plan: {
    id: string;
    name: string;
    householdType: "SINGLE" | "COUPLE";
    startYear: number | null;
    persons: { role: PersonRole; name: string | null; age: number }[];
  };
  counts: { scenarios: number; actuals: number; analyses: number };
  base: {
    scenarioId: string;
    name: string;
    phaseCount: number;
    endNominal: number;
    endReal: number;
    ruinAge: number | null;
    actualEndNominal: number | null;
    actualYears: number[];
  } | null;
  scenarios: {
    id: string;
    name: string;
    isBase: boolean;
    parentScenarioId: string | null;
    version: string | null;
    versionComment: string | null;
    elementCount: number;
    phaseCount: number;
    versionCount: number;
    endNominal: number;
    endReal: number;
    ruinAge: number | null;
  }[];
}

function useDashboard(planId: string, reloadKey: number) {
  const [data, setData] = useState<DashboardResponse | null>(null);
  const [error, setError] = useState<string | null>(null);
  useEffect(() => {
    let cancelled = false;
    (async () => {
      try {
        const d = await api.get<DashboardResponse>(`/api/plans/${planId}/dashboard`);
        if (!cancelled) setData(d);
      } catch (e) {
        if (!cancelled) setError(e instanceof Error ? e.message : "Konnte nicht geladen werden.");
      }
    })();
    return () => {
      cancelled = true;
    };
  }, [planId, reloadKey]);
  return { data, error };
}

// Anklickbare Kennzahl-Kachel. Ohne `onClick` bleibt sie eine reine Anzeige.
function Stat({
  label,
  value,
  hint,
  tone,
  icon: Icon,
  onClick,
}: {
  label: string;
  value: string;
  hint?: string;
  tone?: "danger" | "success";
  icon?: typeof Layers;
  onClick?: () => void;
}) {
  const toneClass = tone === "danger" ? "text-danger" : tone === "success" ? "text-success" : "text-fg";
  const body = (
    <>
      <div className="flex items-center gap-1.5 text-xs text-muted">
        {Icon && <Icon className="h-3.5 w-3.5 text-accent" />}
        {label}
      </div>
      <div className={`mt-1 text-2xl font-semibold tabular-nums ${toneClass}`}>{value}</div>
      {hint && <div className="mt-0.5 text-[11px] text-faint">{hint}</div>}
    </>
  );
  if (!onClick) {
    return <div className="rounded-2xl border border-border bg-surface p-4 shadow-sm">{body}</div>;
  }
  return (
    <button
      type="button"
      onClick={onClick}
      className="group rounded-2xl border border-border bg-surface p-4 text-left shadow-sm transition-all hover:-translate-y-0.5 hover:border-accent hover:shadow-md"
    >
      {body}
      <div className="mt-1 text-[11px] font-medium text-accent opacity-0 transition-opacity group-hover:opacity-100">
        Öffnen →
      </div>
    </button>
  );
}

// =========================================================================================
// Plan-Dashboard
// =========================================================================================
export function PlanDashboardView({
  planId,
  onNavigate,
  onRenamed,
}: {
  planId: string;
  onNavigate: (tab: PlanTab) => void;
  onRenamed: () => void;
}) {
  const [reloadKey, setReloadKey] = useState(0);
  const { data, error } = useDashboard(planId, reloadKey);
  const [editing, setEditing] = useState(false);
  const [draftName, setDraftName] = useState("");
  const [saving, setSaving] = useState(false);
  const toast = useToast();

  if (error) return <p className="text-sm text-danger">{error}</p>;
  if (!data) return <p className="text-sm text-muted">Wird geladen…</p>;

  const { plan, counts, base } = data;
  const persons = plan.persons
    .map((p) => `${p.name || (p.role === "PERSON_A" ? "Person A" : "Person B")} (${p.age})`)
    .join(" · ");

  // Jüngster erfasster Ist-Datensatz -- er bestimmt, gegen welchen Stand verglichen wird.
  const latestActualYear = base && base.actualYears.length > 0 ? Math.max(...base.actualYears) : null;
  const delta = base && base.actualEndNominal !== null ? base.actualEndNominal - base.endNominal : null;

  async function saveName() {
    const name = draftName.trim();
    if (!name) return;
    setSaving(true);
    try {
      await api.patch(`/api/plans/${planId}`, { name });
      setEditing(false);
      setReloadKey((k) => k + 1);
      onRenamed();
      toast("success", "Plan umbenannt.");
    } catch (e) {
      toast("error", e instanceof Error ? e.message : "Umbenennen fehlgeschlagen.");
    } finally {
      setSaving(false);
    }
  }

  return (
    <div className="flex flex-col gap-6">
      <div>
        {editing ? (
          <div className="flex flex-wrap items-center gap-2">
            <input
              autoFocus
              value={draftName}
              onChange={(e) => setDraftName(e.target.value)}
              onKeyDown={(e) => {
                if (e.key === "Enter") void saveName();
                if (e.key === "Escape") setEditing(false);
              }}
              maxLength={120}
              className="rounded-lg border border-border bg-input px-3 py-1.5 text-lg font-semibold text-fg focus:border-accent focus:outline-none focus:ring-2 focus:ring-accent/25"
            />
            <Button size="sm" onClick={saveName} disabled={saving}>
              <Check className="h-4 w-4" /> Speichern
            </Button>
            <Button size="sm" variant="secondary" onClick={() => setEditing(false)}>
              <X className="h-4 w-4" />
            </Button>
          </div>
        ) : (
          <div className="group flex items-center gap-2">
            <h2 className="text-lg font-semibold text-fg">{plan.name}</h2>
            <button
              type="button"
              aria-label="Plan umbenennen"
              title="Plan umbenennen"
              onClick={() => {
                setDraftName(plan.name);
                setEditing(true);
              }}
              className="rounded-md p-1 text-faint opacity-60 transition-opacity hover:bg-surface-2 hover:text-fg group-hover:opacity-100"
            >
              <Pencil className="h-4 w-4" />
            </button>
          </div>
        )}
        <p className="text-sm text-muted">
          {plan.householdType === "COUPLE" ? "Paar" : "Einzelperson"} · {persons}
          {plan.startYear ? ` · Planstart ${plan.startYear}` : ""}
        </p>
      </div>

      {/* Anklickbare Kacheln -- jede führt in ihren Bereich. */}
      <div className="grid grid-cols-2 gap-4 lg:grid-cols-4">
        <Stat
          label="Szenarien"
          value={String(counts.scenarios)}
          hint="Varianten dieser Planung"
          icon={Layers}
          onClick={() => onNavigate("scenarios")}
        />
        <Stat
          label="Effektive Werte"
          value={String(counts.actuals)}
          hint="erfasste Ist-Datensätze"
          icon={CalendarClock}
          onClick={() => onNavigate("actuals")}
        />
        <Stat
          label="Gespeicherte Analysen"
          value={String(counts.analyses)}
          hint="Grafiken, Simulationen, Tornados"
          icon={BarChart3}
          onClick={() => onNavigate("analyses")}
        />
        <Stat
          label="Berichte"
          value="PDF"
          hint="erzeugen und wieder herunterladen"
          icon={FileSpreadsheet}
          onClick={() => onNavigate("reports")}
        />
      </div>

      {base && (
        <div className="rounded-2xl border border-border bg-surface p-5 shadow-sm">
          <h3 className="mb-3 flex flex-wrap items-baseline gap-2 text-sm font-semibold text-fg">
            Basisszenario «{base.name}»
            <span className="text-[11px] font-normal text-faint">alle Kennzahlen beziehen sich hierauf</span>
          </h3>
          <div className="grid grid-cols-1 gap-4 sm:grid-cols-4">
            <Stat label="Endvermögen (nominal)" value={formatChf(base.endNominal)} />
            <Stat label="Endvermögen (real)" value={formatChf(base.endReal)} />
            <Stat label="Lebensphasen" value={String(base.phaseCount)} />
            {base.ruinAge !== null ? (
              <Stat label="Kapital reicht" value={`bis Alter ${base.ruinAge}`} tone="danger" hint="danach aufgebraucht" />
            ) : (
              <Stat label="Kapital reicht" value="bis Planende" tone="success" />
            )}
          </div>
          {base.actualEndNominal !== null && delta !== null && (
            <p
              className={`mt-4 rounded-xl border px-3 py-2 text-xs ${
                delta >= 0 ? "border-success bg-success/10 text-fg" : "border-danger bg-danger-soft text-fg"
              }`}
            >
              Mit den effektiven Werten{latestActualYear ? ` von ${latestActualYear}` : ""} liegt das Endvermögen
              (nominal) bei <strong>{formatChf(base.actualEndNominal)}</strong> – eine Abweichung von{" "}
              <strong className={delta >= 0 ? "text-success" : "text-danger"}>
                {delta >= 0 ? "+" : ""}
                {formatChf(delta)}
              </strong>{" "}
              gegenüber dem Plan.
            </p>
          )}
        </div>
      )}
    </div>
  );
}

// =========================================================================================
// Szenario-Liste
// =========================================================================================
export function ScenarioListView({
  planId,
  reloadKey = 0,
  onOpenMatrix,
  onOpenHistory,
  onCopyFrom,
  onDelete,
}: {
  planId: string;
  reloadKey?: number;
  onOpenMatrix: (scenarioId: string) => void;
  onOpenHistory: (scenarioId: string) => void;
  // Kopiervorlage ist frei wählbar -- nicht mehr zwingend das Basisszenario.
  onCopyFrom: (scenarioId: string) => void;
  onDelete: (scenarioId: string) => void;
}) {
  const { data, error } = useDashboard(planId, reloadKey);
  if (error) return <p className="text-sm text-danger">{error}</p>;
  if (!data) return <p className="text-sm text-muted">Wird geladen…</p>;

  const nameById = new Map(data.scenarios.map((s) => [s.id, s.name]));
  const baseId = data.scenarios.find((s) => s.isBase)?.id ?? data.scenarios[0]?.id;

  return (
    <div className="flex flex-col gap-4">
      <div className="flex items-center justify-between">
        <h2 className="text-lg font-semibold text-fg">Szenarien</h2>
        {baseId && (
          <Button onClick={() => onCopyFrom(baseId)}>
            <Plus className="h-4 w-4" /> Neues Szenario
          </Button>
        )}
      </div>

      <div className="overflow-x-auto rounded-xl border border-border">
        <table className="w-full border-collapse text-sm">
          <thead>
            <tr className="bg-surface-2 text-xs text-faint">
              <th className="px-3 py-2 text-left font-semibold">Szenario</th>
              <th className="px-3 py-2 text-right font-semibold">Version</th>
              <th className="px-3 py-2 text-right font-semibold">Phasen</th>
              <th className="px-3 py-2 text-right font-semibold">Elemente</th>
              <th className="px-3 py-2 text-right font-semibold">Endvermögen (nom.)</th>
              <th className="px-3 py-2 text-right font-semibold">Kapital reicht</th>
              <th className="px-3 py-2 text-right font-semibold">Aktionen</th>
            </tr>
          </thead>
          <tbody>
            {data.scenarios.map((s) => (
              // Die ganze Zeile öffnet die Matrix -- der frühere «Matrix»-Knopf entfällt.
              <tr
                key={s.id}
                onClick={() => onOpenMatrix(s.id)}
                className={`cursor-pointer border-t border-border transition-colors hover:bg-accent-soft/40 ${
                  s.isBase ? "bg-accent-soft/20" : ""
                }`}
              >
                <td className="px-3 py-2">
                  <div className="flex items-center gap-2">
                    <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>
                    )}
                  </div>
                  {s.parentScenarioId && (
                    <div className="flex items-center gap-1 text-[11px] text-faint">
                      <GitBranch className="h-3 w-3" /> aus {nameById.get(s.parentScenarioId) ?? "…"}
                    </div>
                  )}
                </td>
                <td className="px-3 py-2 text-right">
                  <div className="tabular-nums text-muted">{s.version ?? "–"}</div>
                  {s.versionComment && (
                    <div className="max-w-48 truncate text-[11px] text-faint" title={s.versionComment}>
                      «{s.versionComment}»
                    </div>
                  )}
                </td>
                <td className="px-3 py-2 text-right tabular-nums text-muted">{s.phaseCount}</td>
                <td className="px-3 py-2 text-right tabular-nums text-muted">{s.elementCount}</td>
                <td className="px-3 py-2 text-right tabular-nums text-fg">{formatChf(s.endNominal)}</td>
                <td className="px-3 py-2 text-right">
                  {s.ruinAge !== null ? (
                    <span className="text-danger">Alter {s.ruinAge}</span>
                  ) : (
                    <span className="text-success">Planende</span>
                  )}
                </td>
                {/* Aktionen: stopPropagation, sonst öffnet der Zeilenklick die Matrix. */}
                <td className="px-3 py-2" onClick={(e) => e.stopPropagation()}>
                  <div className="flex items-center justify-end gap-1.5">
                    <button
                      type="button"
                      title="Änderungshistorie"
                      onClick={() => onOpenHistory(s.id)}
                      className="flex items-center gap-1 rounded-lg border border-border px-2 py-1 text-[11px] text-muted hover:bg-surface-2 hover:text-fg"
                    >
                      <History className="h-3.5 w-3.5" /> Historie
                    </button>
                    <button
                      type="button"
                      title="Neues Szenario aus diesem"
                      onClick={() => onCopyFrom(s.id)}
                      className="flex items-center gap-1 rounded-lg border border-border px-2 py-1 text-[11px] text-muted hover:bg-surface-2 hover:text-fg"
                    >
                      <Plus className="h-3.5 w-3.5" /> Kopie
                    </button>
                    {!s.isBase && (
                      <button
                        type="button"
                        aria-label="Szenario löschen"
                        title="Szenario löschen"
                        onClick={() => onDelete(s.id)}
                        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>
                </td>
              </tr>
            ))}
          </tbody>
        </table>
      </div>
    </div>
  );
}

// =========================================================================================
// Analysen: vier Kacheln + Liste der gespeicherten
// =========================================================================================
export type ToolKind = "CHART" | "MONTE_CARLO" | "SENSITIVITY" | "LIVESIM";

const TILES: { kind: ToolKind; title: string; icon: typeof BarChart3; blurb: string }[] = [
  {
    kind: "CHART",
    title: "Grafiken",
    icon: LineChartIcon,
    blurb:
      "Vermögensverlauf, Einkommen vs. Ausgaben oder Vermögensaufteilung – wähle eine Grafik und ob nominal/real und Plan/effektiv gezeigt werden.",
  },
  {
    kind: "LIVESIM",
    title: "Live-Simulation",
    icon: SlidersHorizontal,
    blurb: "Dreh an Reglern (Rendite, Ausgaben, Inflation …) und sieh die Wirkung sofort – ohne etwas zu speichern.",
  },
  {
    kind: "MONTE_CARLO",
    title: "Monte-Carlo",
    icon: Dices,
    blurb: "Tausende Zufallspfade zeigen, wie wahrscheinlich deine Planung hält und dein Ziel erreicht wird.",
  },
  {
    kind: "SENSITIVITY",
    title: "Einflussfaktoren",
    icon: Tornado,
    blurb: "Welche deiner Annahmen entscheidet überhaupt über das Ergebnis? Ein Tornado ordnet sie nach Wirkung.",
  },
];

function typeIcon(t: AnalysisType) {
  return t === "MONTE_CARLO" ? Dices : t === "SENSITIVITY" ? Tornado : BarChart3;
}

export function AnalysesView({
  planId,
  onLaunch,
  onOpenSaved,
}: {
  planId: string;
  onLaunch: (kind: ToolKind) => void;
  onOpenSaved: (id: string) => void;
}) {
  const [saved, setSaved] = useState<SavedAnalysisMeta[] | null>(null);
  const [error, setError] = useState<string | null>(null);
  const confirm = useConfirm();
  const toast = useToast();

  const load = useCallback(async () => {
    try {
      const d = await api.get<{ analyses: SavedAnalysisMeta[] }>(`/api/plans/${planId}/analyses`);
      setSaved(d.analyses);
    } catch (e) {
      setError(e instanceof Error ? e.message : "Konnte nicht geladen werden.");
    }
  }, [planId]);

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

  async function remove(a: SavedAnalysisMeta) {
    const ok = await confirm({ title: "Analyse löschen?", message: `«${a.name}» wird entfernt.`, confirmLabel: "Löschen", danger: true });
    if (!ok) return;
    try {
      await api.delete(`/api/plans/${planId}/analyses/${a.id}`);
      await load();
      toast("success", "Analyse gelöscht.");
    } catch (e) {
      toast("error", e instanceof Error ? e.message : "Löschen fehlgeschlagen.");
    }
  }

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

  return (
    <div className="flex flex-col gap-6">
      <h2 className="text-lg font-semibold text-fg">Analysen</h2>

      {/* Vier Kacheln, die beim Darüberfahren (oder Antippen) umklappen. */}
      <div className="grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-4">
        {TILES.map((t) => (
          <FlipTile key={t.kind} tile={t} onClick={() => onLaunch(t.kind)} />
        ))}
      </div>

      <div>
        <h3 className="mb-2 text-sm font-semibold text-fg">Gespeicherte Analysen</h3>
        {error && <p className="text-xs text-danger">{error}</p>}
        {!saved && !error && <p className="text-xs text-muted">Wird geladen…</p>}
        {saved && saved.length === 0 && (
          <p className="rounded-lg border border-dashed border-border bg-surface-2 p-4 text-xs text-muted">
            Noch nichts gespeichert. In jedem Werkzeug oben kannst du ein Ergebnis festhalten – es erscheint dann hier.
          </p>
        )}
        {saved && saved.length > 0 && (
          <div className="flex flex-col gap-2">
            {saved.map((a) => {
              const Icon = typeIcon(a.type);
              return (
                <div key={a.id} className="flex flex-wrap items-center gap-3 rounded-xl border border-border bg-surface-2 p-3">
                  <Icon 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">{a.name}</div>
                    <div className="text-[11px] text-muted">
                      {ANALYSIS_TYPE_LABEL[a.type]} · {dt(a.createdAt)}
                      {a.scenarioName ? ` · ${a.scenarioName}${a.versionLabel ? ` ${a.versionLabel}` : ""}` : ""} ·{" "}
                      {a.metric === "real" ? "real" : "nominal"} · {sourceLabel(a.source)}
                      {a.summary ? ` · ${a.summary}` : ""}
                    </div>
                  </div>
                  <button
                    type="button"
                    onClick={() => onOpenSaved(a.id)}
                    className="flex items-center gap-1 rounded-lg border border-border px-2 py-1 text-[11px] text-muted hover:bg-surface-2 hover:text-fg"
                  >
                    <Eye className="h-3.5 w-3.5" /> Anzeigen
                  </button>
                  <button
                    type="button"
                    onClick={() => remove(a)}
                    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>
    </div>
  );
}

function FlipTile({ tile, onClick }: { tile: (typeof TILES)[number]; onClick: () => void }) {
  const [flipped, setFlipped] = useState(false);
  const Icon = tile.icon;
  return (
    <button
      type="button"
      onClick={onClick}
      onMouseEnter={() => setFlipped(true)}
      onMouseLeave={() => setFlipped(false)}
      // Touch hat kein Hover -- ein Antippen des Info-Bereichs klappt um, statt gleich zu starten.
      className="group relative flex h-40 flex-col items-start justify-between overflow-hidden rounded-2xl border border-border bg-surface p-4 text-left shadow-sm transition-all hover:-translate-y-0.5 hover:border-accent hover:shadow-md"
    >
      {!flipped ? (
        <>
          <Icon className="h-8 w-8 text-accent" />
          <div>
            <div className="text-sm font-semibold text-fg">{tile.title}</div>
            <div className="text-[11px] text-faint">Zum Starten klicken</div>
          </div>
        </>
      ) : (
        <div className="flex h-full flex-col">
          <div className="mb-1 flex items-center gap-1.5 text-sm font-semibold text-accent">
            <Icon className="h-4 w-4" /> {tile.title}
          </div>
          <p className="text-[11px] leading-relaxed text-muted">{tile.blurb}</p>
          <span className="mt-auto text-[11px] font-medium text-accent">Starten →</span>
        </div>
      )}
    </button>
  );
}
