"use client";

import { useMemo, useState } from "react";
import {
  ArrowDownRight,
  ArrowUpRight,
  Brain,
  CalendarDays,
  ChevronLeft,
  ChevronRight,
  CreditCard,
  PieChart,
  Plus,
  Repeat,
  Tags,
  Trash2,
  TrendingDown,
  TrendingUp,
  Upload,
  Wallet,
  Zap,
  Coffee,
  Home,
  Car,
  Briefcase,
  ShoppingBag,
  Utensils,
  Dumbbell,
  Tv,
  Music,
  Smartphone,
  Wifi,
  GraduationCap,
  Heart,
  Plane,
  Gift,
  Euro,
  Building2,
  Pause,
  Play,
} from "lucide-react";
import { Badge } from "@/components/ui/badge";
import { Button } from "@/components/ui/button";
import { EmptyState } from "@/components/ui/empty-state";
import { Input } from "@/components/ui/input";
import { Modal } from "@/components/ui/modal";
import { Skeleton } from "@/components/ui/skeleton";
import { Textarea } from "@/components/ui/textarea";
import { useFinances, type FinanceTransactionInput } from "@/hooks/use-finances";
import { cn, formatDate } from "@/lib/utils";
import { PnLChart } from "@/components/finances/pnl-chart";
import { PnLExport } from "@/components/finances/pnl-export";
import type {
  FinanceCategoryType,
  FinanceRecurringFrequency,
  FinanceRecurringItem,
  FinanceTransactionType,
} from "@/types";

/* ─── Quick-add presets ─── */

interface QuickPreset {
  label: string;
  type: FinanceTransactionType;
  category: string;
  icon: React.ComponentType<{ className?: string }>;
  color: string;
  recurring?: boolean;
  frequency?: FinanceRecurringFrequency;
  amount?: string;
}

const QUICK_INCOME_PRESETS: QuickPreset[] = [
  { label: "Gehalt", type: "income", category: "Gehalt", icon: Briefcase, color: "#10b981", recurring: true, frequency: "monthly" },
  { label: "Mieteinnahmen", type: "income", category: "Mieteinnahmen", icon: Building2, color: "#6366f1", recurring: true, frequency: "monthly" },
  { label: "Nebenjob", type: "income", category: "Nebeneinkommen", icon: Zap, color: "#f59e0b" },
  { label: "Freelance", type: "income", category: "Freelance", icon: Briefcase, color: "#8b5cf6" },
  { label: "Dividende", type: "income", category: "Investments", icon: TrendingUp, color: "#06b6d4", recurring: true, frequency: "yearly" },
  { label: "Geschenk", type: "income", category: "Geschenk", icon: Gift, color: "#ec4899" },
];

const QUICK_EXPENSE_PRESETS: QuickPreset[] = [
  { label: "Miete", type: "expense", category: "Miete", icon: Home, color: "#ef4444", recurring: true, frequency: "monthly" },
  { label: "Lebensmittel", type: "expense", category: "Lebensmittel", icon: ShoppingBag, color: "#f59e0b" },
  { label: "Essen gehen", type: "expense", category: "Essen gehen", icon: Utensils, color: "#ec4899" },
  { label: "Transport", type: "expense", category: "Transport", icon: Car, color: "#3b82f6" },
  { label: "Shopping", type: "expense", category: "Shopping", icon: ShoppingBag, color: "#8b5cf6" },
  { label: "Sport", type: "expense", category: "Sport & Fitness", icon: Dumbbell, color: "#10b981" },
  { label: "Streaming", type: "expense", category: "Abonnements", icon: Tv, color: "#6366f1", recurring: true, frequency: "monthly" },
  { label: "Musik-Abo", type: "expense", category: "Abonnements", icon: Music, color: "#ec4899", recurring: true, frequency: "monthly" },
  { label: "Handy", type: "expense", category: "Abonnements", icon: Smartphone, color: "#06b6d4", recurring: true, frequency: "monthly" },
  { label: "Internet", type: "expense", category: "Abonnements", icon: Wifi, color: "#3b82f6", recurring: true, frequency: "monthly" },
  { label: "Versicherung", type: "expense", category: "Versicherung", icon: Heart, color: "#ef4444", recurring: true, frequency: "monthly" },
  { label: "Bildung", type: "expense", category: "Bildung", icon: GraduationCap, color: "#f59e0b" },
  { label: "Reise", type: "expense", category: "Reise", icon: Plane, color: "#06b6d4" },
  { label: "Kaffee", type: "expense", category: "Essen gehen", icon: Coffee, color: "#92400e" },
  { label: "Netflix", type: "expense", category: "Abonnements", icon: Tv, color: "#e50914", recurring: true, frequency: "monthly" },
  { label: "Spotify", type: "expense", category: "Abonnements", icon: Music, color: "#1db954", recurring: true, frequency: "monthly" },
  { label: "ChatGPT", type: "expense", category: "Software", icon: Brain, color: "#10b981", recurring: true, frequency: "monthly" },
  { label: "Apple One", type: "expense", category: "Abonnements", icon: Smartphone, color: "#555555", recurring: true, frequency: "monthly" },
  { label: "GitHub", type: "expense", category: "Software", icon: Zap, color: "#6e40c9", recurring: true, frequency: "monthly" },
];

/* ─── Constants ─── */

const DEFAULT_CATEGORIES = [
  "Gehalt",
  "Mieteinnahmen",
  "Nebeneinkommen",
  "Freelance",
  "Investments",
  "Miete",
  "Lebensmittel",
  "Essen gehen",
  "Abonnements",
  "Transport",
  "Shopping",
  "Software",
  "Sport & Fitness",
  "Gesundheit",
  "Versicherung",
  "Bildung",
  "Reise",
  "Business",
  "Freizeit",
  "Sparen",
  "Geschenk",
  "Sonstiges",
];

const CATEGORY_COLORS = [
  "#6366f1",
  "#ec4899",
  "#f59e0b",
  "#10b981",
  "#3b82f6",
  "#8b5cf6",
  "#ef4444",
  "#06b6d4",
];

const FREQUENCY_LABELS: Record<FinanceRecurringFrequency, string> = {
  weekly: "Wöchentlich",
  monthly: "Monatlich",
  yearly: "Jährlich",
};

/* ─── Helpers ─── */

function todayDate() {
  return new Date().toISOString().split("T")[0];
}

function currentMonth() {
  return todayDate().slice(0, 7);
}

function shiftMonth(month: string, offset: number) {
  const date = new Date(`${month}-01T00:00:00`);
  date.setMonth(date.getMonth() + offset);
  return date.toISOString().slice(0, 7);
}

function monthStart(month: string) {
  return `${month}-01`;
}

function formatMoney(cents: number, currency = "EUR") {
  return new Intl.NumberFormat("de-DE", {
    style: "currency",
    currency,
  }).format(cents / 100);
}

function formatMonthLabel(month: string) {
  const d = new Date(`${month}-01T00:00:00`);
  return d.toLocaleDateString("de-DE", { month: "long", year: "numeric" });
}

function parseCsvLine(line: string): string[] {
  const cells: string[] = [];
  let current = "";
  let inQuotes = false;
  for (const char of line) {
    if (char === '"') {
      inQuotes = !inQuotes;
    } else if (char === "," && !inQuotes) {
      cells.push(current.trim());
      current = "";
    } else {
      current += char;
    }
  }
  cells.push(current.trim());
  return cells;
}

function parseAmountToCents(value: string) {
  const parsed = Number(value.replace(",", "."));
  if (!Number.isFinite(parsed) || parsed <= 0) return null;
  return Math.round(parsed * 100);
}

function buildCategoryOptions(...sources: string[][]) {
  return Array.from(new Set([...DEFAULT_CATEGORIES, ...sources.flat()].filter(Boolean))).sort();
}

/* ─── Form state types ─── */

type AddMode = "single" | "recurring";

interface UnifiedFormState {
  mode: AddMode;
  type: FinanceTransactionType;
  title: string;
  amount: string;
  category: string;
  transactionDate: string;
  status: "cleared" | "pending";
  description: string;
  frequency: FinanceRecurringFrequency;
  nextDueDate: string;
  business: boolean;
}

type ScopeFilter = "all" | "private" | "business";

const SCOPE_LABELS: Record<ScopeFilter, string> = { all: "Alle", private: "Privat", business: "Geschäftlich" };

interface BudgetFormState {
  category: string;
  amount: string;
}

interface CategoryFormState {
  name: string;
  type: FinanceCategoryType;
  color: string;
}

function defaultUnifiedForm(type: FinanceTransactionType, preset?: QuickPreset): UnifiedFormState {
  return {
    mode: preset?.recurring ? "recurring" : "single",
    type: preset?.type ?? type,
    title: preset?.label ?? "",
    amount: preset?.amount ?? "",
    category: preset?.category ?? (type === "income" ? "Gehalt" : "Lebensmittel"),
    transactionDate: todayDate(),
    status: "cleared",
    description: "",
    frequency: preset?.frequency ?? "monthly",
    nextDueDate: todayDate(),
    business: false,
  };
}

const DEFAULT_BUDGET_FORM: BudgetFormState = { category: "Lebensmittel", amount: "" };
const DEFAULT_CATEGORY_FORM: CategoryFormState = { name: "", type: "both", color: "#6366f1" };

function monthlyEquivalent(item: FinanceRecurringItem) {
  if (item.frequency === "weekly") return Math.round(item.amount_cents * 4.33);
  if (item.frequency === "yearly") return Math.round(item.amount_cents / 12);
  return item.amount_cents;
}

function yearlyEquivalent(item: FinanceRecurringItem) {
  if (item.frequency === "weekly") return item.amount_cents * 52;
  if (item.frequency === "monthly") return item.amount_cents * 12;
  return item.amount_cents;
}

