"use client";

import { useMemo, useState } from "react";
import { Bar, BarChart, CartesianGrid, Legend, ResponsiveContainer, Tooltip, XAxis, YAxis } from "recharts";
import { BarChart3, Download, LineChart as LineChartIcon } from "lucide-react";
import { WealthChart, type TimelineSeries } from "@/components/WealthChart";
import { SparquoteChart } from "@/components/SparquoteChart";
import { api } from "@/lib/api-client";
import { formatChf } from "@/lib/format";
import type { PlanComputed } from "@/lib/calculations";
import type { PlanInput } from "@/lib/types";

const PALETTE = ["#4f46e5", "#0ea5e9", "#16a34a", "#d97706", "#dc2626", "#7c3äd"];

interface PlanListItem {
  id: string;
  name: string;
}

export function Dashboard({
  plan,
  computed,
  siblings,
}: {
  plan: PlanInput;
  computed: PlanComputed;
  // Die übrigen Szenarien desselben Plans -- nur die sind sinnvoll vergleichbar.
  siblings: PlanListItem[];
}) {
  const [compareIds, setCompareIds] = useState<string[]>([]);
  const [compareData, setCompareData] = useState<Record<string, PlanComputed>>({});

  async function toggleCompare(id: string) {
    if (compareIds.includes(id)) {
      setCompareIds((prev) => prev.filter((p) => p !== id));
      return;
    }
    setCompareIds((prev) => [...prev, id]);
    if (!compareData[id]) {
      const data = await api.get<{ computed: PlanComputed }>(`/api/scenarios/${id}`);
      setCompareData((prev) => ({ ...prev, [id]: data.computed }));
    }
  }

  const series: TimelineSeries[] = useMemo(() => {
    const result: TimelineSeries[] = [{ label: plan.name, color: PALETTE[0], computed }];
    compareIds.forEach((id, i) => {
      const c = compareData[id];
      const name = siblings.find((p) => p.id === id)?.name ?? id;
      if (c) result.push({ label: name, color: PALETTE[(i + 1) % PALETTE.length], computed: c });
    });
    return result;
  }, [plan.name, computed, compareIds, compareData, siblings]);

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

  // 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 }));
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [computed]);

  // Je Phase zwei Kategorien auf der x-Achse: Beginn und Ende. Werte je Asset-Element.
  const barData = useMemo(
    () =>
      computed.phases.flatMap((phase) => {
        const beginn: Record<string, number | string> = { label: `${phase.name} · Beginn` };
        const ende: Record<string, number | string> = { label: `${phase.name} · Ende` };
        for (const el of phase.elements) {
          if (!ASSET_CATS.includes(el.category)) continue;
          beginn[el.elementId] = Math.max(0, Math.round(el.startValue));
          ende[el.elementId] = Math.max(0, Math.round(el.endValue));
        }
        return [beginn, ende];
      }),
    // eslint-disable-next-line react-hooks/exhaustive-deps
    [computed]
  );

  const otherPlans = siblings;
  const lastPhase = computed.phases[computed.phases.length - 1];

  return (
    <div className="flex flex-col gap-6">
      <div className="grid grid-cols-1 gap-4 sm:grid-cols-2">
        <StatCard label="Endvermögen (nominal)" value={lastPhase ? lastPhase.endWealthNominal : 0} />
        <StatCard label="Endvermögen (real, kaufkraftbereinigt)" value={lastPhase ? lastPhase.endWealthReal : 0} />
      </div>

      <section className="rounded-xl border border-border bg-surface p-4 shadow-sm">
        <h3 className="mb-1 flex items-center gap-1.5 text-sm font-semibold text-fg">
          <LineChartIcon className="h-4 w-4 text-accent" />
          Einkommen vs. Ausgaben pro Jahr
        </h3>
        <p className="mb-3 text-xs text-muted">
          Die Fläche zwischen Einkommen und nominalen Ausgaben ist die Spar- (grün) bzw. Verzehrquote (rot).
          Die blasse Linie sind die realen Ausgaben &ndash; der Abstand zur nominalen Linie ist der Inflationsanteil.
        </p>
        <SparquoteChart computed={computed} />
      </section>

      <section className="rounded-xl border border-border bg-surface p-4 shadow-sm">
        <div className="mb-3 flex flex-wrap items-center justify-between gap-2">
          <h3 className="flex items-center gap-1.5 text-sm font-semibold text-fg">
            <LineChartIcon className="h-4 w-4 text-accent" />
            Vermögensverlauf nach Alter
          </h3>
          <a
            href={`/api/scenarios/${plan.id}/export`}
            className="flex items-center gap-1.5 rounded-lg border border-border px-3 py-1.5 text-xs font-medium text-muted hover:bg-surface-2"
          >
            <Download className="h-3.5 w-3.5" />
            CSV-Export
          </a>
        </div>
        {otherPlans.length > 0 && (
          <div className="mb-3 flex flex-wrap gap-2">
            <span className="text-xs text-muted">Szenarien vergleichen:</span>
            {otherPlans.map((p) => (
              <label key={p.id} className="flex items-center gap-1 text-xs text-muted">
                <input
                  type="checkbox"
                  checked={compareIds.includes(p.id)}
                  onChange={() => toggleCompare(p.id)}
                />
                {p.name}
              </label>
            ))}
          </div>
        )}
        <WealthChart series={series} />
      </section>

      <section className="rounded-xl border border-border bg-surface p-4 shadow-sm">
        <h3 className="mb-1 flex items-center gap-1.5 text-sm font-semibold text-fg">
          <BarChart3 className="h-4 w-4 text-accent" />
          Vermögensaufteilung pro Phase (Beginn &amp; Ende)
        </h3>
        <p className="mb-3 text-xs text-muted">
          Je Phase links die Aufteilung zu Beginn, rechts am Ende. Das Ende einer Phase entspricht im
          Gesamtvolumen dem Beginn der nächsten &ndash; die Aufteilung kann durch Umschichtung abweichen.
        </p>
        <div className="h-72 w-full">
          <ResponsiveContainer width="100%" height="100%">
            <BarChart data={barData} margin={{ top: 8, right: 16, left: 8, bottom: 8 }}>
              <CartesianGrid strokeDasharray="3 3" className="stroke-border" />
              <XAxis dataKey="label" tick={{ fontSize: 10 }} interval={0} angle={-30} textAnchor="end" height={70} />
              <YAxis
                tick={{ fontSize: 11 }}
                tickFormatter={(v) => Intl.NumberFormat("de-CH", { notation: "compact" }).format(v)}
              />
              <Tooltip formatter={(v) => (typeof v === "number" ? formatChf(v) : v)} />
              <Legend wrapperStyle={{ fontSize: 12 }} />
              {assetEls.map((el, i) => (
                <Bar key={el.id} dataKey={el.id} name={el.name} stackId="a" fill={PALETTE[i % PALETTE.length]} />
              ))}
            </BarChart>
          </ResponsiveContainer>
        </div>
      </section>
    </div>
  );
}

function StatCard({ label, value, help }: { label: string; value: number; help?: string }) {
  return (
    <div className="rounded-xl border border-border bg-surface p-4 shadow-sm">
      <div className="text-xs text-muted" title={help}>
        {label}
      </div>
      <div className="mt-1 text-xl font-semibold text-accent">
        {formatChf(value)} CHF
      </div>
    </div>
  );
}
