"use client";

import { useMemo, useState } from "react";
import {
  Area,
  AreaChart,
  Cell,
  Legend,
  Pie,
  PieChart,
  ReferenceLine,
  ResponsiveContainer,
  Tooltip,
  XAxis,
  YAxis,
} from "recharts";
import { formatChf } from "@/lib/format";
import type { PlanComputed } from "@/lib/calculations";

// Diagramm-Palette aus den Theme-Tokens (globals.css) statt fester Hex-Werte -- so passt sie
// sich Hell/Dunkel/Warm an. Recharts reicht die Werte als SVG-Attribut durch, der Browser
// löst `var(...)` dort auf.
export const CHART_PALETTE = [
  "var(--chart-1)",
  "var(--chart-2)",
  "var(--chart-3)",
  "var(--chart-4)",
  "var(--chart-5)",
  "var(--chart-6)",
];

// Einheitliches Aussehen der Recharts-Tooltips (folgt dem Farbschema).
export const TOOLTIP_STYLE = {
  background: "var(--surface)",
  border: "1px solid var(--border)",
  borderRadius: "0.5rem",
  fontSize: 12,
  color: "var(--fg)",
} as const;

const ASSET_CATS = ["PENSION_FUND", "PILLAR_3A", "REAL_ESTATE", "OTHER_ASSET"];