/* ─── Sub icon map for recurring items ─── */
function getSubIcon(title: string, category: string) {
  const t = (title + " " + category).toLowerCase();
  if (t.includes("netflix") || t.includes("stream") || t.includes("disney") || t.includes("prime")) return Tv;
  if (t.includes("spotify") || t.includes("musik") || t.includes("music") || t.includes("apple music")) return Music;
  if (t.includes("handy") || t.includes("mobil") || t.includes("telefon") || t.includes("smartphone")) return Smartphone;
  if (t.includes("internet") || t.includes("wifi") || t.includes("wlan") || t.includes("dsl")) return Wifi;
  if (t.includes("miete") || t.includes("wohn")) return Home;
  if (t.includes("versicherung")) return Heart;
  if (t.includes("gehalt") || t.includes("lohn") || t.includes("salary")) return Briefcase;
  if (t.includes("gym") || t.includes("fitness") || t.includes("sport")) return Dumbbell;
  if (t.includes("auto") || t.includes("tank") || t.includes("transport") || t.includes("bahn")) return Car;
  return CreditCard;
}

/* ─── Tab type ─── */
type FinanceTab = "overview" | "transactions" | "budgets" | "subscriptions";

/* ═══════════════════════════════════════════════════════ */
/*  Page                                                   */
/* ═══════════════════════════════════════════════════════ */

export default function FinancesPage() {
  const {
    transactions: allTransactions,
    budgets,
    recurringItems: allRecurringItems,
    categories,
    loading,
    createTransaction,
    createTransactions,
    updateTransaction,
    deleteTransaction,
    upsertBudget,
    deleteBudget,
    createRecurringItem,
    updateRecurringItem,
    deleteRecurringItem,
    createCategory,
    deleteCategory,
  } = useFinances();

  const [activeTab, setActiveTab] = useState<FinanceTab>("overview");
  const [selectedMonth, setSelectedMonth] = useState(currentMonth());
  const [addFormOpen, setAddFormOpen] = useState(false);
  const [budgetFormOpen, setBudgetFormOpen] = useState(false);
  const [categoryFormOpen, setCategoryFormOpen] = useState(false);
  const [csvImportOpen, setCsvImportOpen] = useState(false);
  const [addFormNewCategory, setAddFormNewCategory] = useState("");
  const [budgetNewCategory, setBudgetNewCategory] = useState("");
  const [form, setForm] = useState<UnifiedFormState>(defaultUnifiedForm("expense"));
  const [budgetForm, setBudgetForm] = useState<BudgetFormState>(DEFAULT_BUDGET_FORM);
  const [categoryForm, setCategoryForm] = useState<CategoryFormState>(DEFAULT_CATEGORY_FORM);
  const [csvText, setCsvText] = useState("");
  const [saving, setSaving] = useState(false);
  const [error, setError] = useState("");
  const [scopeFilter, setScopeFilter] = useState<ScopeFilter>("all");

  /* ─── Privat / Geschäftlich: filters everything below (stats, lists, insights) ─── */
  const transactions = useMemo(
    () => allTransactions.filter((t) => scopeFilter === "all" || (scopeFilter === "business" ? Boolean(t.business) : !t.business)),
    [allTransactions, scopeFilter]
  );
  const recurringItems = useMemo(
    () => allRecurringItems.filter((i) => scopeFilter === "all" || (scopeFilter === "business" ? Boolean(i.business) : !i.business)),
    [allRecurringItems, scopeFilter]
  );

  /* ─── Derived data ─── */

  const monthTransactions = useMemo(
    () => transactions.filter((t) => t.transaction_date.startsWith(selectedMonth)),
    [selectedMonth, transactions]
  );

  const monthBudgets = useMemo(
    () => budgets.filter((b) => b.month.startsWith(selectedMonth)),
    [budgets, selectedMonth]
  );

  const previousMonthTransactions = useMemo(() => {
    const month = shiftMonth(selectedMonth, -1);
    return transactions.filter((t) => t.transaction_date.startsWith(month));
  }, [selectedMonth, transactions]);

  const expenseByCategory = useMemo(() => {
    const totals = new Map<string, number>();
    monthTransactions
      .filter((t) => t.type === "expense")
      .forEach((t) => {
        totals.set(t.category, (totals.get(t.category) || 0) + t.amount_cents);
      });
    return totals;
  }, [monthTransactions]);

  const summary = useMemo(() => {
    const income = monthTransactions.filter((t) => t.type === "income").reduce((s, t) => s + t.amount_cents, 0);
    const expenses = monthTransactions.filter((t) => t.type === "expense").reduce((s, t) => s + t.amount_cents, 0);
    const pending = monthTransactions.filter((t) => t.status === "pending").reduce((s, t) => s + t.amount_cents, 0);
    return { income, expenses, net: income - expenses, pending };
  }, [monthTransactions]);

  const previousSummary = useMemo(() => {
    const income = previousMonthTransactions.filter((t) => t.type === "income").reduce((s, t) => s + t.amount_cents, 0);
    const expenses = previousMonthTransactions.filter((t) => t.type === "expense").reduce((s, t) => s + t.amount_cents, 0);
    return { income, expenses, net: income - expenses };
  }, [previousMonthTransactions]);

  const monthlyFixedExpenses = useMemo(
    () =>
      recurringItems
        .filter((item) => item.is_active && item.type === "expense")
        .reduce((sum, item) => sum + monthlyEquivalent(item), 0),
    [recurringItems]
  );

  const monthlyFixedIncome = useMemo(
    () =>
      recurringItems
        .filter((item) => item.is_active && item.type === "income")
        .reduce((sum, item) => sum + monthlyEquivalent(item), 0),
    [recurringItems]
  );

  const categoryBreakdown = useMemo(
    () =>
      Array.from(expenseByCategory.entries())
        .map(([category, amount]) => ({ category, amount }))
        .sort((a, b) => b.amount - a.amount),
    [expenseByCategory]
  );

  /* ─── Subscriptions / Abos ─── */
  const activeSubscriptions = useMemo(
    () => recurringItems.filter((i) => i.is_active && i.type === "expense"),
    [recurringItems]
  );
  const pausedSubscriptions = useMemo(
    () => recurringItems.filter((i) => !i.is_active && i.type === "expense"),
    [recurringItems]
  );
  const activeIncomeRecurring = useMemo(
    () => recurringItems.filter((i) => i.is_active && i.type === "income"),
    [recurringItems]
  );
  const totalSubscriptionMonthly = useMemo(
    () => activeSubscriptions.reduce((s, i) => s + monthlyEquivalent(i), 0),
    [activeSubscriptions]
  );

  const totalSubscriptionYearly = useMemo(
    () => activeSubscriptions.reduce((s, i) => s + yearlyEquivalent(i), 0),
    [activeSubscriptions]
  );

  const upcomingRenewals = useMemo(() => {
    const now = new Date();
    const in30Days = new Date(now.getTime() + 30 * 24 * 60 * 60 * 1000);
    return activeSubscriptions
      .filter((i) => {
        const due = new Date(i.next_due_date);
        return due >= now && due <= in30Days;
      })
      .sort((a, b) => new Date(a.next_due_date).getTime() - new Date(b.next_due_date).getTime());
  }, [activeSubscriptions]);

  const financeInsights = useMemo(() => {
    const insights: string[] = [];
    const expenseDelta = summary.expenses - previousSummary.expenses;
    const topCategory = categoryBreakdown[0] || null;
    const overBudget = monthBudgets.find(
      (b) => (expenseByCategory.get(b.category) || 0) > b.amount_cents
    );

    if (summary.income === 0 && summary.expenses === 0) {
      insights.push("Füge ein paar Transaktionen hinzu und ich kann deinen Monat automatisch analysieren.");
    } else if (summary.net >= 0) {
      insights.push(`Du bist diesen Monat ${formatMoney(summary.net)} im Plus.`);
    } else {
      insights.push(`Du bist diesen Monat ${formatMoney(Math.abs(summary.net))} im Minus.`);
    }

    if (previousMonthTransactions.length > 0) {
      if (expenseDelta > 0) {
        insights.push(`Ausgaben sind ${formatMoney(expenseDelta)} höher als letzten Monat.`);
      } else if (expenseDelta < 0) {
        insights.push(`Ausgaben sind ${formatMoney(Math.abs(expenseDelta))} niedriger als letzten Monat.`);
      }
    }

    if (topCategory) {
      insights.push(`Größte Kategorie: ${topCategory.category} mit ${formatMoney(topCategory.amount)}.`);
    }

    if (overBudget) {
      insights.push(`${overBudget.category} ist über dem Budget.`);
    }

    if (activeSubscriptions.length > 0) {
      insights.push(`${activeSubscriptions.length} aktive Abos kosten dich ${formatMoney(totalSubscriptionMonthly)}/Monat.`);
    }

    if (monthlyFixedExpenses > 0 && summary.income > 0) {
      insights.push(
        `Nach Fixkosten bleiben ${formatMoney(summary.income - monthlyFixedExpenses)} für variable Ausgaben.`
      );
    }

    return insights.slice(0, 5);
  }, [activeSubscriptions.length, categoryBreakdown, expenseByCategory, monthBudgets, monthlyFixedExpenses, previousMonthTransactions.length, previousSummary.expenses, summary.expenses, summary.income, summary.net, totalSubscriptionMonthly]);

  const categoryOptions = useMemo(
    () =>
      buildCategoryOptions(
        categories.map((c) => c.name),
        transactions.map((t) => t.category),
        budgets.map((b) => b.category),
        recurringItems.map((i) => i.category)
      ),
    [budgets, categories, recurringItems, transactions]
  );

  /* ─── Percentage changes ─── */
  const incomeChange = previousSummary.income > 0
    ? ((summary.income - previousSummary.income) / previousSummary.income) * 100
    : 0;
  const expenseChange = previousSummary.expenses > 0
    ? ((summary.expenses - previousSummary.expenses) / previousSummary.expenses) * 100
    : 0;

  /* ─── Handlers ─── */

  function openAddForm(type: FinanceTransactionType, preset?: QuickPreset) {
    setError("");
    setForm(defaultUnifiedForm(type, preset));
    setAddFormOpen(true);
  }

  async function handleSaveForm() {
    const amountCents = parseAmountToCents(form.amount);
    if (!form.title.trim() || !amountCents) {
      setError("Bitte Titel und gültigen Betrag eingeben.");
      return;
    }
    if (form.category === "__create__") {
      setError("Bitte Kategorie-Name eingeben und mit OK bestätigen.");
      return;
    }
    setSaving(true);
    setError("");
    try {
      if (form.mode === "recurring") {
        await createRecurringItem({
          type: form.type,
          title: form.title.trim(),
          amount_cents: amountCents,
          category: form.category.trim() || "Sonstiges",
          frequency: form.frequency,
          next_due_date: form.nextDueDate,
          business: form.business,
        });
      } else {
        await createTransaction({
          type: form.type,
          title: form.title.trim(),
          amount_cents: amountCents,
          category: form.category.trim() || "Sonstiges",
          transaction_date: form.transactionDate,
          status: form.status,
          description: form.description.trim(),
          business: form.business,
        });
      }
      setAddFormOpen(false);
    } catch (err) {
      setError(err instanceof Error ? err.message : "Konnte nicht gespeichert werden.");
    } finally {
      setSaving(false);
    }
  }

  async function handleSaveBudget() {
    const amountCents = parseAmountToCents(budgetForm.amount);
    if (budgetForm.category === "__create__") {
      setError("Bitte Kategorie-Name eingeben und mit OK bestätigen.");
      return;
    }
    if (!budgetForm.category.trim() || !amountCents) {
      setError("Bitte Kategorie und gültigen Betrag eingeben.");
      return;
    }
    setSaving(true);
    setError("");
    try {
      await upsertBudget({
        category: budgetForm.category.trim(),
        amount_cents: amountCents,
        month: monthStart(selectedMonth),
      });
      setBudgetFormOpen(false);
      setBudgetForm(DEFAULT_BUDGET_FORM);
    } catch (err) {
      setError(err instanceof Error ? err.message : "Budget konnte nicht gespeichert werden.");
    } finally {
      setSaving(false);
    }
  }

  async function handleCreateCategory() {
    if (!categoryForm.name.trim()) {
      setError("Bitte Kategorie-Name eingeben.");
      return;
    }
    setSaving(true);
    setError("");
    try {
      await createCategory({ name: categoryForm.name.trim(), type: categoryForm.type, color: categoryForm.color });
      setCategoryForm(DEFAULT_CATEGORY_FORM);
      setCategoryFormOpen(false);
    } catch (err) {
      setError(err instanceof Error ? err.message : "Kategorie konnte nicht gespeichert werden.");
    } finally {
      setSaving(false);
    }
  }

  async function handleImportCsv() {
    const lines = csvText.split(/\r?\n/).map((l) => l.trim()).filter(Boolean);
    if (lines.length === 0) { setError("Bitte CSV-Zeilen einfügen."); return; }
    const rows = /^type,/i.test(lines[0]) ? lines.slice(1) : lines;
    const inputs: FinanceTransactionInput[] = rows
      .map((line) => parseCsvLine(line))
      .map(([type, title, amount, category, date, status, ...descParts]) => {
        const amountCents = parseAmountToCents(amount || "");
        const txType: FinanceTransactionType = type === "income" ? "income" : "expense";
        if (!title || !amountCents) return null;
        return { type: txType, title, amount_cents: amountCents, category: category || "Sonstiges", transaction_date: date || todayDate(), status: status === "pending" ? ("pending" as const) : ("cleared" as const), description: descParts.join(", ") };
      })
      .filter((item): item is NonNullable<typeof item> => Boolean(item));
    if (inputs.length === 0) { setError("Keine gültigen CSV-Zeilen."); return; }
    setSaving(true);
    setError("");
    try {
      await createTransactions(inputs);
      setCsvText("");
      setCsvImportOpen(false);
    } catch (err) {
      setError(err instanceof Error ? err.message : "CSV konnte nicht importiert werden.");
    } finally {
      setSaving(false);
    }
  }

  async function addRecurringAsTransaction(item: FinanceRecurringItem) {
    await createTransaction({ type: item.type, title: item.title, amount_cents: item.amount_cents, category: item.category, transaction_date: item.next_due_date, status: "pending", business: Boolean(item.business) });
  }

  function BusinessToggle({ business, onToggle }: { business?: boolean; onToggle: () => void }) {
    return (
      <button
        type="button"
        onClick={onToggle}
        title="Zwischen privat und geschäftlich umschalten"
        className={cn(
          "rounded-full border px-2 py-0.5 text-[10px] font-semibold transition-colors",
          business
            ? "border-amber-500/40 bg-amber-500/10 text-amber-500 hover:bg-amber-500/20"
            : "border-border/60 text-muted-foreground hover:text-foreground"
        )}
      >
        {business ? "Geschäftlich" : "Privat"}
      </button>
    );
  }

  /* ─── Tabs ─── */
  const TABS: { key: FinanceTab; label: string; count?: number }[] = [
    { key: "overview", label: "Übersicht" },
    { key: "transactions", label: "Transaktionen", count: monthTransactions.length },
    { key: "subscriptions", label: "Abos & Fixkosten", count: recurringItems.length },
    { key: "budgets", label: "Budgets", count: monthBudgets.length },
  ];

  /* ─── Loading ─── */
  if (loading) {
    return (
      <div className="mx-auto max-w-[1200px] px-6 py-8">
        <div className="mb-8 flex items-center gap-3">
          <div className="flex h-10 w-10 items-center justify-center rounded-xl bg-gradient-to-br from-emerald-500 to-teal-600">
            <Wallet className="h-5 w-5 text-white" />
          </div>
          <div>
            <Skeleton className="h-6 w-32" />
            <Skeleton className="mt-1 h-4 w-48" />
          </div>
        </div>
        <div className="grid gap-4 md:grid-cols-4">
          {Array.from({ length: 4 }).map((_, i) => (
            <Skeleton key={i} className="h-32 rounded-2xl" />
          ))}
        </div>
      </div>
    );
  }

  /* ═══════════════════════════════════════════════════════ */
  /*  Render                                                */
  /* ═══════════════════════════════════════════════════════ */

  return (
    <div className="mx-auto max-w-[1200px] px-6 py-8 space-y-8">


      {/* ─── Header ─── */}
      <div className="flex flex-wrap items-start justify-between gap-4">
        <div className="flex items-center gap-3.5">
          <div className="relative">
            <div className="flex h-11 w-11 items-center justify-center rounded-xl bg-gradient-to-br from-emerald-500 to-teal-600 shadow-lg shadow-emerald-500/20">
              <Wallet className="h-5 w-5 text-white" />
            </div>
            <div className="absolute -inset-1 rounded-xl bg-gradient-to-br from-emerald-500/20 to-teal-600/20 blur-lg -z-10" />
          </div>
          <div>
            <h1 className="text-xl font-bold tracking-tight">Finanzen</h1>
            <p className="text-sm text-muted-foreground">Einnahmen, Ausgaben & Abos verwalten</p>
          </div>
        </div>

        <div className="flex flex-wrap gap-2">
          <Button size="sm" variant="outline" onClick={() => setCsvImportOpen(true)} className="gap-1.5">
            <Upload className="h-3.5 w-3.5" />
            CSV Import
          </Button>
          <Button size="sm" variant="outline" onClick={() => setCategoryFormOpen(true)} className="gap-1.5">
            <Tags className="h-3.5 w-3.5" />
            Kategorien
          </Button>
          <Button size="sm" variant="outline" onClick={() => openAddForm("income")} className="gap-1.5">
            <TrendingUp className="h-3.5 w-3.5" />
            Einnahme
          </Button>
          <Button size="sm" onClick={() => openAddForm("expense")} className="gap-1.5">
            <TrendingDown className="h-3.5 w-3.5" />
            Ausgabe
          </Button>
        </div>
      </div>

      {/* ─── Month selector ─── */}
      <div className="flex items-center gap-3">
        <button onClick={() => setSelectedMonth(shiftMonth(selectedMonth, -1))} className="flex h-8 w-8 items-center justify-center rounded-lg border border-border/60 bg-card text-muted-foreground hover:text-foreground hover:bg-accent/50 transition-colors">
          <ChevronLeft className="h-4 w-4" />
        </button>
        <span className="text-sm font-semibold min-w-[160px] text-center">{formatMonthLabel(selectedMonth)}</span>
        <button onClick={() => setSelectedMonth(shiftMonth(selectedMonth, 1))} className="flex h-8 w-8 items-center justify-center rounded-lg border border-border/60 bg-card text-muted-foreground hover:text-foreground hover:bg-accent/50 transition-colors">
          <ChevronRight className="h-4 w-4" />
        </button>
        {selectedMonth !== currentMonth() && (
          <button onClick={() => setSelectedMonth(currentMonth())} className="text-xs text-muted-foreground hover:text-foreground transition-colors">Heute</button>
        )}
        <div role="radiogroup" aria-label="Privat oder geschäftlich" className="ml-auto flex items-center gap-1 rounded-xl border border-border/60 bg-card p-1">
          {(Object.keys(SCOPE_LABELS) as ScopeFilter[]).map((scope) => (
            <button
              key={scope}
              type="button"
              role="radio"
              aria-checked={scopeFilter === scope}
              onClick={() => setScopeFilter(scope)}
              className={cn(
                "rounded-lg px-3 py-1.5 text-xs font-medium transition-all",
                scopeFilter === scope
                  ? scope === "business"
                    ? "bg-amber-500/15 text-amber-500"
                    : "bg-foreground text-background"
                  : "text-muted-foreground hover:text-foreground"
              )}
            >
              {SCOPE_LABELS[scope]}
            </button>
          ))}
        </div>
      </div>

      {/* ─── Stat cards ─── */}
      <div className="grid gap-4 sm:grid-cols-2 lg:grid-cols-4">
        {/* Income */}
        <div className="group relative rounded-2xl border border-border/60 bg-card p-5 overflow-hidden transition-all hover:border-emerald-500/30 hover:shadow-lg hover:shadow-emerald-500/5">
          <div className="absolute top-0 right-0 w-24 h-24 rounded-full bg-emerald-500/5 blur-2xl -translate-y-6 translate-x-6 group-hover:bg-emerald-500/10 transition-colors" />
          <div className="relative">
            <div className="flex items-center justify-between">
              <p className="text-xs font-medium uppercase tracking-[0.16em] text-muted-foreground">Einnahmen</p>
              <div className="flex h-7 w-7 items-center justify-center rounded-lg bg-emerald-500/10"><TrendingUp className="h-3.5 w-3.5 text-emerald-500" /></div>
            </div>
            <p className="mt-3 text-2xl font-bold text-emerald-500">{formatMoney(summary.income)}</p>
            {previousSummary.income > 0 && (
              <div className="mt-2 flex items-center gap-1 text-xs">
                {incomeChange >= 0 ? <ArrowUpRight className="h-3 w-3 text-emerald-500" /> : <ArrowDownRight className="h-3 w-3 text-rose-500" />}
                <span className={incomeChange >= 0 ? "text-emerald-500" : "text-rose-500"}>{Math.abs(incomeChange).toFixed(1)}%</span>
                <span className="text-muted-foreground">vs. Vormonat</span>
              </div>
            )}
          </div>
        </div>

        {/* Expenses */}
        <div className="group relative rounded-2xl border border-border/60 bg-card p-5 overflow-hidden transition-all hover:border-rose-500/30 hover:shadow-lg hover:shadow-rose-500/5">
          <div className="absolute top-0 right-0 w-24 h-24 rounded-full bg-rose-500/5 blur-2xl -translate-y-6 translate-x-6 group-hover:bg-rose-500/10 transition-colors" />
          <div className="relative">
            <div className="flex items-center justify-between">
              <p className="text-xs font-medium uppercase tracking-[0.16em] text-muted-foreground">Ausgaben</p>
              <div className="flex h-7 w-7 items-center justify-center rounded-lg bg-rose-500/10"><TrendingDown className="h-3.5 w-3.5 text-rose-500" /></div>
            </div>
            <p className="mt-3 text-2xl font-bold text-rose-500">{formatMoney(summary.expenses)}</p>
            {previousSummary.expenses > 0 && (
              <div className="mt-2 flex items-center gap-1 text-xs">
                {expenseChange <= 0 ? <ArrowDownRight className="h-3 w-3 text-emerald-500" /> : <ArrowUpRight className="h-3 w-3 text-rose-500" />}
                <span className={expenseChange <= 0 ? "text-emerald-500" : "text-rose-500"}>{Math.abs(expenseChange).toFixed(1)}%</span>
                <span className="text-muted-foreground">vs. Vormonat</span>
              </div>
            )}
          </div>
        </div>

        {/* Net */}
        <div className="group relative rounded-2xl border border-border/60 bg-card p-5 overflow-hidden transition-all hover:border-indigo-500/30 hover:shadow-lg hover:shadow-indigo-500/5">
          <div className="absolute top-0 right-0 w-24 h-24 rounded-full bg-indigo-500/5 blur-2xl -translate-y-6 translate-x-6 group-hover:bg-indigo-500/10 transition-colors" />
          <div className="relative">
            <div className="flex items-center justify-between">
              <p className="text-xs font-medium uppercase tracking-[0.16em] text-muted-foreground">Netto</p>
              <div className={cn("flex h-7 w-7 items-center justify-center rounded-lg", summary.net >= 0 ? "bg-emerald-500/10" : "bg-rose-500/10")}>
                <Wallet className={cn("h-3.5 w-3.5", summary.net >= 0 ? "text-emerald-500" : "text-rose-500")} />
              </div>
            </div>
            <p className={cn("mt-3 text-2xl font-bold", summary.net >= 0 ? "text-emerald-500" : "text-rose-500")}>{formatMoney(summary.net)}</p>
            <p className="mt-2 text-xs text-muted-foreground">Einnahmen - Ausgaben</p>
          </div>
        </div>

        {/* Abos */}
        <div className="group relative rounded-2xl border border-border/60 bg-card p-5 overflow-hidden transition-all hover:border-violet-500/30 hover:shadow-lg hover:shadow-violet-500/5 cursor-pointer" onClick={() => setActiveTab("subscriptions")}>
          <div className="absolute top-0 right-0 w-24 h-24 rounded-full bg-violet-500/5 blur-2xl -translate-y-6 translate-x-6 group-hover:bg-violet-500/10 transition-colors" />
          <div className="relative">
            <div className="flex items-center justify-between">
              <p className="text-xs font-medium uppercase tracking-[0.16em] text-muted-foreground">Fixkosten</p>
              <div className="flex h-7 w-7 items-center justify-center rounded-lg bg-violet-500/10"><Repeat className="h-3.5 w-3.5 text-violet-500" /></div>
            </div>
            <p className="mt-3 text-2xl font-bold text-violet-500">{formatMoney(monthlyFixedExpenses)}</p>
            <p className="mt-2 text-xs text-muted-foreground">{activeSubscriptions.length} aktive Abos/Monat</p>
          </div>
        </div>
      </div>

      {/* ─── Quick add section ─── */}
      <div className="rounded-2xl border border-border/60 bg-card p-5">
        <div className="flex items-center gap-2.5 mb-4">
          <div className="flex h-8 w-8 items-center justify-center rounded-lg bg-gradient-to-br from-amber-500 to-orange-600">
            <Zap className="h-4 w-4 text-white" />
          </div>
          <div>
            <h2 className="text-sm font-semibold">Schnell hinzufügen</h2>
            <p className="text-xs text-muted-foreground">Klicke auf ein Preset oder erstelle manuell</p>
          </div>
        </div>

        {/* Income presets */}
        <p className="text-[10px] font-semibold uppercase tracking-widest text-emerald-500 mb-2">Einnahmen</p>
        <div className="flex flex-wrap gap-2 mb-4">
          {QUICK_INCOME_PRESETS.map((p) => (
            <button
              key={p.label}
              onClick={() => openAddForm("income", p)}
              className="group/btn flex items-center gap-2 rounded-xl border border-border/40 bg-background/60 px-3 py-2 text-xs font-medium transition-all hover:border-emerald-500/40 hover:bg-emerald-500/5 hover:shadow-sm"
            >
              <span className="flex h-6 w-6 items-center justify-center rounded-lg transition-colors" style={{ backgroundColor: `${p.color}15` }}>
                <p.icon className="h-3 w-3" />
              </span>
              {p.label}
              {p.recurring && <Repeat className="h-2.5 w-2.5 text-muted-foreground" />}
            </button>
          ))}
        </div>

        {/* Expense presets */}
        <p className="text-[10px] font-semibold uppercase tracking-widest text-rose-500 mb-2">Ausgaben</p>
        <div className="flex flex-wrap gap-2">
          {QUICK_EXPENSE_PRESETS.map((p) => (
            <button
              key={p.label}
              onClick={() => openAddForm("expense", p)}
              className="group/btn flex items-center gap-2 rounded-xl border border-border/40 bg-background/60 px-3 py-2 text-xs font-medium transition-all hover:border-rose-500/40 hover:bg-rose-500/5 hover:shadow-sm"
            >
              <span className="flex h-6 w-6 items-center justify-center rounded-lg transition-colors" style={{ backgroundColor: `${p.color}15` }}>
                <p.icon className="h-3 w-3" />
              </span>
              {p.label}
              {p.recurring && <Repeat className="h-2.5 w-2.5 text-muted-foreground" />}
            </button>
          ))}
        </div>
      </div>

      {/* ─── Tab navigation ─── */}
      <div className="flex items-center gap-1 rounded-xl border border-border/60 bg-card p-1 w-fit">
        {TABS.map((tab) => (
          <button
            key={tab.key}
            onClick={() => setActiveTab(tab.key)}
            className={cn(
              "flex items-center gap-2 rounded-lg px-4 py-2 text-sm font-medium transition-all",
              activeTab === tab.key
                ? "bg-foreground text-background shadow-sm"
                : "text-muted-foreground hover:text-foreground hover:bg-accent/50"
            )}
          >
            {tab.label}
            {tab.count !== undefined && tab.count > 0 && (
              <span className={cn(
                "flex h-5 min-w-[20px] items-center justify-center rounded-full px-1.5 text-[10px] font-bold",
                activeTab === tab.key ? "bg-background/20 text-background" : "bg-muted text-muted-foreground"
              )}>
                {tab.count}
              </span>
            )}
          </button>
        ))}
      </div>

      {/* ═══════════════════════════════ OVERVIEW TAB ═══════════════════════════════ */}
      {activeTab === "overview" && (
        <div className="space-y-6">
          <PnLChart transactions={transactions} />
          <PnLExport transactions={transactions} />

          <div className="grid gap-6 xl:grid-cols-2">
            {/* AI Coach */}
            <div className="rounded-2xl border border-border/60 bg-card p-5">
              <div className="flex items-center gap-2.5 mb-4">
                <div className="flex h-8 w-8 items-center justify-center rounded-lg bg-gradient-to-br from-violet-500 to-purple-600">
                  <Brain className="h-4 w-4 text-white" />
                </div>
                <div>
                  <h2 className="text-sm font-semibold">Finanz-Coach</h2>
                  <p className="text-xs text-muted-foreground">Automatische Insights</p>
                </div>
              </div>
              <div className="space-y-2">
                {financeInsights.map((insight, i) => (
                  <div key={i} className="flex items-start gap-3 rounded-xl border border-border/40 bg-background/60 px-4 py-3 text-sm">
                    <span className="flex h-5 w-5 shrink-0 items-center justify-center rounded-full bg-violet-500/10 text-[10px] font-bold text-violet-500 mt-0.5">{i + 1}</span>
                    <span>{insight}</span>
                  </div>
                ))}
              </div>
            </div>

            {/* Category Breakdown */}
            <div className="rounded-2xl border border-border/60 bg-card p-5">
              <div className="flex items-center gap-2.5 mb-4">
                <div className="flex h-8 w-8 items-center justify-center rounded-lg bg-gradient-to-br from-blue-500 to-cyan-600">
                  <PieChart className="h-4 w-4 text-white" />
                </div>
                <div>
                  <h2 className="text-sm font-semibold">Kategorien</h2>
                  <p className="text-xs text-muted-foreground">Ausgaben nach Kategorie</p>
                </div>
              </div>
              <div className="grid gap-3 sm:grid-cols-3 mb-5">
                <div className="rounded-xl bg-background/60 border border-border/40 p-3">
                  <p className="text-[10px] font-medium uppercase tracking-wider text-muted-foreground">Differenz</p>
                  <p className={cn("mt-1 text-sm font-bold", summary.expenses - previousSummary.expenses <= 0 ? "text-emerald-500" : "text-rose-500")}>
                    {formatMoney(summary.expenses - previousSummary.expenses)}
                  </p>
                </div>
                <div className="rounded-xl bg-background/60 border border-border/40 p-3">
                  <p className="text-[10px] font-medium uppercase tracking-wider text-muted-foreground">Fixkosten</p>
                  <p className="mt-1 text-sm font-bold">{formatMoney(monthlyFixedExpenses)}</p>
                </div>
                <div className="rounded-xl bg-background/60 border border-border/40 p-3">
                  <p className="text-[10px] font-medium uppercase tracking-wider text-muted-foreground">Nach Fix</p>
                  <p className="mt-1 text-sm font-bold">{formatMoney(summary.income - monthlyFixedExpenses)}</p>
                </div>
              </div>
              <div className="space-y-3">
                {categoryBreakdown.length === 0 ? (
                  <p className="text-sm text-muted-foreground py-4 text-center">Noch keine Ausgaben.</p>
                ) : (
                  categoryBreakdown.slice(0, 6).map((item, i) => {
                    const pct = summary.expenses > 0 ? Math.round((item.amount / summary.expenses) * 100) : 0;
                    const color = CATEGORY_COLORS[i % CATEGORY_COLORS.length];
                    return (
                      <div key={item.category}>
                        <div className="mb-1.5 flex items-center justify-between text-sm">
                          <div className="flex items-center gap-2">
                            <span className="h-2.5 w-2.5 rounded-full" style={{ backgroundColor: color }} />
                            <span className="font-medium">{item.category}</span>
                          </div>
                          <span className="text-muted-foreground">{formatMoney(item.amount)} <span className="text-xs">({pct}%)</span></span>
                        </div>
                        <div className="h-2 rounded-full bg-muted overflow-hidden">
                          <div className="h-2 rounded-full transition-all duration-500" style={{ width: `${pct}%`, backgroundColor: color }} />
                        </div>
                      </div>
                    );
                  })
                )}
              </div>
            </div>
          </div>
        </div>
      )}

      {/* ═══════════════════════════════ TRANSACTIONS TAB ═══════════════════════════════ */}
      {activeTab === "transactions" && (
        <div className="rounded-2xl border border-border/60 bg-card p-5">
          <div className="flex flex-wrap items-center justify-between gap-3 mb-5">
            <div>
              <h2 className="text-sm font-semibold">Transaktionen</h2>
              <p className="text-xs text-muted-foreground">Einnahmen und Ausgaben für {formatMonthLabel(selectedMonth)}</p>
            </div>
            <div className="flex gap-2">
              <Button size="sm" variant="outline" onClick={() => openAddForm("income")} className="gap-1.5"><TrendingUp className="h-3.5 w-3.5" />Einnahme</Button>
              <Button size="sm" onClick={() => openAddForm("expense")} className="gap-1.5"><TrendingDown className="h-3.5 w-3.5" />Ausgabe</Button>
            </div>
          </div>

          {monthTransactions.length === 0 ? (
            <EmptyState icon={<Wallet className="h-10 w-10" />} title="Keine Transaktionen" description="Füge deine erste Einnahme oder Ausgabe hinzu."
              action={<Button size="sm" onClick={() => openAddForm("expense")}><Plus className="h-4 w-4" />Transaktion hinzufügen</Button>} />
          ) : (
            <div className="space-y-2">
              {monthTransactions.map((t) => (
                <div key={t.id} className="group flex flex-wrap items-center gap-4 rounded-xl border border-border/40 bg-background/60 p-4 transition-all hover:border-border hover:shadow-sm">
                  <div className={cn("flex h-10 w-10 items-center justify-center rounded-xl transition-colors", t.type === "income" ? "bg-emerald-500/10 text-emerald-500 group-hover:bg-emerald-500/15" : "bg-rose-500/10 text-rose-500 group-hover:bg-rose-500/15")}>
                    {t.type === "income" ? <TrendingUp className="h-4 w-4" /> : <TrendingDown className="h-4 w-4" />}
                  </div>
                  <div className="min-w-0 flex-1">
                    <div className="flex flex-wrap items-center gap-2">
                      <p className="truncate text-sm font-semibold">{t.title}</p>
                      <Badge variant="outline" className="text-[10px]">{t.category}</Badge>
                      <BusinessToggle business={t.business} onToggle={() => void updateTransaction(t.id, { business: !t.business })} />
                      {t.status === "pending" && <Badge variant="secondary" className="text-[10px]">Ausstehend</Badge>}
                    </div>
                    <p className="text-xs text-muted-foreground mt-0.5">{formatDate(t.transaction_date)}{t.description ? ` — ${t.description}` : ""}</p>
                  </div>
                  <p className={cn("text-sm font-bold tabular-nums", t.type === "income" ? "text-emerald-500" : "text-rose-500")}>
                    {t.type === "income" ? "+" : "-"}{formatMoney(t.amount_cents, t.currency)}
                  </p>
                  <button type="button" onClick={() => void deleteTransaction(t.id)} className="rounded-lg p-1.5 text-muted-foreground opacity-0 group-hover:opacity-100 hover:bg-accent hover:text-destructive transition-all">
                    <Trash2 className="h-3.5 w-3.5" />
                  </button>
                </div>
              ))}
            </div>
          )}
        </div>
      )}

      {/* ═══════════════════════════════ SUBSCRIPTIONS TAB ═══════════════════════════════ */}
      {activeTab === "subscriptions" && (
        <div className="space-y-6">
          {/* Summary cards */}
          <div className="grid gap-4 sm:grid-cols-2 lg:grid-cols-4">
            <div className="rounded-2xl border border-border/60 bg-card p-5">
              <p className="text-xs font-medium uppercase tracking-[0.16em] text-muted-foreground">Monatliche Abos</p>
              <p className="mt-2 text-2xl font-bold text-rose-500">{formatMoney(totalSubscriptionMonthly)}</p>
              <p className="mt-1 text-xs text-muted-foreground">{activeSubscriptions.length} aktive Ausgaben</p>
            </div>
            <div className="rounded-2xl border border-border/60 bg-card p-5">
              <p className="text-xs font-medium uppercase tracking-[0.16em] text-muted-foreground">Wiederkehrende Einnahmen</p>
              <p className="mt-2 text-2xl font-bold text-emerald-500">{formatMoney(monthlyFixedIncome)}</p>
              <p className="mt-1 text-xs text-muted-foreground">{activeIncomeRecurring.length} aktive Einnahmen</p>
            </div>
            <div className="rounded-2xl border border-border/60 bg-card p-5">
              <p className="text-xs font-medium uppercase tracking-[0.16em] text-muted-foreground">Netto Fix/Monat</p>
              <p className={cn("mt-2 text-2xl font-bold", monthlyFixedIncome - totalSubscriptionMonthly >= 0 ? "text-emerald-500" : "text-rose-500")}>
                {formatMoney(monthlyFixedIncome - totalSubscriptionMonthly)}
              </p>
              <p className="mt-1 text-xs text-muted-foreground">Einnahmen - Fixkosten</p>
            </div>
            <div className="rounded-2xl border border-border/60 bg-card p-5">
              <p className="text-xs font-medium uppercase tracking-[0.16em] text-muted-foreground">Jährliche Kosten</p>
              <p className="mt-2 text-2xl font-bold text-rose-500">{formatMoney(totalSubscriptionYearly)}</p>
              <p className="mt-1 text-xs text-muted-foreground">Alle aktiven Abos / Jahr</p>
            </div>
          </div>

          {/* Upcoming Renewals */}
          {upcomingRenewals.length > 0 && (
            <div className="rounded-2xl border border-orange-500/20 bg-orange-500/5 p-5">
              <div className="flex items-center gap-2.5 mb-4">
                <div className="flex h-8 w-8 items-center justify-center rounded-lg bg-gradient-to-br from-orange-500 to-amber-500">
                  <CalendarDays className="h-4 w-4 text-white" />
                </div>
                <div>
                  <h2 className="text-sm font-semibold text-orange-500">Fällig in 30 Tagen</h2>
                  <p className="text-xs text-muted-foreground">{upcomingRenewals.length} Zahlung{upcomingRenewals.length !== 1 ? "en" : ""} stehen an</p>
                </div>
              </div>
              <div className="space-y-2">
                {upcomingRenewals.map((item) => {
                  const Icon = getSubIcon(item.title, item.category);
                  const daysUntil = Math.ceil((new Date(item.next_due_date).getTime() - new Date().getTime()) / (1000 * 60 * 60 * 24));
                  const urgencyClass = daysUntil <= 7 ? "text-rose-500" : daysUntil <= 14 ? "text-amber-500" : "text-orange-400";
                  return (
                    <div key={item.id} className="flex items-center gap-3 rounded-xl border border-orange-500/10 bg-background/60 px-4 py-3">
                      <div className="flex h-9 w-9 items-center justify-center rounded-lg bg-orange-500/10 text-orange-400">
                        <Icon className="h-4 w-4" />
                      </div>
                      <div className="min-w-0 flex-1">
                        <p className="text-sm font-semibold">{item.title}</p>
                        <p className={cn("text-xs font-medium", urgencyClass)}>
                          {daysUntil === 0 ? "Heute fällig" : daysUntil === 1 ? "Morgen fällig" : `In ${daysUntil} Tagen · ${formatDate(item.next_due_date)}`}
                        </p>
                      </div>
                      <p className="text-sm font-bold tabular-nums text-rose-500">{formatMoney(item.amount_cents, item.currency)}</p>
                    </div>
                  );
                })}
              </div>
            </div>
          )}

          {/* Active expense subscriptions */}
          <div className="rounded-2xl border border-border/60 bg-card p-5">
            <div className="flex flex-wrap items-center justify-between gap-3 mb-5">
              <div className="flex items-center gap-2.5">
                <div className="flex h-8 w-8 items-center justify-center rounded-lg bg-gradient-to-br from-rose-500 to-pink-600">
                  <CreditCard className="h-4 w-4 text-white" />
                </div>
                <div>
                  <h2 className="text-sm font-semibold">Aktive Abos & Fixkosten</h2>
                  <p className="text-xs text-muted-foreground">{activeSubscriptions.length} laufende Ausgaben</p>
                </div>
              </div>
              <Button size="sm" onClick={() => { setForm(defaultUnifiedForm("expense")); setForm((f) => ({ ...f, mode: "recurring" })); setAddFormOpen(true); }} className="gap-1.5">
                <Plus className="h-3.5 w-3.5" />
                Abo hinzufügen
              </Button>
            </div>

            {activeSubscriptions.length === 0 ? (
              <EmptyState icon={<Repeat className="h-10 w-10" />} title="Keine aktiven Abos" description="Füge deine Abos und Fixkosten hinzu — Netflix, Miete, Versicherung, etc." />
            ) : (
              <div className="space-y-2">
                {activeSubscriptions.map((item) => {
                  const Icon = getSubIcon(item.title, item.category);
                  const monthly = monthlyEquivalent(item);
                  const yearly = yearlyEquivalent(item);
                  return (
                    <div key={item.id} className="group flex items-center gap-4 rounded-xl border border-border/40 bg-background/60 p-4 transition-all hover:border-border hover:shadow-sm">
                      <div className="flex h-10 w-10 items-center justify-center rounded-xl bg-rose-500/10 text-rose-500 group-hover:bg-rose-500/15 transition-colors">
                        <Icon className="h-4 w-4" />
                      </div>
                      <div className="min-w-0 flex-1">
                        <div className="flex flex-wrap items-center gap-2">
                          <p className="text-sm font-semibold">{item.title}</p>
                          <Badge variant="outline" className="text-[10px]">{item.category}</Badge>
                          <Badge variant="secondary" className="text-[10px]">{FREQUENCY_LABELS[item.frequency]}</Badge>
                          <BusinessToggle business={item.business} onToggle={() => void updateRecurringItem(item.id, { business: !item.business })} />
                        </div>
                        <p className="text-xs text-muted-foreground mt-0.5 flex items-center gap-1.5">
                          <CalendarDays className="h-3 w-3" />
                          Nächste Zahlung: {formatDate(item.next_due_date)}
                        </p>
                      </div>
                      <div className="text-right">
                        <p className="text-sm font-bold tabular-nums text-rose-500">{formatMoney(item.amount_cents, item.currency)}</p>
                        {item.frequency !== "monthly" && (
                          <p className="text-[10px] text-muted-foreground">{formatMoney(monthly)}/Monat</p>
                        )}
                        {item.frequency !== "yearly" && (
                          <p className="text-[10px] text-muted-foreground">{formatMoney(yearly)} / Jahr</p>
                        )}
                      </div>
                      <div className="flex items-center gap-1 opacity-0 group-hover:opacity-100 transition-all">
                        <button type="button" onClick={() => void addRecurringAsTransaction(item)} title="Als Transaktion buchen" className="rounded-lg p-1.5 text-muted-foreground hover:bg-accent hover:text-foreground transition-colors">
                          <Plus className="h-3.5 w-3.5" />
                        </button>
                        <button type="button" onClick={() => void updateRecurringItem(item.id, { is_active: false })} title="Pausieren" className="rounded-lg p-1.5 text-muted-foreground hover:bg-amber-500/10 hover:text-amber-500 transition-colors">
                          <Pause className="h-3.5 w-3.5" />
                        </button>
                        <button type="button" onClick={() => void deleteRecurringItem(item.id)} title="Löschen" className="rounded-lg p-1.5 text-muted-foreground hover:bg-accent hover:text-destructive transition-colors">
                          <Trash2 className="h-3.5 w-3.5" />
                        </button>
                      </div>
                    </div>
                  );
                })}
                {/* Total row */}
                <div className="flex items-center justify-between rounded-xl border border-rose-500/20 bg-rose-500/5 px-5 py-3">
                  <p className="text-sm font-semibold">Gesamt monatlich</p>
                  <p className="text-sm font-bold text-rose-500 tabular-nums">{formatMoney(totalSubscriptionMonthly)}</p>
                </div>
              </div>
            )}
          </div>

          {/* Active income recurring */}
          {activeIncomeRecurring.length > 0 && (
            <div className="rounded-2xl border border-border/60 bg-card p-5">
              <div className="flex items-center gap-2.5 mb-5">
                <div className="flex h-8 w-8 items-center justify-center rounded-lg bg-gradient-to-br from-emerald-500 to-teal-600">
                  <Euro className="h-4 w-4 text-white" />
                </div>
                <div>
                  <h2 className="text-sm font-semibold">Wiederkehrende Einnahmen</h2>
                  <p className="text-xs text-muted-foreground">{activeIncomeRecurring.length} aktive Einnahmequellen</p>
                </div>
              </div>
              <div className="space-y-2">
                {activeIncomeRecurring.map((item) => {
                  const Icon = getSubIcon(item.title, item.category);
                  const monthly = monthlyEquivalent(item);
                  return (
                    <div key={item.id} className="group flex items-center gap-4 rounded-xl border border-border/40 bg-background/60 p-4 transition-all hover:border-border hover:shadow-sm">
                      <div className="flex h-10 w-10 items-center justify-center rounded-xl bg-emerald-500/10 text-emerald-500 group-hover:bg-emerald-500/15 transition-colors">
                        <Icon className="h-4 w-4" />
                      </div>
                      <div className="min-w-0 flex-1">
                        <div className="flex flex-wrap items-center gap-2">
                          <p className="text-sm font-semibold">{item.title}</p>
                          <Badge variant="outline" className="text-[10px]">{item.category}</Badge>
                          <Badge variant="secondary" className="text-[10px]">{FREQUENCY_LABELS[item.frequency]}</Badge>
                          <BusinessToggle business={item.business} onToggle={() => void updateRecurringItem(item.id, { business: !item.business })} />
                        </div>
                        <p className="text-xs text-muted-foreground mt-0.5 flex items-center gap-1.5">
                          <CalendarDays className="h-3 w-3" />
                          Nächste: {formatDate(item.next_due_date)}
                        </p>
                      </div>
                      <div className="text-right">
                        <p className="text-sm font-bold tabular-nums text-emerald-500">+{formatMoney(item.amount_cents, item.currency)}</p>
                        {item.frequency !== "monthly" && (
                          <p className="text-[10px] text-muted-foreground">{formatMoney(monthly)}/Monat</p>
                        )}
                      </div>
                      <div className="flex items-center gap-1 opacity-0 group-hover:opacity-100 transition-all">
                        <button type="button" onClick={() => void updateRecurringItem(item.id, { is_active: false })} title="Pausieren" className="rounded-lg p-1.5 text-muted-foreground hover:bg-amber-500/10 hover:text-amber-500 transition-colors">
                          <Pause className="h-3.5 w-3.5" />
                        </button>
                        <button type="button" onClick={() => void deleteRecurringItem(item.id)} title="Löschen" className="rounded-lg p-1.5 text-muted-foreground hover:bg-accent hover:text-destructive transition-colors">
                          <Trash2 className="h-3.5 w-3.5" />
                        </button>
                      </div>
                    </div>
                  );
                })}
                <div className="flex items-center justify-between rounded-xl border border-emerald-500/20 bg-emerald-500/5 px-5 py-3">
                  <p className="text-sm font-semibold">Gesamt monatlich</p>
                  <p className="text-sm font-bold text-emerald-500 tabular-nums">+{formatMoney(monthlyFixedIncome)}</p>
                </div>
              </div>
            </div>
          )}

          {/* Paused subscriptions */}
          {pausedSubscriptions.length > 0 && (
            <div className="rounded-2xl border border-border/60 bg-card p-5">
              <div className="flex items-center gap-2.5 mb-4">
                <div className="flex h-8 w-8 items-center justify-center rounded-lg bg-muted">
                  <Pause className="h-4 w-4 text-muted-foreground" />
                </div>
                <div>
                  <h2 className="text-sm font-semibold">Pausierte Abos</h2>
                  <p className="text-xs text-muted-foreground">{pausedSubscriptions.length} pausiert</p>
                </div>
              </div>
              <div className="space-y-2">
                {pausedSubscriptions.map((item) => {
                  const Icon = getSubIcon(item.title, item.category);
                  return (
                    <div key={item.id} className="group flex items-center gap-4 rounded-xl border border-border/40 bg-background/60 p-4 opacity-60 transition-all hover:opacity-100 hover:border-border">
                      <div className="flex h-10 w-10 items-center justify-center rounded-xl bg-muted"><Icon className="h-4 w-4 text-muted-foreground" /></div>
                      <div className="min-w-0 flex-1">
                        <p className="text-sm font-semibold">{item.title}</p>
                        <p className="text-xs text-muted-foreground">{formatMoney(item.amount_cents, item.currency)} · {FREQUENCY_LABELS[item.frequency]}</p>
                      </div>
                      <div className="flex items-center gap-1 opacity-0 group-hover:opacity-100 transition-all">
                        <button type="button" onClick={() => void updateRecurringItem(item.id, { is_active: true })} title="Aktivieren" className="rounded-lg p-1.5 text-muted-foreground hover:bg-emerald-500/10 hover:text-emerald-500 transition-colors">
                          <Play className="h-3.5 w-3.5" />
                        </button>
                        <button type="button" onClick={() => void deleteRecurringItem(item.id)} title="Löschen" className="rounded-lg p-1.5 text-muted-foreground hover:bg-accent hover:text-destructive transition-colors">
                          <Trash2 className="h-3.5 w-3.5" />
                        </button>
                      </div>
                    </div>
                  );
                })}
              </div>
            </div>
          )}
        </div>
      )}

      {/* ═══════════════════════════════ BUDGETS TAB ═══════════════════════════════ */}
      {activeTab === "budgets" && (
        <div className="rounded-2xl border border-border/60 bg-card p-5">
          <div className="flex flex-wrap items-center justify-between gap-3 mb-5">
            <div>
              <h2 className="text-sm font-semibold">Budgets</h2>
              <p className="text-xs text-muted-foreground">Kategorie-Limits für {formatMonthLabel(selectedMonth)}</p>
            </div>
            <Button size="sm" variant="outline" onClick={() => setBudgetFormOpen(true)} className="gap-1.5"><Plus className="h-3.5 w-3.5" />Budget hinzufügen</Button>
          </div>

          {monthBudgets.length === 0 ? (
            <EmptyState icon={<Wallet className="h-10 w-10" />} title="Keine Budgets" description="Erstelle ein Monatsbudget pro Kategorie."
              action={<Button size="sm" onClick={() => setBudgetFormOpen(true)}><Plus className="h-4 w-4" />Budget hinzufügen</Button>} />
          ) : (
            <div className="grid gap-4 sm:grid-cols-2">
              {monthBudgets.map((budget) => {
                const used = expenseByCategory.get(budget.category) || 0;
                const pct = budget.amount_cents > 0 ? Math.min(100, Math.round((used / budget.amount_cents) * 100)) : 0;
                const over = used > budget.amount_cents;
                const color = over ? "#f43f5e" : "#10b981";
                return (
                  <div key={budget.id} className="group rounded-xl border border-border/40 bg-background/60 p-5 transition-all hover:border-border hover:shadow-sm">
                    <div className="flex items-start justify-between gap-3">
                      <div>
                        <p className="font-semibold text-sm">{budget.category}</p>
                        <p className="text-xs text-muted-foreground mt-1">{formatMoney(used, budget.currency)} von {formatMoney(budget.amount_cents, budget.currency)}</p>
                      </div>
                      <div className="flex items-center gap-2">
                        <span className={cn("text-xs font-bold tabular-nums", over ? "text-rose-500" : "text-emerald-500")}>{pct}%</span>
                        <button type="button" onClick={() => void deleteBudget(budget.id)} className="rounded-lg p-1 text-muted-foreground opacity-0 group-hover:opacity-100 hover:bg-accent hover:text-destructive transition-all"><Trash2 className="h-3.5 w-3.5" /></button>
                      </div>
                    </div>
                    <div className="mt-4 h-2.5 rounded-full bg-muted overflow-hidden">
                      <div className="h-2.5 rounded-full transition-all duration-500" style={{ width: `${pct}%`, backgroundColor: color }} />
                    </div>
                    <p className={cn("mt-2 text-xs", over ? "text-rose-500" : "text-muted-foreground")}>
                      {over ? `${formatMoney(used - budget.amount_cents, budget.currency)} über Budget` : `${formatMoney(budget.amount_cents - used, budget.currency)} übrig`}
                    </p>
                  </div>
                );
              })}
            </div>
          )}
        </div>
      )}

      {/* ═══════════════════════════════ UNIFIED ADD MODAL ═══════════════════════════════ */}
      {addFormOpen && (
        <Modal open={addFormOpen} onClose={() => setAddFormOpen(false)} title={form.type === "income" ? "Einnahme hinzufügen" : "Ausgabe hinzufügen"} className="max-w-xl">
          <div className="space-y-4">
            {error && <p className="rounded-lg bg-destructive/10 px-3 py-2 text-sm text-destructive">{error}</p>}

            {/* Mode toggle: einmalig / wiederkehrend */}
            <div className="flex items-center gap-1 rounded-xl border border-border/60 bg-background/60 p-1">
              <button
                onClick={() => setForm((f) => ({ ...f, mode: "single" }))}
                className={cn("flex-1 rounded-lg px-3 py-2 text-sm font-medium transition-all text-center", form.mode === "single" ? "bg-foreground text-background shadow-sm" : "text-muted-foreground hover:text-foreground")}
              >
                Einmalig
              </button>
              <button
                onClick={() => setForm((f) => ({ ...f, mode: "recurring" }))}
                className={cn("flex-1 flex items-center justify-center gap-1.5 rounded-lg px-3 py-2 text-sm font-medium transition-all", form.mode === "recurring" ? "bg-foreground text-background shadow-sm" : "text-muted-foreground hover:text-foreground")}
              >
                <Repeat className="h-3.5 w-3.5" />
                Wiederkehrend
              </button>
            </div>

            {/* Type + Amount */}
            <div className="grid gap-3 sm:grid-cols-2">
              <label className="space-y-1 text-sm">
                <span className="text-muted-foreground">Typ</span>
                <select value={form.type} onChange={(e) => setForm((f) => ({ ...f, type: e.target.value as FinanceTransactionType }))} className="h-10 w-full rounded-md border border-input bg-background px-3 text-sm">
                  <option value="expense">Ausgabe</option>
                  <option value="income">Einnahme</option>
                </select>
              </label>
              <label className="space-y-1 text-sm">
                <span className="text-muted-foreground">Betrag</span>
                <Input inputMode="decimal" placeholder="49,99" value={form.amount} onChange={(e) => setForm((f) => ({ ...f, amount: e.target.value }))} />
              </label>
            </div>

            {/* Title */}
            <label className="space-y-1 text-sm">
              <span className="text-muted-foreground">Titel</span>
              <Input placeholder={form.mode === "recurring" ? "Netflix, Miete, Gehalt..." : "McDonald's, Fußballschuhe, Einkauf..."} value={form.title} onChange={(e) => setForm((f) => ({ ...f, title: e.target.value }))} autoFocus />
            </label>

            {/* Category + Date/Frequency */}
            <div className={cn("grid gap-3", form.mode === "recurring" ? "sm:grid-cols-3" : "sm:grid-cols-2")}>
              <label className="space-y-1 text-sm">
                <span className="text-muted-foreground">Kategorie</span>
                {form.category === "__create__" ? (
                  <div className="flex gap-1.5">
                    <Input
                      autoFocus
                      placeholder="Neue Kategorie..."
                      value={addFormNewCategory}
                      onChange={(e) => setAddFormNewCategory(e.target.value)}
                      onKeyDown={(e) => {
                        if (e.key === "Enter" && addFormNewCategory.trim()) {
                          setForm((f) => ({ ...f, category: addFormNewCategory.trim() }));
                          setAddFormNewCategory("");
                        }
                        if (e.key === "Escape") {
                          setForm((f) => ({ ...f, category: "Sonstiges" }));
                          setAddFormNewCategory("");
                        }
                      }}
                    />
                    <button
                      type="button"
                      onClick={() => {
                        if (addFormNewCategory.trim()) {
                          setForm((f) => ({ ...f, category: addFormNewCategory.trim() }));
                          setAddFormNewCategory("");
                        } else {
                          setForm((f) => ({ ...f, category: "Sonstiges" }));
                        }
                      }}
                      className="shrink-0 h-10 px-3 rounded-md border border-input bg-background text-sm hover:bg-accent transition-colors"
                    >
                      OK
                    </button>
                  </div>
                ) : (
                  <select
                    value={form.category}
                    onChange={(e) => setForm((f) => ({ ...f, category: e.target.value }))}
                    className="h-10 w-full rounded-md border border-input bg-background px-3 text-sm"
                  >
                    <option value="__create__">+ Erstellen</option>
                    {form.category !== "__create__" && !categoryOptions.includes(form.category) && (
                      <option value={form.category}>{form.category}</option>
                    )}
                    {categoryOptions.map((c) => (
                      <option key={c} value={c}>{c}</option>
                    ))}
                  </select>
                )}
              </label>
              {form.mode === "single" ? (
                <label className="space-y-1 text-sm">
                  <span className="text-muted-foreground">Datum</span>
                  <Input type="date" value={form.transactionDate} onChange={(e) => setForm((f) => ({ ...f, transactionDate: e.target.value }))} />
                </label>
              ) : (
                <>
                  <label className="space-y-1 text-sm">
                    <span className="text-muted-foreground">Frequenz</span>
                    <select value={form.frequency} onChange={(e) => setForm((f) => ({ ...f, frequency: e.target.value as FinanceRecurringFrequency }))} className="h-10 w-full rounded-md border border-input bg-background px-3 text-sm">
                      <option value="weekly">Wöchentlich</option>
                      <option value="monthly">Monatlich</option>
                      <option value="yearly">Jährlich</option>
                    </select>
                  </label>
                  <label className="space-y-1 text-sm">
                    <span className="text-muted-foreground">Nächste Fälligkeit</span>
                    <Input type="date" value={form.nextDueDate} onChange={(e) => setForm((f) => ({ ...f, nextDueDate: e.target.value }))} />
                  </label>
                </>
              )}
            </div>

            {/* Privat / Geschäftlich */}
            <label className="flex items-center gap-3 rounded-xl border border-border/60 px-4 py-3 text-sm cursor-pointer">
              <input
                type="checkbox"
                checked={form.business}
                onChange={(e) => setForm((f) => ({ ...f, business: e.target.checked }))}
                className="h-4 w-4 accent-amber-500"
              />
              <span>
                <span className="font-medium">Geschäftlich</span>
                <span className="block text-xs text-muted-foreground">z. B. Aftermoon, MaroBuilds, Tools fürs Business – sonst privat</span>
              </span>
            </label>

            {/* Extra fields for single */}
            {form.mode === "single" && (
              <>
                <label className="space-y-1 text-sm">
                  <span className="text-muted-foreground">Status</span>
                  <select value={form.status} onChange={(e) => setForm((f) => ({ ...f, status: e.target.value as "cleared" | "pending" }))} className="h-10 w-full rounded-md border border-input bg-background px-3 text-sm">
                    <option value="cleared">Verbucht</option>
                    <option value="pending">Ausstehend</option>
                  </select>
                </label>
                <label className="space-y-1 text-sm">
                  <span className="text-muted-foreground">Notiz (optional)</span>
                  <Input placeholder="z.B. Wocheneinkauf bei Rewe" value={form.description} onChange={(e) => setForm((f) => ({ ...f, description: e.target.value }))} />
                </label>
              </>
            )}

            {/* Info hint */}
            <div className="rounded-xl bg-muted/50 px-4 py-3 text-xs text-muted-foreground">
              {form.mode === "recurring"
                ? "Wiederkehrende Einträge erscheinen in deinen Abos & Fixkosten und werden in die monatliche Kalkulation einbezogen."
                : "Einmalige Einträge werden direkt als Transaktion im ausgewählten Monat gebucht."}
            </div>

            <div className="flex justify-end gap-2">
              <Button variant="ghost" onClick={() => setAddFormOpen(false)}>Abbrechen</Button>
              <Button onClick={() => void handleSaveForm()} disabled={saving}>
                {saving ? "Speichert..." : form.mode === "recurring" ? "Abo speichern" : "Transaktion speichern"}
              </Button>
            </div>
          </div>
        </Modal>
      )}

      {/* Budget form */}
      {budgetFormOpen && (
        <Modal open={budgetFormOpen} onClose={() => setBudgetFormOpen(false)} title="Budget hinzufügen" className="max-w-md">
          <div className="space-y-4">
            {error && <p className="rounded-lg bg-destructive/10 px-3 py-2 text-sm text-destructive">{error}</p>}
            <label className="space-y-1 text-sm">
              <span className="text-muted-foreground">Kategorie</span>
              {budgetForm.category === "__create__" ? (
                <div className="flex gap-1.5">
                  <Input
                    autoFocus
                    placeholder="Neue Kategorie..."
                    value={budgetNewCategory}
                    onChange={(e) => setBudgetNewCategory(e.target.value)}
                    onKeyDown={(e) => {
                      if (e.key === "Enter" && budgetNewCategory.trim()) {
                        setBudgetForm((c) => ({ ...c, category: budgetNewCategory.trim() }));
                        setBudgetNewCategory("");
                      }
                      if (e.key === "Escape") {
                        setBudgetForm((c) => ({ ...c, category: "Sonstiges" }));
                        setBudgetNewCategory("");
                      }
                    }}
                  />
                  <button
                    type="button"
                    onClick={() => {
                      if (budgetNewCategory.trim()) {
                        setBudgetForm((c) => ({ ...c, category: budgetNewCategory.trim() }));
                        setBudgetNewCategory("");
                      } else {
                        setBudgetForm((c) => ({ ...c, category: "Sonstiges" }));
                      }
                    }}
                    className="shrink-0 h-10 px-3 rounded-md border border-input bg-background text-sm hover:bg-accent transition-colors"
                  >
                    OK
                  </button>
                </div>
              ) : (
                <select
                  value={budgetForm.category}
                  onChange={(e) => setBudgetForm((c) => ({ ...c, category: e.target.value }))}
                  className="h-10 w-full rounded-md border border-input bg-background px-3 text-sm"
                >
                  <option value="__create__">+ Erstellen</option>
                  {budgetForm.category !== "__create__" && !categoryOptions.includes(budgetForm.category) && (
                    <option value={budgetForm.category}>{budgetForm.category}</option>
                  )}
                  {categoryOptions.map((c) => (
                    <option key={c} value={c}>{c}</option>
                  ))}
                </select>
              )}
            </label>
            <label className="space-y-1 text-sm">
              <span className="text-muted-foreground">Monatliches Budget</span>
              <Input inputMode="decimal" placeholder="300" value={budgetForm.amount} onChange={(e) => setBudgetForm((c) => ({ ...c, amount: e.target.value }))} />
            </label>
            <div className="flex justify-end gap-2">
              <Button variant="ghost" onClick={() => setBudgetFormOpen(false)}>Abbrechen</Button>
              <Button onClick={() => void handleSaveBudget()} disabled={saving}>{saving ? "Speichert..." : "Speichern"}</Button>
            </div>
          </div>
        </Modal>
      )}

      {/* Category manager */}
      {categoryFormOpen && (
        <Modal open={categoryFormOpen} onClose={() => setCategoryFormOpen(false)} title="Kategorien verwalten" className="max-w-xl">
          <div className="space-y-4">
            {error && <p className="rounded-lg bg-destructive/10 px-3 py-2 text-sm text-destructive">{error}</p>}
            <div className="grid gap-3 sm:grid-cols-[1fr,140px]">
              <label className="space-y-1 text-sm">
                <span className="text-muted-foreground">Name</span>
                <Input value={categoryForm.name} onChange={(e) => setCategoryForm((c) => ({ ...c, name: e.target.value }))} placeholder="Versicherung, Tanken, Kunden..." autoFocus />
              </label>
              <label className="space-y-1 text-sm">
                <span className="text-muted-foreground">Typ</span>
                <select value={categoryForm.type} onChange={(e) => setCategoryForm((c) => ({ ...c, type: e.target.value as FinanceCategoryType }))} className="h-10 w-full rounded-md border border-input bg-background px-3 text-sm">
                  <option value="both">Beides</option>
                  <option value="income">Einnahme</option>
                  <option value="expense">Ausgabe</option>
                </select>
              </label>
            </div>
            <div>
              <p className="mb-2 text-sm text-muted-foreground">Farbe</p>
              <div className="flex flex-wrap gap-2">
                {CATEGORY_COLORS.map((color) => (
                  <button key={color} type="button" onClick={() => setCategoryForm((c) => ({ ...c, color }))} className={cn("h-8 w-8 rounded-full border-2 transition-all", categoryForm.color === color ? "border-foreground scale-110" : "border-transparent hover:scale-105")} style={{ backgroundColor: color }} />
                ))}
              </div>
            </div>
            <div className="flex justify-end gap-2">
              <Button variant="ghost" onClick={() => setCategoryFormOpen(false)}>Schließen</Button>
              <Button onClick={() => void handleCreateCategory()} disabled={saving}>{saving ? "Speichert..." : "Hinzufügen"}</Button>
            </div>
            <div className="space-y-2 border-t border-border pt-4">
              {categories.length === 0 ? (
                <p className="text-sm text-muted-foreground">Noch keine eigenen Kategorien.</p>
              ) : (
                categories.map((cat) => (
                  <div key={cat.id} className="group flex items-center gap-3 rounded-xl border border-border/40 px-3 py-2.5 transition-all hover:border-border">
                    <span className="h-3 w-3 rounded-full" style={{ backgroundColor: cat.color }} />
                    <div className="min-w-0 flex-1">
                      <p className="truncate text-sm font-medium">{cat.name}</p>
                      <p className="text-xs text-muted-foreground">{cat.type === "both" ? "Beides" : cat.type === "income" ? "Einnahme" : "Ausgabe"}</p>
                    </div>
                    <button type="button" onClick={() => void deleteCategory(cat.id)} className="rounded-lg p-1 text-muted-foreground opacity-0 group-hover:opacity-100 hover:bg-accent hover:text-destructive transition-all"><Trash2 className="h-3.5 w-3.5" /></button>
                  </div>
                ))
              )}
            </div>
          </div>
        </Modal>
      )}

      {/* CSV import */}
      {csvImportOpen && (
        <Modal open={csvImportOpen} onClose={() => setCsvImportOpen(false)} title="CSV Import" className="max-w-2xl">
          <div className="space-y-4">
            {error && <p className="rounded-lg bg-destructive/10 px-3 py-2 text-sm text-destructive">{error}</p>}
            <div className="rounded-xl border border-border/40 bg-background/60 p-3 text-sm text-muted-foreground">
              Format: <span className="font-mono text-xs">type,title,amount,category,date,status,description</span><br />
              Beispiel: <span className="font-mono text-xs">expense,Einkauf,54.20,Lebensmittel,2026-04-10,cleared,Wocheneinkauf</span>
            </div>
            <Textarea value={csvText} onChange={(e) => setCsvText(e.target.value)} placeholder="type,title,amount,category,date,status,description" className="min-h-[220px] font-mono text-xs" />
            <div className="flex justify-end gap-2">
              <Button variant="ghost" onClick={() => setCsvImportOpen(false)}>Abbrechen</Button>
              <Button onClick={() => void handleImportCsv()} disabled={saving || !csvText.trim()}>{saving ? "Importiert..." : "Importieren"}</Button>
            </div>
          </div>
        </Modal>
      )}
    </div>
  );
}