// Gestapelte Vermögensaufteilung.
//
// Bis 0.30 waren das gestapelte Balken mit je zwei Säulen pro Phase (Beginn/Ende) und schräg
// gestellter Beschriftung -- schwer lesbar, sobald es mehr als zwei Phasen gab. Neu:
//   * eine gestapelte FLÄCHE über alle Planjahre (zeigt den Verlauf statt zweier Stichproben),
//     Phasengrenzen als feine senkrechte Linien,
//   * daneben ein RING für ein wählbares Jahr, der die RELATIVE Aufteilung zeigt.
// Ein Klick in die Fläche wählt das Jahr des Rings.
export function AllocationChart({ computed, height = 300 }: { computed: PlanComputed; height?: number }) {
  // Asset-Elemente (nach id, damit gleiche Namen nicht kollidieren), die irgendwann einen
  // positiven Wert haben -- in Reihenfolge ihres ersten Auftretens.
  const assetEls = useMemo(() => {
    const info = new Map<string, { name: string; any: boolean }>();
    for (const phase of computed.phases) {
      for (const el of phase.elements) {
        if (!ASSET_CATS.includes(el.category)) continue;
        const cur = info.get(el.elementId) ?? { name: el.name, any: false };
        cur.name = el.name;
        if (el.startValue > 0 || el.endValue > 0) cur.any = true;
        info.set(el.elementId, cur);
      }
    }
    return [...info.entries()].filter(([, v]) => v.any).map(([id, v]) => ({ id, name: v.name }));
  }, [computed]);

  // Je Planjahr eine Zeile mit dem Wert jedes Elements. Die Jahreswerte liegen bereits in
  // `ElementPhaseComputed.yearly` (seit 0.11) -- hier wird nur umsortiert, nichts gerechnet.
  const areaData = useMemo(() => {
    const byYear = new Map<number, Record<string, number>>();
    const ageOf = new Map<number, number>();
    for (const phase of computed.phases) {
      for (const el of phase.elements) {
        if (!ASSET_CATS.includes(el.category)) continue;
        for (const y of el.yearly) {
          const row = byYear.get(y.year) ?? {};
          row[el.elementId] = Math.max(0, Math.round(y.value));
          byYear.set(y.year, row);
          ageOf.set(y.year, y.age);
        }
      }
    }
    return [...byYear.entries()]
      .sort(([a], [b]) => a - b)
      .map(([year, values]) => ({ year, age: ageOf.get(year) ?? 0, ...values }));
  }, [computed]);

  // Phasengrenzen (kumulierte Dauer) für die Trennlinien.
  const boundaryAges = useMemo(() => {
    const out: number[] = [];
    let acc = 0;
    for (let i = 0; i < computed.phases.length - 1; i++) {
      acc += computed.phases[i].durationYears;
      const age = areaData.find((r) => r.year === acc)?.age;
      if (typeof age === "number") out.push(age);
    }
    return out;
  }, [computed, areaData]);

  // Gewähltes Jahr für den Ring -- Vorgabe: das letzte (Endzustand).
  const [pickedYear, setPickedYear] = useState<number | null>(null);
  const ringRow = areaData.find((r) => r.year === pickedYear) ?? areaData[areaData.length - 1];

  const ringData = useMemo(() => {
    if (!ringRow) return [];
    return assetEls
      .map((el) => ({ name: el.name, value: Number(ringRow[el.id as keyof typeof ringRow] ?? 0) }))
      .filter((d) => d.value > 0);
  }, [assetEls, ringRow]);
  const ringTotal = ringData.reduce((s, d) => s + d.value, 0);

  if (assetEls.length === 0) {
    return <p className="text-sm text-muted">Dieser Plan enthält keine Vermögenselemente.</p>;
  }

  return (
    <div className="flex flex-col gap-4 lg:flex-row">
      {/* Verlauf */}
      <div className="min-w-0 flex-1">
        <div className="mb-1 text-xs font-medium text-muted">
          Verlauf über alle Planjahre <span className="text-faint">· Klick wählt das Jahr für den Ring</span>
        </div>
        <div style={{ height }}>
          <ResponsiveContainer width="100%" height="100%">
            <AreaChart
              data={areaData}
              margin={{ top: 8, right: 8, left: 8, bottom: 4 }}
              style={{ cursor: "pointer" }}
              // Recharts 3 reicht im Klick-Parameter NUR den aktiven Index durch -- das in
              // Version 2 übliche `activePayload` gibt es nicht mehr. Über den Index in
              // `areaData` kommt man an das Planjahr.
              onClick={(state) => {
                const raw = state?.activeIndex ?? state?.activeTooltipIndex;
                const idx = typeof raw === "number" ? raw : Number(raw);
                if (!Number.isInteger(idx) || idx < 0 || idx >= areaData.length) return;
                setPickedYear(areaData[idx].year);
              }}
            >
              <XAxis
                dataKey="age"
                type="number"
                domain={["dataMin", "dataMax"]}
                tick={{ fontSize: 11 }}
                tickFormatter={(v) => `${v} J.`}
                stroke="var(--faint)"
              />
              <YAxis
                tick={{ fontSize: 11 }}
                stroke="var(--faint)"
                tickFormatter={(v) => Intl.NumberFormat("de-CH", { notation: "compact" }).format(v)}
              />
              <Tooltip
                contentStyle={TOOLTIP_STYLE}
                formatter={(v) => (typeof v === "number" ? formatChf(v) : v)}
                labelFormatter={(v) => `Alter ${v}`}
              />
              {boundaryAges.map((age) => (
                <ReferenceLine key={age} x={age} stroke="var(--border-strong)" strokeDasharray="3 3" />
              ))}
              {/* Markierung des Ring-Jahres. */}
              {ringRow && <ReferenceLine x={ringRow.age} stroke="var(--accent)" strokeWidth={1.5} />}
              {assetEls.map((el, i) => (
                <Area
                  key={el.id}
                  type="monotone"
                  dataKey={el.id}
                  name={el.name}
                  stackId="a"
                  stroke={CHART_PALETTE[i % CHART_PALETTE.length]}
                  fill={CHART_PALETTE[i % CHART_PALETTE.length]}
                  fillOpacity={0.75}
                  isAnimationActive={false}
                />
              ))}
              <Legend wrapperStyle={{ fontSize: 12 }} />
            </AreaChart>
          </ResponsiveContainer>
        </div>
      </div>

      {/* Relative Aufteilung im gewählten Jahr */}
      <div className="lg:w-72 lg:shrink-0">
        <div className="mb-1 text-xs font-medium text-muted">
          Aufteilung mit {ringRow?.age ?? "–"} Jahren
          {pickedYear !== null && (
            <button
              type="button"
              onClick={() => setPickedYear(null)}
              className="ml-2 text-[11px] font-normal text-accent hover:underline"
            >
              zurücksetzen
            </button>
          )}
        </div>
        <div style={{ height }}>
          <ResponsiveContainer width="100%" height="100%">
            <PieChart>
              <Pie
                data={ringData}
                dataKey="value"
                nameKey="name"
                innerRadius="55%"
                outerRadius="80%"
                paddingAngle={1}
                isAnimationActive={false}
              >
                {ringData.map((d, i) => (
                  <Cell key={d.name} fill={CHART_PALETTE[i % CHART_PALETTE.length]} />
                ))}
              </Pie>
              <Tooltip
                contentStyle={TOOLTIP_STYLE}
                formatter={(v) =>
                  typeof v === "number"
                    ? `${formatChf(v)} · ${ringTotal > 0 ? Math.round((v / ringTotal) * 100) : 0} %`
                    : v
                }
              />
            </PieChart>
          </ResponsiveContainer>
        </div>
        <div className="-mt-2 text-center text-xs text-muted">
          Total <strong className="text-fg">{formatChf(ringTotal)}</strong>
        </div>
      </div>
    </div>
  );
}
