import React, { useState, useEffect } from 'react';
import DashboardLayout from '../components/dashboard/DashboardLayout';
import {
  Alert,
  Box,
  Button,
  Card,
  CardContent,
  Checkbox,
  Chip,
  CircularProgress,
  Dialog,
  DialogActions,
  DialogContent,
  DialogTitle,
  FormControl,
  FormControlLabel,
  IconButton,
  InputAdornment,
  InputLabel,
  MenuItem,
  Paper,
  Select,
  Stack,
  Switch,
  Tab,
  Table,
  TableBody,
  TableCell,
  TableContainer,
  TableHead,
  TableRow,
  TableSortLabel,
  Tabs,
  TextField,
  ToggleButton,
  ToggleButtonGroup,
  Tooltip,
  Typography,
} from '@mui/material';
import {
  Add as AddIcon,
  BookmarkAdd,
  Cancel,
  Delete,
  Download,
  Edit,
  ExpandLess as ExpandLessIcon,
  ExpandMore as ExpandMoreIcon,
  Lock,
  Save,
  SwapHoriz,
  PictureAsPdf as PdfIcon,
} from '@mui/icons-material';
import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query';
import { useNavigate, useSearchParams } from 'react-router-dom';
import { buchhaltungApi } from '../services/buchhaltung';
import { configApi, type PdfSettings } from '../services/config';
import { addPdfHeader, addPdfFooter } from '../utils/pdfExport';
import ChatAwareFab from '../components/shared/ChatAwareFab';
import { useNotification } from '../contexts/NotificationContext';
import { usePermissionContext } from '../contexts/PermissionContext';
import type {
  Haushaltsjahr, HaushaltsjahrFormData,
  Bankkonto, BankkontoFormData,
  Konto, KontoFormData,
  KontoTreeNode,
  KontoTyp,
  Kategorie,
  Transaktion, TransaktionFilters,
  TransaktionTyp,

  WiederkehrendBuchung, WiederkehrendFormData,
  WiederkehrendIntervall,
  BudgetTyp,
  ErstattungFormData,
  TransferFormData,
} from '../types/buchhaltung.types';
import {
  TRANSAKTION_TYP_LABELS,
  INTERVALL_LABELS,
  KONTO_ART_LABELS,
} from '../types/buchhaltung.types';


// ─── helpers ───────────────────────────────────────────────────────────────────

function fmtEur(val: number) {
  return new Intl.NumberFormat('de-DE', { style: 'currency', currency: 'EUR' }).format(val);
}

const dividerLeft = { borderLeft: '2px solid', borderColor: 'divider' } as const;
const dividerRight = { borderRight: '2px solid', borderColor: 'divider' } as const;

function fmtDate(val: string) {
  return new Date(val).toLocaleDateString('de-DE');
}

function TabPanel({ children, value, index }: { children: React.ReactNode; value: number; index: number }) {
  return value === index ? <Box role="tabpanel" sx={{ pt: 3 }}>{children}</Box> : null;
}

// ─── PDF Export ─────────────────────────────────────────────────────────────────

let _pdfSettingsCache: PdfSettings | null = null;
let _pdfSettingsCacheTime = 0;

async function fetchPdfSettings(): Promise<PdfSettings> {
  if (_pdfSettingsCache && Date.now() - _pdfSettingsCacheTime < 30_000) {
    return _pdfSettingsCache;
  }
  try {
    _pdfSettingsCache = await configApi.getPdfSettings();
    _pdfSettingsCacheTime = Date.now();
    return _pdfSettingsCache;
  } catch {
    return { pdf_header: '', pdf_footer: '', pdf_logo: '', pdf_org_name: '' };
  }
}

async function generateBuchhaltungPdf(
  jahrBezeichnung: string,
  totalEinnahmen: number,
  totalAusgaben: number,
  saldo: number,
  treeData: KontoTreeNode[],
  transaktionen: Transaktion[],
) {
  const { jsPDF } = await import('jspdf');
  const autoTable = (await import('jspdf-autotable')).default;
  const pdfSettings = await fetchPdfSettings();

  const doc = new jsPDF({ orientation: 'portrait', unit: 'mm', format: 'a4' });
  const pageWidth = 210;

  // ── Page 1: Summary ──
  let y = await addPdfHeader(doc, pdfSettings, pageWidth);

  doc.setFontSize(16);
  doc.setFont('helvetica', 'bold');
  doc.text(`Buchhaltung \u2014 ${jahrBezeichnung}`, 10, y);
  y += 12;

  doc.setFontSize(11);
  doc.setFont('helvetica', 'normal');
  doc.text(`Einnahmen:`, 10, y);
  doc.setFont('helvetica', 'bold');
  doc.setTextColor(46, 125, 50);
  doc.text(fmtEur(totalEinnahmen), 50, y);
  y += 7;

  doc.setFont('helvetica', 'normal');
  doc.setTextColor(0, 0, 0);
  doc.text(`Ausgaben:`, 10, y);
  doc.setFont('helvetica', 'bold');
  doc.setTextColor(211, 47, 47);
  doc.text(fmtEur(totalAusgaben), 50, y);
  y += 7;

  doc.setFont('helvetica', 'normal');
  doc.setTextColor(0, 0, 0);
  doc.text(`Saldo:`, 10, y);
  doc.setFont('helvetica', 'bold');
  doc.setTextColor(saldo >= 0 ? 46 : 211, saldo >= 0 ? 125 : 47, saldo >= 0 ? 50 : 47);
  doc.text(fmtEur(saldo), 50, y);
  y += 14;

  doc.setTextColor(0, 0, 0);

  // ── Page 2+: Konten tree table ──
  doc.setFontSize(13);
  doc.setFont('helvetica', 'bold');
  doc.text('Konten', 10, y);
  y += 6;

  const kontenRows = treeData.map(k => [
    `${k.kontonummer} ${k.bezeichnung}`,
    fmtEur(Number(k.budget_gwg || 0)),
    fmtEur(Number(k.budget_anlagen || 0)),
    fmtEur(Number(k.budget_instandhaltung || 0)),
    fmtEur(Number(k.budget_gwg || 0) + Number(k.budget_anlagen || 0) + Number(k.budget_instandhaltung || 0)),
    fmtEur(Number(k.spent_gwg || 0) + Number(k.spent_anlagen || 0) + Number(k.spent_instandhaltung || 0)),
    fmtEur(Number(k.einnahmen_betrag || 0)),
  ]);

  autoTable(doc, {
    head: [['Konto', 'Budget GWG', 'Budget Anl.', 'Budget Inst.', 'Budget Ges.', 'Ausgaben Ges.', 'Einnahmen']],
    body: kontenRows,
    startY: y,
    headStyles: { fillColor: [183, 28, 28], textColor: 255, fontStyle: 'bold', fontSize: 7 },
    styles: { fontSize: 7, cellPadding: 1.5 },
    alternateRowStyles: { fillColor: [250, 235, 235] },
    margin: { left: 10, right: 10 },
    columnStyles: {
      0: { cellWidth: 50 },
      1: { halign: 'right' },
      2: { halign: 'right' },
      3: { halign: 'right' },
      4: { halign: 'right' },
      5: { halign: 'right' },
      6: { halign: 'right' },
    },
    didDrawPage: addPdfFooter(doc, pdfSettings),
  });

  // ── Next page(s): Transactions ──
  doc.addPage();
  let txY = await addPdfHeader(doc, pdfSettings, pageWidth);

  doc.setFontSize(13);
  doc.setFont('helvetica', 'bold');
  doc.text('Transaktionen', 10, txY);
  txY += 6;

  const txRows = transaktionen.map(t => [
    fmtDate(t.datum),
    t.typ === 'transfer' ? 'Transfer' : t.typ === 'einnahme' ? 'Einnahme' : 'Ausgabe',
    t.beschreibung || t.empfaenger_auftraggeber || '',
    t.beleg_nr || '',
    t.konto_kontonummer ? `${t.konto_kontonummer} ${t.konto_bezeichnung || ''}` : '',
    `${t.typ === 'ausgabe' ? '-' : t.typ === 'einnahme' ? '+' : ''}${fmtEur(t.betrag)}`,
  ]);

  autoTable(doc, {
    head: [['Datum', 'Typ', 'Beschreibung', 'Beleg-Nr.', 'Konto', 'Betrag']],
    body: txRows,
    startY: txY,
    headStyles: { fillColor: [183, 28, 28], textColor: 255, fontStyle: 'bold', fontSize: 7 },
    styles: { fontSize: 7, cellPadding: 1.5 },
    alternateRowStyles: { fillColor: [250, 235, 235] },
    margin: { left: 10, right: 10 },
    columnStyles: {
      0: { cellWidth: 22 },
      1: { cellWidth: 18 },
      2: { cellWidth: 55 },
      3: { cellWidth: 22 },
      4: { cellWidth: 40 },
      5: { halign: 'right', cellWidth: 25 },
    },
    didDrawPage: addPdfFooter(doc, pdfSettings),
  });

  doc.save(`buchhaltung_${jahrBezeichnung.replace(/\s+/g, '_')}.pdf`);
}

// ─── Sub-components ────────────────────────────────────────────────────────────

function HaushaltsjahrDialog({
  open,
  onClose,
  existing,
  onSave,
}: {
  open: boolean;
  onClose: () => void;
  existing?: Haushaltsjahr;
  onSave: (data: HaushaltsjahrFormData) => void;
}) {
  const year = new Date().getFullYear();
  const [form, setForm] = useState<HaushaltsjahrFormData>({
    jahr: year,
    bezeichnung: `Haushaltsjahr ${year}`,
    beginn: `${year}-01-01`,
    ende: `${year}-12-31`,
  });

  useEffect(() => {
    if (existing) {
      setForm({ jahr: existing.jahr, bezeichnung: existing.bezeichnung, beginn: existing.beginn.slice(0, 10), ende: existing.ende.slice(0, 10) });
    } else {
      setForm({ jahr: year, bezeichnung: `Haushaltsjahr ${year}`, beginn: `${year}-01-01`, ende: `${year}-12-31` });
    }
  }, [existing, open, year]);

  return (
    <Dialog open={open} onClose={onClose} maxWidth="sm" fullWidth>
      <DialogTitle>{existing ? 'Haushaltsjahr bearbeiten' : 'Neues Haushaltsjahr'}</DialogTitle>
      <DialogContent>
        <Stack spacing={2} sx={{ mt: 1 }}>
          <TextField label="Jahr" type="number" value={form.jahr} onChange={e => setForm(f => ({ ...f, jahr: parseInt(e.target.value, 10) }))} />
          <TextField label="Bezeichnung" value={form.bezeichnung} onChange={e => setForm(f => ({ ...f, bezeichnung: e.target.value }))} />
          <TextField label="Beginn" type="date" value={form.beginn} onChange={e => setForm(f => ({ ...f, beginn: e.target.value }))} InputLabelProps={{ shrink: true }} />
          <TextField label="Ende" type="date" value={form.ende} onChange={e => setForm(f => ({ ...f, ende: e.target.value }))} InputLabelProps={{ shrink: true }} />
        </Stack>
      </DialogContent>
      <DialogActions>
        <Button onClick={onClose}>Abbrechen</Button>
        <Button variant="contained" onClick={() => onSave(form)}>Speichern</Button>
      </DialogActions>
    </Dialog>
  );
}

function BankkontoDialog({
  open,
  onClose,
  existing,
  onSave,
}: {
  open: boolean;
  onClose: () => void;
  existing?: Bankkonto;
  onSave: (data: BankkontoFormData) => void;
}) {
  const empty: BankkontoFormData = { bezeichnung: '', iban: '', bic: '', institut: '', ist_standard: false };
  const [form, setForm] = useState<BankkontoFormData>(empty);

  useEffect(() => {
    if (existing) {
      setForm({ bezeichnung: existing.bezeichnung, iban: existing.iban || '', bic: existing.bic || '', institut: existing.institut || '', ist_standard: existing.ist_standard });
    } else {
      setForm(empty);
    }
  // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [existing, open]);

  return (
    <Dialog open={open} onClose={onClose} maxWidth="sm" fullWidth>
      <DialogTitle>{existing ? 'Bankkonto bearbeiten' : 'Neues Bankkonto'}</DialogTitle>
      <DialogContent>
        <Stack spacing={2} sx={{ mt: 1 }}>
          <TextField label="Bezeichnung" value={form.bezeichnung} onChange={e => setForm(f => ({ ...f, bezeichnung: e.target.value }))} required />
          <TextField label="IBAN" value={form.iban} onChange={e => setForm(f => ({ ...f, iban: e.target.value }))} />
          <TextField label="Institut" value={form.institut} onChange={e => setForm(f => ({ ...f, institut: e.target.value }))} />
        </Stack>
      </DialogContent>
      <DialogActions>
        <Button onClick={onClose}>Abbrechen</Button>
        <Button variant="contained" onClick={() => onSave(form)}>Speichern</Button>
      </DialogActions>
    </Dialog>
  );
}

function KontoDialog({
  open,
  onClose,
  haushaltsjahrId,
  existing,
  konten,
  kategorien = [],
  onSave,
  externalError,
}: {
  open: boolean;
  onClose: () => void;
  haushaltsjahrId: number;
  existing?: Konto;
  konten: Konto[];
  kategorien?: Kategorie[];
  onSave: (data: KontoFormData) => void;
  externalError?: string | null;
}) {
  const empty: KontoFormData = { haushaltsjahr_id: haushaltsjahrId, kontonummer: 0, bezeichnung: '', budget_gwg: 0, budget_anlagen: 0, budget_instandhaltung: 0, budget_typ: 'detailliert', budget_gesamt: 0, parent_id: null, kategorie_id: null, notizen: '' };
  const [form, setForm] = useState<KontoFormData>(empty);
  const [saveError, setSaveError] = useState<string | null>(null);

  const selectedParent = konten.find(k => k.id === form.parent_id);

  // Compute sibling budget usage for parent reference
  const siblingBudgets = selectedParent ? (() => {
    const siblings = konten.filter(k => k.parent_id === selectedParent.id && k.id !== existing?.id);
    return {
      gwg: siblings.reduce((s, k) => s + Number(k.budget_gwg || 0), 0),
      anlagen: siblings.reduce((s, k) => s + Number(k.budget_anlagen || 0), 0),
      instandhaltung: siblings.reduce((s, k) => s + Number(k.budget_instandhaltung || 0), 0),
    };
  })() : null;

  // suffix = form.kontonummer - parent.kontonummer (arithmetic)
  const suffixValue = selectedParent ? form.kontonummer - selectedParent.kontonummer : form.kontonummer;

  const handleParentChange = (parentId: number | null) => {
    const parent = konten.find(k => k.id === parentId);
    const oldBase = selectedParent ? selectedParent.kontonummer : 0;
    const currentSuffix = form.kontonummer - oldBase;
    const newBase = parent ? parent.kontonummer : 0;
    setForm(f => ({ ...f, parent_id: parentId, kontonummer: newBase + Math.max(0, currentSuffix) }));
  };

  const handleSuffixChange = (value: string) => {
    const suffix = parseInt(value, 10);
    const base = selectedParent ? selectedParent.kontonummer : 0;
    setForm(f => ({ ...f, kontonummer: base + (isNaN(suffix) ? 0 : suffix) }));
  };

  useEffect(() => {
    if (existing) {
      setForm({ haushaltsjahr_id: haushaltsjahrId, kontonummer: existing.kontonummer, bezeichnung: existing.bezeichnung, budget_gwg: existing.budget_gwg, budget_anlagen: existing.budget_anlagen, budget_instandhaltung: existing.budget_instandhaltung, budget_typ: existing.budget_typ || 'detailliert', budget_gesamt: existing.budget_gesamt || 0, parent_id: existing.parent_id, kategorie_id: existing.kategorie_id ?? null, notizen: existing.notizen || '' });
    } else {
      setForm({ ...empty, haushaltsjahr_id: haushaltsjahrId });
    }
  // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [existing, open, haushaltsjahrId]);

  return (
    <Dialog open={open} onClose={onClose} maxWidth="sm" fullWidth>
      <DialogTitle>{existing ? 'Konto bearbeiten' : 'Neues Konto'}</DialogTitle>
      <DialogContent>
        <Stack spacing={2} sx={{ mt: 1 }}>
          <TextField
            label={selectedParent ? 'Kontonummer (Suffix)' : 'Kontonummer'}
            type="number"
            value={suffixValue || ''}
            onChange={e => handleSuffixChange(e.target.value)}
            required
            inputProps={{ min: 1, step: 1 }}
            InputProps={selectedParent ? {
              startAdornment: <InputAdornment position="start">{selectedParent.kontonummer} +</InputAdornment>,
            } : undefined}
            helperText={selectedParent ? `Ergibt Kontonummer: ${form.kontonummer}` : undefined}
          />
          <TextField label="Bezeichnung" value={form.bezeichnung} onChange={e => setForm(f => ({ ...f, bezeichnung: e.target.value }))} required />
          <FormControl fullWidth margin="dense">
            <InputLabel>Elternkonto (optional)</InputLabel>
            <Select
              value={form.parent_id ?? ''}
              onChange={e => handleParentChange(e.target.value ? Number(e.target.value) : null)}
              label="Elternkonto (optional)"
            >
              <MenuItem value=""><em>Kein Elternkonto</em></MenuItem>
              {konten
                .filter(k => k.id !== existing?.id)
                .map(k => (
                  <MenuItem key={k.id} value={k.id}>{k.kontonummer} — {k.bezeichnung}</MenuItem>
                ))
              }
            </Select>
          </FormControl>
          {kategorien.length > 0 && (
            <FormControl fullWidth margin="dense">
              <InputLabel>Kategorie</InputLabel>
              <Select
                value={form.kategorie_id ?? ''}
                onChange={e => setForm(f => ({ ...f, kategorie_id: e.target.value ? Number(e.target.value) : null }))}
                label="Kategorie"
              >
                <MenuItem value=""><em>Keine Kategorie</em></MenuItem>
                {kategorien.map(kat => (
                  <MenuItem key={kat.id} value={kat.id}>{kat.bezeichnung}</MenuItem>
                ))}
              </Select>
            </FormControl>
          )}
          {!form.parent_id && (
            <Box>
              <Typography variant="body2" color="text.secondary" sx={{ mb: 0.5 }}>Budget-Typ</Typography>
              <ToggleButtonGroup
                value={form.budget_typ || 'detailliert'}
                exclusive
                size="small"
                onChange={(_, val) => { if (val) setForm(f => ({ ...f, budget_typ: val as BudgetTyp })); }}
              >
                <ToggleButton value="detailliert">Detailliert</ToggleButton>
                <ToggleButton value="einfach">Einfach</ToggleButton>
              </ToggleButtonGroup>
            </Box>
          )}
          {(form.budget_typ || 'detailliert') === 'einfach' ? (
            <TextField label="Budget Gesamt (€)" type="number" value={form.budget_gesamt ?? 0} onChange={e => setForm(f => ({ ...f, budget_gesamt: parseFloat(e.target.value) || 0 }))} inputProps={{ step: '0.01', min: '0' }} />
          ) : (
          <>
          <TextField label="GWG Budget (€)" type="number" value={form.budget_gwg} onChange={e => setForm(f => ({ ...f, budget_gwg: parseFloat(e.target.value) || 0 }))} inputProps={{ step: '0.01', min: '0' }} />
          {selectedParent && siblingBudgets && (
            <Typography variant="caption" color="text.secondary" sx={{ mt: -1 }}>
              Eltern-Budget: {fmtEur(selectedParent.budget_gwg)}, vergeben: {fmtEur(siblingBudgets.gwg)}, verfügbar: {fmtEur(selectedParent.budget_gwg - siblingBudgets.gwg)}
            </Typography>
          )}
          <TextField label="Anlagen Budget (€)" type="number" value={form.budget_anlagen} onChange={e => setForm(f => ({ ...f, budget_anlagen: parseFloat(e.target.value) || 0 }))} inputProps={{ step: '0.01', min: '0' }} />
          {selectedParent && siblingBudgets && (
            <Typography variant="caption" color="text.secondary" sx={{ mt: -1 }}>
              Eltern-Budget: {fmtEur(selectedParent.budget_anlagen)}, vergeben: {fmtEur(siblingBudgets.anlagen)}, verfügbar: {fmtEur(selectedParent.budget_anlagen - siblingBudgets.anlagen)}
            </Typography>
          )}
          <TextField label="Instandhaltung Budget (€)" type="number" value={form.budget_instandhaltung} onChange={e => setForm(f => ({ ...f, budget_instandhaltung: parseFloat(e.target.value) || 0 }))} inputProps={{ step: '0.01', min: '0' }} />
          {selectedParent && siblingBudgets && (
            <Typography variant="caption" color="text.secondary" sx={{ mt: -1 }}>
              Eltern-Budget: {fmtEur(selectedParent.budget_instandhaltung)}, vergeben: {fmtEur(siblingBudgets.instandhaltung)}, verfügbar: {fmtEur(selectedParent.budget_instandhaltung - siblingBudgets.instandhaltung)}
            </Typography>
          )}
          </>
          )}
          <TextField label="Notizen" value={form.notizen} onChange={e => setForm(f => ({ ...f, notizen: e.target.value }))} multiline rows={2} />
          {saveError && <Alert severity="error" onClose={() => setSaveError(null)}>{saveError}</Alert>}
          {!saveError && externalError && <Alert severity="error">{externalError}</Alert>}
        </Stack>
      </DialogContent>
      <DialogActions>
        <Button onClick={onClose}>Abbrechen</Button>
        <Button variant="contained" onClick={() => onSave(form)} disabled={!form.bezeichnung || !form.kontonummer || (!!selectedParent && suffixValue <= 0)}>Speichern</Button>
      </DialogActions>
    </Dialog>
  );
}

// ─── Tree helpers ─────────────────────────────────────────────────────────────

function buildTree(flat: KontoTreeNode[]): KontoTreeNode[] {
  const map = new Map<number, KontoTreeNode>();
  flat.forEach(k => map.set(k.id, { ...k, children: [] }));
  const roots: KontoTreeNode[] = [];
  flat.forEach(k => {
    if (k.parent_id && map.has(k.parent_id)) {
      map.get(k.parent_id)!.children.push(map.get(k.id)!);
    } else {
      roots.push(map.get(k.id)!);
    }
  });
  return roots;
}

function KontoRow({ konto, depth = 0, onNavigate }: { konto: KontoTreeNode; depth?: number; onNavigate: (id: number) => void }) {
  const [open, setOpen] = useState(false);
  const isEinfach = (konto.budget_typ || 'detailliert') === 'einfach';
  const totalBudget = isEinfach ? Number(konto.budget_gesamt || 0) : Number(konto.budget_gwg || 0) + Number(konto.budget_anlagen || 0) + Number(konto.budget_instandhaltung || 0);
  const totalSpent = Number(konto.spent_gwg || 0) + Number(konto.spent_anlagen || 0) + Number(konto.spent_instandhaltung || 0);

  return (
    <>
      <TableRow onClick={() => onNavigate(konto.id)} sx={{ cursor: 'pointer' }}>
        <TableCell sx={{ pl: 2 + depth * 3 }}>
          <Typography variant="body2">
            {konto.kontonummer} — {konto.bezeichnung}
          </Typography>
        </TableCell>
        <TableCell align="right" sx={dividerLeft}>{isEinfach ? '' : fmtEur(konto.budget_gwg)}</TableCell>
        <TableCell align="right">{isEinfach ? '' : fmtEur(konto.budget_anlagen)}</TableCell>
        <TableCell align="right">{isEinfach ? '' : fmtEur(konto.budget_instandhaltung)}</TableCell>
        <TableCell align="right"><strong>{fmtEur(totalBudget)}</strong></TableCell>
        <TableCell align="right" sx={dividerLeft}>{isEinfach ? '' : fmtEur(konto.spent_gwg)}</TableCell>
        <TableCell align="right">{isEinfach ? '' : fmtEur(konto.spent_anlagen)}</TableCell>
        <TableCell align="right">{isEinfach ? '' : fmtEur(konto.spent_instandhaltung)}</TableCell>
        <TableCell align="right"><strong>{fmtEur(totalSpent)}</strong></TableCell>
        <TableCell align="right" sx={{ ...dividerLeft, ...dividerRight }}>{fmtEur(konto.einnahmen_betrag)}</TableCell>
        <TableCell sx={{ width: 40, px: 0.5 }}>
          {konto.children.length > 0 && (
            <IconButton size="small" onClick={e => { e.stopPropagation(); setOpen(!open); }}>
              {open ? <ExpandLessIcon /> : <ExpandMoreIcon />}
            </IconButton>
          )}
        </TableCell>
      </TableRow>
      {open && konto.children.map(child => (
        <KontoRow key={child.id} konto={child} depth={depth + 1} onNavigate={onNavigate} />
      ))}
    </>
  );
}

function KontoManageRow({ konto, depth = 0, onNavigate }: {
  konto: KontoTreeNode;
  depth?: number;
  onNavigate: (id: number) => void;
}) {
  const [open, setOpen] = useState(false);
  const isEinfach = (konto.budget_typ || 'detailliert') === 'einfach';
  const totalBudget = isEinfach
    ? Number(konto.budget_gesamt || 0)
    : Number(konto.budget_gwg) + Number(konto.budget_anlagen) + Number(konto.budget_instandhaltung);

  return (
    <>
      <TableRow hover onClick={() => onNavigate(konto.id)} sx={{ cursor: 'pointer' }}>
        <TableCell sx={{ pl: 2 + depth * 3 }}>
          <Typography variant="body2">{konto.kontonummer} — {konto.bezeichnung}</Typography>
        </TableCell>
        <TableCell align="right">{isEinfach ? '—' : fmtEur(konto.budget_gwg)}</TableCell>
        <TableCell align="right">{isEinfach ? '—' : fmtEur(konto.budget_anlagen)}</TableCell>
        <TableCell align="right">{isEinfach ? '—' : fmtEur(konto.budget_instandhaltung)}</TableCell>
        <TableCell align="right"><strong>{fmtEur(totalBudget)}</strong></TableCell>
        <TableCell sx={{ width: 40, px: 0.5 }}>
          {konto.children.length > 0 && (
            <IconButton size="small" onClick={e => { e.stopPropagation(); setOpen(!open); }}>
              {open ? <ExpandLessIcon /> : <ExpandMoreIcon />}
            </IconButton>
          )}
        </TableCell>
      </TableRow>
      {open && konto.children.map(child => (
        <KontoManageRow key={child.id} konto={child} depth={depth + 1} onNavigate={onNavigate} />
      ))}
    </>
  );
}

// ─── Tab 0: Übersicht ─────────────────────────────────────────────────────────

function UebersichtTab({ haushaltsjahre, selectedJahrId, onJahrChange }: {
  haushaltsjahre: Haushaltsjahr[];
  selectedJahrId: number | null;
  onJahrChange: (id: number) => void;
}) {
  const navigate = useNavigate();
  const { hasPermission } = usePermissionContext();
  const { showError } = useNotification();
  const { data: treeData = [], isLoading } = useQuery({
    queryKey: ['kontenTree', selectedJahrId],
    queryFn: () => buchhaltungApi.getKontenTree(selectedJahrId!),
    enabled: selectedJahrId != null,
  });
  const { data: kategorien = [] } = useQuery({
    queryKey: ['buchhaltung-kategorien', selectedJahrId],
    queryFn: () => buchhaltungApi.getKategorien(selectedJahrId!),
    enabled: selectedJahrId != null,
  });
  const { data: transaktionenForPdf = [] } = useQuery({
    queryKey: ['buchhaltung-transaktionen', { haushaltsjahr_id: selectedJahrId }],
    queryFn: () => buchhaltungApi.getTransaktionen({ haushaltsjahr_id: selectedJahrId! }),
    enabled: selectedJahrId != null,
  });

  const tree = buildTree(treeData);

  const sumBudgetGwg = treeData.reduce((s, k) => s + Number(k.budget_gwg || 0), 0);
  const sumBudgetAnlagen = treeData.reduce((s, k) => s + Number(k.budget_anlagen || 0), 0);
  const sumBudgetInst = treeData.reduce((s, k) => s + Number(k.budget_instandhaltung || 0), 0);
  const sumBudgetGesamt = sumBudgetGwg + sumBudgetAnlagen + sumBudgetInst;
  const sumSpentGwg = treeData.reduce((s, k) => s + Number(k.spent_gwg || 0), 0);
  const sumSpentAnlagen = treeData.reduce((s, k) => s + Number(k.spent_anlagen || 0), 0);
  const sumSpentInst = treeData.reduce((s, k) => s + Number(k.spent_instandhaltung || 0), 0);
  const sumSpentGesamt = sumSpentGwg + sumSpentAnlagen + sumSpentInst;
  const sumEinnahmen = treeData.reduce((s, k) => s + Number(k.einnahmen_betrag || 0), 0);

  const totalEinnahmen = sumEinnahmen;
  const totalAusgaben = sumSpentGesamt;
  const saldo = totalEinnahmen - totalAusgaben;

  return (
    <Box>
      <Box sx={{ mb: 3, display: 'flex', alignItems: 'center', gap: 2 }}>
        <FormControl sx={{ minWidth: 240 }}>
          <InputLabel>Haushaltsjahr</InputLabel>
          <Select value={selectedJahrId ?? ''} label="Haushaltsjahr" onChange={e => onJahrChange(Number(e.target.value))}>
            {haushaltsjahre.map(hj => <MenuItem key={hj.id} value={hj.id}>{hj.bezeichnung}{hj.abgeschlossen ? ' (abgeschlossen)' : ''}</MenuItem>)}
          </Select>
        </FormControl>
        {hasPermission('buchhaltung:export') && selectedJahrId && (
          <Button
            variant="outlined"
            startIcon={<PdfIcon />}
            onClick={async () => {
              const hj = haushaltsjahre.find(h => h.id === selectedJahrId);
              if (!hj) return;
              try {
                await generateBuchhaltungPdf(hj.bezeichnung, totalEinnahmen, totalAusgaben, saldo, treeData, transaktionenForPdf);
              } catch {
                showError('PDF-Export fehlgeschlagen');
              }
            }}
          >
            PDF exportieren
          </Button>
        )}
      </Box>

      {isLoading && <CircularProgress />}
      {!isLoading && selectedJahrId && (
        <>
          <Box sx={{ display: 'grid', gridTemplateColumns: 'repeat(3, 1fr)', gap: 2, mb: 3 }}>
            <Card>
              <CardContent>
                <Typography color="text.secondary" variant="body2">Einnahmen</Typography>
                <Typography variant="h5" color="success.main">{fmtEur(totalEinnahmen)}</Typography>
              </CardContent>
            </Card>
            <Card>
              <CardContent>
                <Typography color="text.secondary" variant="body2">Ausgaben</Typography>
                <Typography variant="h5" color="error.main">{fmtEur(totalAusgaben)}</Typography>
              </CardContent>
            </Card>
            <Card>
              <CardContent>
                <Typography color="text.secondary" variant="body2">Saldo</Typography>
                <Typography variant="h5" color={saldo >= 0 ? 'success.main' : 'error.main'}>{fmtEur(saldo)}</Typography>
              </CardContent>
            </Card>
          </Box>

          <Typography variant="h6" gutterBottom>Konten</Typography>
          <TableContainer component={Paper}>
            <Table size="small">
              <TableHead>
                <TableRow>
                  <TableCell>Konto</TableCell>
                  <TableCell align="right" sx={dividerLeft}>Budget GWG</TableCell>
                  <TableCell align="right">Budget Anlagen</TableCell>
                  <TableCell align="right">Budget Instandh.</TableCell>
                  <TableCell align="right">Budget Gesamt</TableCell>
                  <TableCell align="right" sx={dividerLeft}>Ausgaben GWG</TableCell>
                  <TableCell align="right">Ausgaben Anlagen</TableCell>
                  <TableCell align="right">Ausgaben Instandh.</TableCell>
                  <TableCell align="right">Ausgaben Gesamt</TableCell>
                  <TableCell align="right" sx={{ ...dividerLeft, ...dividerRight }}>Einnahmen</TableCell>
                  <TableCell sx={{ width: 40 }} />
                </TableRow>
              </TableHead>
              <TableBody>
                {tree.length === 0 && (
                  <TableRow><TableCell colSpan={11} align="center"><Typography color="text.secondary">Keine Konten</Typography></TableCell></TableRow>
                )}
                {(() => {
                  const grouped = new Map<number | null, KontoTreeNode[]>();
                  tree.forEach(k => {
                    const key = k.kategorie_id ?? null;
                    if (!grouped.has(key)) grouped.set(key, []);
                    grouped.get(key)!.push(k);
                  });
                  const categoryOrder = kategorien.map(kat => kat.id);
                  const sortedKeys = [...grouped.keys()].sort((a, b) => {
                    if (a === null) return 1;
                    if (b === null) return -1;
                    return categoryOrder.indexOf(a) - categoryOrder.indexOf(b);
                  });
                  const hasMultipleGroups = sortedKeys.length > 1 || (sortedKeys.length === 1 && sortedKeys[0] !== null);
                  return sortedKeys.flatMap(key => {
                    const items = grouped.get(key)!;
                    const rows: React.ReactNode[] = [];
                    if (hasMultipleGroups) {
                      const katName = key !== null ? kategorien.find(k => k.id === key)?.bezeichnung : 'Ohne Kategorie';
                      const catBudgetGwg = items.reduce((s, k) => s + Number(k.budget_gwg || 0), 0);
                      const catBudgetAnl = items.reduce((s, k) => s + Number(k.budget_anlagen || 0), 0);
                      const catBudgetInst = items.reduce((s, k) => s + Number(k.budget_instandhaltung || 0), 0);
                      const catSpentGwg = items.reduce((s, k) => s + Number(k.spent_gwg || 0), 0);
                      const catSpentAnl = items.reduce((s, k) => s + Number(k.spent_anlagen || 0), 0);
                      const catSpentInst = items.reduce((s, k) => s + Number(k.spent_instandhaltung || 0), 0);
                      const catEinnahmen = items.reduce((s, k) => s + Number(k.einnahmen_betrag || 0), 0);
                      rows.push(
                        <TableRow key={`cat-${key}`} sx={{ bgcolor: 'action.hover', '& td': { fontWeight: 600, fontSize: '0.8rem' } }}>
                          <TableCell>{katName}</TableCell>
                          <TableCell align="right" sx={dividerLeft}>{fmtEur(catBudgetGwg)}</TableCell>
                          <TableCell align="right">{fmtEur(catBudgetAnl)}</TableCell>
                          <TableCell align="right">{fmtEur(catBudgetInst)}</TableCell>
                          <TableCell align="right">{fmtEur(catBudgetGwg + catBudgetAnl + catBudgetInst)}</TableCell>
                          <TableCell align="right" sx={dividerLeft}>{fmtEur(catSpentGwg)}</TableCell>
                          <TableCell align="right">{fmtEur(catSpentAnl)}</TableCell>
                          <TableCell align="right">{fmtEur(catSpentInst)}</TableCell>
                          <TableCell align="right">{fmtEur(catSpentGwg + catSpentAnl + catSpentInst)}</TableCell>
                          <TableCell align="right" sx={{ ...dividerLeft, ...dividerRight }}>{fmtEur(catEinnahmen)}</TableCell>
                          <TableCell />
                        </TableRow>
                      );
                    }
                    items.forEach(k => rows.push(
                      <KontoRow key={k.id} konto={k} onNavigate={(id) => navigate(`/buchhaltung/konto/${id}`)} />
                    ));
                    return rows;
                  });
                })()}
                {tree.length > 0 && (
                  <TableRow sx={{ bgcolor: 'action.hover', '& td': { fontWeight: 700 } }}>
                    <TableCell>Gesamt</TableCell>
                    <TableCell align="right" sx={dividerLeft}>{fmtEur(sumBudgetGwg)}</TableCell>
                    <TableCell align="right">{fmtEur(sumBudgetAnlagen)}</TableCell>
                    <TableCell align="right">{fmtEur(sumBudgetInst)}</TableCell>
                    <TableCell align="right">{fmtEur(sumBudgetGesamt)}</TableCell>
                    <TableCell align="right" sx={dividerLeft}>{fmtEur(sumSpentGwg)}</TableCell>
                    <TableCell align="right">{fmtEur(sumSpentAnlagen)}</TableCell>
                    <TableCell align="right">{fmtEur(sumSpentInst)}</TableCell>
                    <TableCell align="right">{fmtEur(sumSpentGesamt)}</TableCell>
                    <TableCell align="right" sx={{ ...dividerLeft, ...dividerRight }}>{fmtEur(sumEinnahmen)}</TableCell>
                    <TableCell />
                  </TableRow>
                )}
              </TableBody>
            </Table>
          </TableContainer>
        </>
      )}
      {!selectedJahrId && !isLoading && (
        <Typography color="text.secondary">Bitte ein Haushaltsjahr auswählen</Typography>
      )}
    </Box>
  );
}

// ─── Erstattung Dialog ────────────────────────────────────────────────────────

function ErstattungDialog({
  open,
  onClose,
  konten,
  bankkonten,
  transaktionen,
  onSave,
}: {
  open: boolean;
  onClose: () => void;
  konten: Konto[];
  bankkonten: Bankkonto[];
  transaktionen: Transaktion[];
  onSave: (data: ErstattungFormData) => void;
}) {
  const today = new Date().toISOString().slice(0, 10);
  const [selectedKonto, setSelectedKonto] = useState<number | null>(null);
  const [selectedBank, setSelectedBank] = useState<number | null>(null);
  const [selectedIds, setSelectedIds] = useState<Set<number>>(new Set());
  const [betrag, setBetrag] = useState(0);
  const [datum, setDatum] = useState(today);
  const [beschreibung, setBeschreibung] = useState('');
  const [empfaenger, setEmpfaenger] = useState('');

  useEffect(() => {
    if (open) {
      setSelectedKonto(null);
      setSelectedBank(null);
      setSelectedIds(new Set());
      setBetrag(0);
      setDatum(today);
      setBeschreibung('');
      setEmpfaenger('');
    }
  // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [open]);

  const ausgabeTransaktionen = transaktionen.filter(
    t => t.typ === 'ausgabe' && t.status === 'gebucht' && (!selectedKonto || t.konto_id === selectedKonto)
  );

  const autoSum = [...selectedIds].reduce((sum, id) => {
    const t = transaktionen.find(tx => tx.id === id);
    return sum + (t ? Number(t.betrag) : 0);
  }, 0);

  useEffect(() => {
    setBetrag(autoSum);
  }, [autoSum]);

  const toggleId = (id: number) => {
    setSelectedIds(prev => {
      const next = new Set(prev);
      if (next.has(id)) next.delete(id); else next.add(id);
      return next;
    });
  };

  return (
    <Dialog open={open} onClose={onClose} maxWidth="md" fullWidth>
      <DialogTitle>Erstattung erfassen</DialogTitle>
      <DialogContent>
        <Stack spacing={2} sx={{ mt: 1 }}>
          <FormControl fullWidth required>
            <InputLabel>Konto</InputLabel>
            <Select value={selectedKonto ?? ''} label="Konto" onChange={e => { setSelectedKonto(e.target.value ? Number(e.target.value) : null); setSelectedIds(new Set()); }}>
              <MenuItem value=""><em>Alle Konten</em></MenuItem>
              {konten.map(k => <MenuItem key={k.id} value={k.id}>{k.kontonummer} – {k.bezeichnung}</MenuItem>)}
            </Select>
          </FormControl>
          <FormControl fullWidth>
            <InputLabel>Bankkonto</InputLabel>
            <Select value={selectedBank ?? ''} label="Bankkonto" onChange={e => setSelectedBank(e.target.value ? Number(e.target.value) : null)}>
              <MenuItem value=""><em>Kein Bankkonto</em></MenuItem>
              {bankkonten.map(bk => <MenuItem key={bk.id} value={bk.id}>{bk.bezeichnung}</MenuItem>)}
            </Select>
          </FormControl>

          <Typography variant="subtitle2">Ausgabe-Transaktionen auswählen</Typography>
          <TableContainer component={Paper} variant="outlined" sx={{ maxHeight: 300 }}>
            <Table size="small" stickyHeader>
              <TableHead>
                <TableRow>
                  <TableCell padding="checkbox" />
                  <TableCell>Datum</TableCell>
                  <TableCell>Beschreibung</TableCell>
                  <TableCell align="right">Betrag</TableCell>
                </TableRow>
              </TableHead>
              <TableBody>
                {ausgabeTransaktionen.length === 0 && (
                  <TableRow><TableCell colSpan={4} align="center"><Typography color="text.secondary" variant="body2">Keine Ausgaben gefunden</Typography></TableCell></TableRow>
                )}
                {ausgabeTransaktionen.map(t => (
                  <TableRow key={t.id} hover onClick={() => toggleId(t.id)} sx={{ cursor: 'pointer' }}>
                    <TableCell padding="checkbox"><Checkbox checked={selectedIds.has(t.id)} size="small" /></TableCell>
                    <TableCell>{fmtDate(t.datum)}</TableCell>
                    <TableCell>{t.beschreibung || t.empfaenger_auftraggeber || '–'}</TableCell>
                    <TableCell align="right">{fmtEur(Number(t.betrag))}</TableCell>
                  </TableRow>
                ))}
              </TableBody>
            </Table>
          </TableContainer>

          <TextField label="Erstattungsbetrag (€)" type="number" value={betrag} onChange={e => setBetrag(parseFloat(e.target.value) || 0)} inputProps={{ step: '0.01', min: '0' }} required />
          <TextField label="Datum" type="date" value={datum} onChange={e => setDatum(e.target.value)} InputLabelProps={{ shrink: true }} required />
          <TextField label="Beschreibung" value={beschreibung} onChange={e => setBeschreibung(e.target.value)} />
          <TextField label="Empfänger" value={empfaenger} onChange={e => setEmpfaenger(e.target.value)} />
        </Stack>
      </DialogContent>
      <DialogActions>
        <Button onClick={onClose}>Abbrechen</Button>
        <Button
          variant="contained"
          disabled={!selectedKonto || !betrag || !datum || selectedIds.size === 0}
          onClick={() => onSave({
            konto_id: selectedKonto!,
            bankkonto_id: selectedBank,
            betrag,
            datum,
            beschreibung: beschreibung || undefined,
            empfaenger_auftraggeber: empfaenger || undefined,
            quell_transaktion_ids: [...selectedIds],
          })}
        >
          Erstattung erstellen
        </Button>
      </DialogActions>
    </Dialog>
  );
}

function TransferDialog({
  open,
  onClose,
  haushaltsjahre,
  selectedJahrId,
  bankkonten,
  onSave,
}: {
  open: boolean;
  onClose: () => void;
  haushaltsjahre: Haushaltsjahr[];
  selectedJahrId: number | null;
  bankkonten: Bankkonto[];
  onSave: (data: TransferFormData) => void;
}) {
  const today = new Date().toISOString().slice(0, 10);
  const [form, setForm] = useState<TransferFormData>({
    haushaltsjahr_id: selectedJahrId || 0,
    bankkonto_id: 0,
    transfer_ziel_bankkonto_id: 0,
    betrag: 0,
    datum: today,
    beschreibung: '',
    beleg_nr: '',
  });

  useEffect(() => {
    if (open) setForm(f => ({ ...f, haushaltsjahr_id: selectedJahrId || 0, bankkonto_id: 0, transfer_ziel_bankkonto_id: 0, betrag: 0, datum: today, beschreibung: '', beleg_nr: '' }));
  // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [open]);

  const zielOptions = bankkonten.filter(bk => bk.id !== form.bankkonto_id);

  return (
    <Dialog open={open} onClose={onClose} maxWidth="sm" fullWidth>
      <DialogTitle>Transfer zwischen Bankkonten</DialogTitle>
      <DialogContent>
        <Stack spacing={2} sx={{ mt: 1 }}>
          <FormControl fullWidth required>
            <InputLabel>Haushaltsjahr</InputLabel>
            <Select value={form.haushaltsjahr_id || ''} label="Haushaltsjahr" onChange={e => setForm(f => ({ ...f, haushaltsjahr_id: Number(e.target.value) }))}>
              {haushaltsjahre.map(hj => <MenuItem key={hj.id} value={hj.id}>{hj.bezeichnung}</MenuItem>)}
            </Select>
          </FormControl>
          <FormControl fullWidth required>
            <InputLabel>Quell-Bankkonto</InputLabel>
            <Select value={form.bankkonto_id || ''} label="Quell-Bankkonto" onChange={e => setForm(f => ({ ...f, bankkonto_id: Number(e.target.value), transfer_ziel_bankkonto_id: f.transfer_ziel_bankkonto_id === Number(e.target.value) ? 0 : f.transfer_ziel_bankkonto_id }))}>
              {bankkonten.map(bk => <MenuItem key={bk.id} value={bk.id}>{bk.bezeichnung}{bk.iban ? ` (${bk.iban})` : ''}</MenuItem>)}
            </Select>
          </FormControl>
          <FormControl fullWidth required>
            <InputLabel>Ziel-Bankkonto</InputLabel>
            <Select value={form.transfer_ziel_bankkonto_id || ''} label="Ziel-Bankkonto" onChange={e => setForm(f => ({ ...f, transfer_ziel_bankkonto_id: Number(e.target.value) }))}>
              {zielOptions.map(bk => <MenuItem key={bk.id} value={bk.id}>{bk.bezeichnung}{bk.iban ? ` (${bk.iban})` : ''}</MenuItem>)}
            </Select>
          </FormControl>
          <TextField label="Betrag (EUR)" type="number" value={form.betrag} onChange={e => setForm(f => ({ ...f, betrag: parseFloat(e.target.value) || 0 }))} inputProps={{ step: '0.01', min: '0' }} required />
          <TextField label="Datum" type="date" value={form.datum} onChange={e => setForm(f => ({ ...f, datum: e.target.value }))} InputLabelProps={{ shrink: true }} required />
          <TextField label="Beschreibung" value={form.beschreibung} onChange={e => setForm(f => ({ ...f, beschreibung: e.target.value }))} />
          <TextField label="Beleg-Nr." value={form.beleg_nr} onChange={e => setForm(f => ({ ...f, beleg_nr: e.target.value }))} />
        </Stack>
      </DialogContent>
      <DialogActions>
        <Button onClick={onClose}>Abbrechen</Button>
        <Button
          variant="contained"
          disabled={!form.haushaltsjahr_id || !form.bankkonto_id || !form.transfer_ziel_bankkonto_id || !form.betrag || !form.datum}
          onClick={() => onSave(form)}
        >
          Transfer erstellen
        </Button>
      </DialogActions>
    </Dialog>
  );
}

// ─── Tab 1: Transaktionen ─────────────────────────────────────────────────────

function TransaktionenTab({ haushaltsjahre, selectedJahrId, onJahrChange }: {
  haushaltsjahre: Haushaltsjahr[];
  selectedJahrId: number | null;
  onJahrChange: (id: number) => void;
}) {
  const qc = useQueryClient();
  const navigate = useNavigate();
  const { showSuccess, showError } = useNotification();
  const { hasPermission } = usePermissionContext();
  const [filters, setFilters] = useState<TransaktionFilters>({ haushaltsjahr_id: selectedJahrId || undefined });
  const [filterAusgabenTyp, setFilterAusgabenTyp] = useState('');
  const [txSubTab, setTxSubTab] = useState(0);

  // ── Erstattung state ──
  const [erstattungOpen, setErstattungOpen] = useState(false);

  // ── Transfer state ──
  const [transferOpen, setTransferOpen] = useState(false);

  // ── Wiederkehrend state ──
  const [wiederkehrendDialog, setWiederkehrendDialog] = useState<{ open: boolean; existing?: WiederkehrendBuchung }>({ open: false });

  const { data: kontenFlat = [] } = useQuery({
    queryKey: ['buchhaltung-konten', selectedJahrId],
    queryFn: () => buchhaltungApi.getKonten(selectedJahrId!),
    enabled: selectedJahrId != null,
  });
  const { data: bankkonten = [] } = useQuery({ queryKey: ['bankkonten'], queryFn: buchhaltungApi.getBankkonten });
  const { data: wiederkehrend = [] } = useQuery({ queryKey: ['buchhaltung-wiederkehrend'], queryFn: buchhaltungApi.getWiederkehrend });

  const { data: transaktionen = [], isLoading } = useQuery({
    queryKey: ['buchhaltung-transaktionen', filters],
    queryFn: () => buchhaltungApi.getTransaktionen(filters),
  });

  const buchenMut = useMutation({
    mutationFn: (id: number) => buchhaltungApi.buchenTransaktion(id),
    onSuccess: () => { qc.invalidateQueries({ queryKey: ['buchhaltung-transaktionen'] }); qc.invalidateQueries({ queryKey: ['buchhaltung-stats'] }); showSuccess('Transaktion gebucht'); },
    onError: () => showError('Buchung fehlgeschlagen'),
  });

  const stornoMut = useMutation({
    mutationFn: (id: number) => buchhaltungApi.stornoTransaktion(id),
    onSuccess: () => { qc.invalidateQueries({ queryKey: ['buchhaltung-transaktionen'] }); qc.invalidateQueries({ queryKey: ['buchhaltung-stats'] }); setTxSubTab(0); showSuccess('Transaktion storniert'); },
    onError: () => showError('Storno fehlgeschlagen'),
  });

  const deleteMut = useMutation({
    mutationFn: (id: number) => buchhaltungApi.deleteTransaktion(id),
    onSuccess: () => { qc.invalidateQueries({ queryKey: ['buchhaltung-transaktionen'] }); showSuccess('Transaktion gelöscht'); },
    onError: () => showError('Löschen fehlgeschlagen'),
  });

  // ── Wiederkehrend mutations ──
  const canManage = hasPermission('buchhaltung:manage_accounts');

  const createWiederkehrendMut = useMutation({
    mutationFn: buchhaltungApi.createWiederkehrend,
    onSuccess: () => { qc.invalidateQueries({ queryKey: ['buchhaltung-wiederkehrend'] }); setWiederkehrendDialog({ open: false }); showSuccess('Wiederkehrende Buchung erstellt'); },
    onError: () => showError('Erstellen fehlgeschlagen'),
  });
  const updateWiederkehrendMut = useMutation({
    mutationFn: ({ id, data }: { id: number; data: Partial<WiederkehrendFormData> }) => buchhaltungApi.updateWiederkehrend(id, data),
    onSuccess: () => { qc.invalidateQueries({ queryKey: ['buchhaltung-wiederkehrend'] }); setWiederkehrendDialog({ open: false }); showSuccess('Wiederkehrende Buchung aktualisiert'); },
    onError: () => showError('Aktualisierung fehlgeschlagen'),
  });
  const deleteWiederkehrendMut = useMutation({
    mutationFn: buchhaltungApi.deleteWiederkehrend,
    onSuccess: () => { qc.invalidateQueries({ queryKey: ['buchhaltung-wiederkehrend'] }); showSuccess('Wiederkehrende Buchung gelöscht'); },
    onError: () => showError('Löschen fehlgeschlagen'),
  });

  // ── Erstattung mutation ──
  const createErstattungMut = useMutation({
    mutationFn: buchhaltungApi.createErstattung,
    onSuccess: () => { qc.invalidateQueries({ queryKey: ['buchhaltung-transaktionen'] }); qc.invalidateQueries({ queryKey: ['buchhaltung-stats'] }); setErstattungOpen(false); showSuccess('Erstattung erstellt'); },
    onError: () => showError('Erstattung konnte nicht erstellt werden'),
  });

  // ── Transfer mutation ──
  const createTransferMut = useMutation({
    mutationFn: buchhaltungApi.createTransfer,
    onSuccess: () => { qc.invalidateQueries({ queryKey: ['buchhaltung-transaktionen'] }); qc.invalidateQueries({ queryKey: ['buchhaltung-stats'] }); setTransferOpen(false); showSuccess('Transfer erstellt'); },
    onError: () => showError('Transfer konnte nicht erstellt werden'),
  });

  const handleExportCsv = async () => {
    if (!filters.haushaltsjahr_id) { showError('Bitte ein Haushaltsjahr auswählen'); return; }
    try {
      const blob = await buchhaltungApi.exportCsv(filters.haushaltsjahr_id);
      const url = URL.createObjectURL(blob);
      const a = document.createElement('a');
      a.href = url;
      a.download = `transaktionen_${filters.haushaltsjahr_id}.csv`;
      a.click();
      URL.revokeObjectURL(url);
    } catch {
      showError('Export fehlgeschlagen');
    }
  };

  useEffect(() => {
    setFilters(f => ({ ...f, haushaltsjahr_id: selectedJahrId || undefined }));
  }, [selectedJahrId]);

  const filteredTransaktionen = filterAusgabenTyp
    ? transaktionen.filter(t => t.ausgaben_typ === filterAusgabenTyp)
    : transaktionen;

  const [sortCol, setSortCol] = useState<'nr' | 'datum' | 'betrag'>('nr');
  const [sortDir, setSortDir] = useState<'asc' | 'desc'>('asc');

  const handleSort = (col: 'nr' | 'datum' | 'betrag') => {
    if (sortCol === col) setSortDir(d => d === 'asc' ? 'desc' : 'asc');
    else { setSortCol(col); setSortDir('asc'); }
  };

  const sortedTransaktionen = [...filteredTransaktionen].sort((a, b) => {
    let cmp = 0;
    if (sortCol === 'nr') cmp = (a.laufende_nummer ?? 0) - (b.laufende_nummer ?? 0);
    else if (sortCol === 'datum') cmp = new Date(a.datum).getTime() - new Date(b.datum).getTime();
    else if (sortCol === 'betrag') cmp = Number(a.betrag) - Number(b.betrag);
    return sortDir === 'asc' ? cmp : -cmp;
  });

  const subTabTransaktionen = sortedTransaktionen.filter(t => {
    if (txSubTab === 0) return t.status === 'entwurf';
    if (txSubTab === 1) return t.status === 'gebucht';
    return false;
  });

  return (
    <Box>
      <Box sx={{ borderBottom: 1, borderColor: 'divider', mb: 2 }}>
        <Tabs value={txSubTab} onChange={(_, v) => setTxSubTab(v)}>
          <Tab label="Offene Buchungen" />
          <Tab label="Buchungen" />
          <Tab label="Wiederkehrende Buchungen" />
        </Tabs>
      </Box>

      {(txSubTab === 0 || txSubTab === 1) && (
        <Box>
      {/* Filters */}
      <Paper variant="outlined" sx={{ p: 1.5, mb: 2 }}>
        <Box sx={{ display: 'flex', gap: 1, flexWrap: 'wrap', alignItems: 'center' }}>
          <FormControl size="small" sx={{ minWidth: 200 }}>
            <InputLabel>Haushaltsjahr</InputLabel>
            <Select size="small" value={filters.haushaltsjahr_id ?? ''} label="Haushaltsjahr"
              onChange={e => { const v = Number(e.target.value); setFilters(f => ({ ...f, haushaltsjahr_id: v || undefined })); onJahrChange(v); }}>
              <MenuItem value=""><em>Alle</em></MenuItem>
              {haushaltsjahre.map(hj => <MenuItem key={hj.id} value={hj.id}>{hj.bezeichnung}</MenuItem>)}
            </Select>
          </FormControl>
          <FormControl size="small" sx={{ minWidth: 130 }}>
            <InputLabel>Typ</InputLabel>
            <Select size="small" value={filters.typ ?? ''} label="Typ"
              onChange={e => setFilters(f => ({ ...f, typ: (e.target.value as TransaktionTyp) || undefined }))}>
              <MenuItem value=""><em>Alle</em></MenuItem>
              <MenuItem value="einnahme">Einnahme</MenuItem>
              <MenuItem value="ausgabe">Ausgabe</MenuItem>
              <MenuItem value="transfer">Transfer</MenuItem>
            </Select>
          </FormControl>
          <TextField size="small" label="Suche" value={filters.search ?? ''}
            onChange={e => setFilters(f => ({ ...f, search: e.target.value || undefined }))} sx={{ minWidth: 180 }} />
          <FormControl size="small" sx={{ minWidth: 160 }}>
            <InputLabel>Ausgaben-Typ</InputLabel>
            <Select
              value={filterAusgabenTyp}
              onChange={e => setFilterAusgabenTyp(e.target.value)}
              label="Ausgaben-Typ"
            >
              <MenuItem value="">Alle</MenuItem>
              <MenuItem value="gwg">GWG</MenuItem>
              <MenuItem value="anlagen">Anlagen</MenuItem>
              <MenuItem value="instandhaltung">Instandhaltung</MenuItem>
            </Select>
          </FormControl>
          {hasPermission('buchhaltung:export') && (
            <Tooltip title="CSV exportieren">
              <IconButton size="small" onClick={handleExportCsv} disabled={!filters.haushaltsjahr_id}>
                <Download fontSize="small" />
              </IconButton>
            </Tooltip>
          )}
          {hasPermission('buchhaltung:create') && (
            <Button size="small" variant="outlined" onClick={() => setErstattungOpen(true)}>
              Erstattung erfassen
            </Button>
          )}
          {hasPermission('buchhaltung:create') && (
            <Button size="small" variant="outlined" startIcon={<SwapHoriz />} onClick={() => setTransferOpen(true)}>
              Transfer
            </Button>
          )}
        </Box>
      </Paper>

      {isLoading ? <CircularProgress /> : (
        <TableContainer component={Paper}>
          <Table size="small">
            <TableHead>
              <TableRow>
                <TableCell sortDirection={sortCol === 'nr' ? sortDir : false}>
                  <TableSortLabel active={sortCol === 'nr'} direction={sortCol === 'nr' ? sortDir : 'asc'} onClick={() => handleSort('nr')}>
                    Nr.
                  </TableSortLabel>
                </TableCell>
                <TableCell sortDirection={sortCol === 'datum' ? sortDir : false}>
                  <TableSortLabel active={sortCol === 'datum'} direction={sortCol === 'datum' ? sortDir : 'asc'} onClick={() => handleSort('datum')}>
                    Datum
                  </TableSortLabel>
                </TableCell>
                <TableCell>Typ</TableCell>
                <TableCell>Beschreibung</TableCell>
                <TableCell>Konto</TableCell>
                <TableCell align="right" sortDirection={sortCol === 'betrag' ? sortDir : false}>
                  <TableSortLabel active={sortCol === 'betrag'} direction={sortCol === 'betrag' ? sortDir : 'asc'} onClick={() => handleSort('betrag')}>
                    Betrag
                  </TableSortLabel>
                </TableCell>
                <TableCell>Aktionen</TableCell>
              </TableRow>
            </TableHead>
            <TableBody>
              {subTabTransaktionen.length === 0 && (
                <TableRow><TableCell colSpan={7} align="center"><Typography color="text.secondary">Keine Transaktionen</Typography></TableCell></TableRow>
              )}
              {subTabTransaktionen.map((t: Transaktion) => (
                <TableRow key={t.id} hover>
                  <TableCell>{t.laufende_nummer != null ? `${t.haushaltsjahr_jahr}/${t.laufende_nummer}` : `E${t.id}`}</TableCell>
                  <TableCell>{fmtDate(t.datum)}</TableCell>
                  <TableCell>
                    <Chip
                      label={t.typ === 'transfer' ? `Transfer${t.transfer_ziel_bezeichnung ? ' \u2192 ' + t.transfer_ziel_bezeichnung : ''}` : TRANSAKTION_TYP_LABELS[t.typ]}
                      size="small"
                      color={t.typ === 'einnahme' ? 'success' : t.typ === 'transfer' ? 'info' : 'error'}
                    />
                  </TableCell>
                  <TableCell>
                    <Box sx={{ display: 'flex', alignItems: 'center', gap: 0.5, flexWrap: 'wrap' }}>
                      <span>{t.beschreibung || t.empfaenger_auftraggeber || '–'}</span>
                      {t.bestellung_id && (
                        <Chip label={`Best. #${t.bestellung_id}`} size="small" variant="outlined" color="info" sx={{ fontSize: '0.7rem' }} />
                      )}
                    </Box>
                  </TableCell>
                  <TableCell>{t.konto_kontonummer ? `${t.konto_kontonummer} ${t.konto_bezeichnung}` : '–'}</TableCell>
                  <TableCell align="right" sx={{ color: t.typ === 'einnahme' ? 'success.main' : t.typ === 'transfer' ? 'info.main' : 'error.main', fontWeight: 600 }}>
                    {t.typ === 'ausgabe' ? '-' : t.typ === 'einnahme' ? '+' : ''}{fmtEur(t.betrag)}
                  </TableCell>
                  <TableCell>
                    <Stack direction="row" spacing={0.5} flexWrap="wrap">
                      {t.status === 'entwurf' && hasPermission('buchhaltung:edit') && (() => {
                        const buchenDisabled =
                          kontenFlat.length === 0 || bankkonten.length === 0 ||
                          !t.konto_id || !t.bankkonto_id || !Number(t.betrag) || !t.datum || !t.beschreibung;
                        const buchenTooltip =
                          kontenFlat.length === 0 ? 'Keine Konten konfiguriert' :
                          bankkonten.length === 0 ? 'Keine Bankkonten konfiguriert' :
                          !t.konto_id ? 'Kein Konto ausgewählt' :
                          !t.bankkonto_id ? 'Kein Bankkonto ausgewählt' :
                          !Number(t.betrag) ? 'Kein Betrag angegeben' :
                          !t.datum ? 'Kein Datum angegeben' :
                          !t.beschreibung ? 'Keine Beschreibung angegeben' : '';
                        return (
                          <Tooltip title={buchenTooltip}>
                            <span>
                              <Button size="small" variant="outlined" startIcon={<BookmarkAdd fontSize="small" />} disabled={buchenDisabled} onClick={() => buchenMut.mutate(t.id)}>
                                Buchen
                              </Button>
                            </span>
                          </Tooltip>
                        );
                      })()}
                      {t.status === 'gebucht' && hasPermission('buchhaltung:edit') && (
                        <Button size="small" variant="outlined" color="warning" startIcon={<Cancel fontSize="small" />} onClick={() => stornoMut.mutate(t.id)}>
                          Stornieren
                        </Button>
                      )}
                      {t.status === 'entwurf' && hasPermission('buchhaltung:edit') && (
                        <Tooltip title="Bearbeiten">
                          <IconButton size="small" onClick={() => navigate(`/buchhaltung/transaktionen/${t.id}/bearbeiten`)}>
                            <Edit fontSize="small" />
                          </IconButton>
                        </Tooltip>
                      )}
                      {t.status === 'entwurf' && hasPermission('buchhaltung:delete') && (
                        <Tooltip title="Löschen">
                          <IconButton size="small" color="error" onClick={() => deleteMut.mutate(t.id)}>
                            <Delete fontSize="small" />
                          </IconButton>
                        </Tooltip>
                      )}
                    </Stack>
                  </TableCell>
                </TableRow>
              ))}
            </TableBody>
          </Table>
        </TableContainer>
      )}

      {hasPermission('buchhaltung:create') && (
        <ChatAwareFab color="primary" onClick={() => navigate(`/buchhaltung/transaktionen/neu${filters.haushaltsjahr_id ? `?jahr=${filters.haushaltsjahr_id}` : ''}`)}>
          <AddIcon />
        </ChatAwareFab>
      )}

      <ErstattungDialog
        open={erstattungOpen}
        onClose={() => setErstattungOpen(false)}
        konten={kontenFlat}
        bankkonten={bankkonten}
        transaktionen={transaktionen}
        onSave={data => createErstattungMut.mutate(data)}
      />

      <TransferDialog
        open={transferOpen}
        onClose={() => setTransferOpen(false)}
        haushaltsjahre={haushaltsjahre}
        selectedJahrId={selectedJahrId}
        bankkonten={bankkonten}
        onSave={data => createTransferMut.mutate(data)}
      />
        </Box>
      )}

      {txSubTab === 2 && (
        <Box>
          <Box sx={{ mb: 2, display: 'flex', justifyContent: 'flex-end' }}>
            {canManage && <Button variant="contained" startIcon={<AddIcon />} onClick={() => setWiederkehrendDialog({ open: true })}>Anlegen</Button>}
          </Box>
          <TableContainer component={Paper}>
            <Table size="small">
              <TableHead>
                <TableRow>
                  <TableCell>Bezeichnung</TableCell>
                  <TableCell>Typ</TableCell>
                  <TableCell align="right">Betrag</TableCell>
                  <TableCell>Intervall</TableCell>
                  <TableCell>Nächste Ausführung</TableCell>
                  <TableCell>Aktiv</TableCell>
                  {canManage && <TableCell>Aktionen</TableCell>}
                </TableRow>
              </TableHead>
              <TableBody>
                {wiederkehrend.length === 0 && <TableRow><TableCell colSpan={7} align="center"><Typography color="text.secondary">Keine wiederkehrenden Buchungen</Typography></TableCell></TableRow>}
                {wiederkehrend.map((w: WiederkehrendBuchung) => (
                  <TableRow key={w.id} hover>
                    <TableCell>{w.bezeichnung}</TableCell>
                    <TableCell>
                      <Chip label={TRANSAKTION_TYP_LABELS[w.typ]} size="small" color={w.typ === 'einnahme' ? 'success' : 'error'} />
                    </TableCell>
                    <TableCell align="right" sx={{ color: w.typ === 'einnahme' ? 'success.main' : 'error.main', fontWeight: 600 }}>
                      {w.typ === 'ausgabe' ? '-' : '+'}{fmtEur(w.betrag)}
                    </TableCell>
                    <TableCell>{INTERVALL_LABELS[w.intervall]}</TableCell>
                    <TableCell>{fmtDate(w.naechste_ausfuehrung)}</TableCell>
                    <TableCell>{w.aktiv ? <Chip label="Aktiv" size="small" color="success" /> : <Chip label="Inaktiv" size="small" color="default" />}</TableCell>
                    {canManage && (
                      <TableCell>
                        <IconButton size="small" onClick={() => setWiederkehrendDialog({ open: true, existing: w })}><Edit fontSize="small" /></IconButton>
                        <IconButton size="small" color="error" onClick={() => deleteWiederkehrendMut.mutate(w.id)}><Delete fontSize="small" /></IconButton>
                      </TableCell>
                    )}
                  </TableRow>
                ))}
              </TableBody>
            </Table>
          </TableContainer>
          <WiederkehrendDialog
            open={wiederkehrendDialog.open}
            onClose={() => setWiederkehrendDialog({ open: false })}
            konten={kontenFlat}
            bankkonten={bankkonten}
            existing={wiederkehrendDialog.existing}
            onSave={data => wiederkehrendDialog.existing
              ? updateWiederkehrendMut.mutate({ id: wiederkehrendDialog.existing.id, data })
              : createWiederkehrendMut.mutate(data)
            }
          />
        </Box>
      )}
    </Box>
  );
}

// ─── Tab 2: Konten ────────────────────────────────────────────────────────────

function WiederkehrendDialog({
  open,
  onClose,
  konten,
  bankkonten,
  existing,
  onSave,
}: {
  open: boolean;
  onClose: () => void;
  konten: Konto[];
  bankkonten: Bankkonto[];
  existing?: WiederkehrendBuchung;
  onSave: (data: WiederkehrendFormData) => void;
}) {
  const today = new Date().toISOString().slice(0, 10);
  const empty: WiederkehrendFormData = {
    bezeichnung: '',
    konto_id: null,
    bankkonto_id: null,
    typ: 'ausgabe',
    betrag: 0,
    beschreibung: '',
    empfaenger_auftraggeber: '',
    intervall: 'monatlich',
    naechste_ausfuehrung: today,
    ausfuehrungstag: 'erster',
    aktiv: true,
  };
  const [form, setForm] = useState<WiederkehrendFormData>(empty);

  useEffect(() => {
    if (existing) {
      setForm({
        bezeichnung: existing.bezeichnung,
        konto_id: existing.konto_id,
        bankkonto_id: existing.bankkonto_id,
        typ: existing.typ,
        betrag: existing.betrag,
        beschreibung: existing.beschreibung || '',
        empfaenger_auftraggeber: existing.empfaenger_auftraggeber || '',
        intervall: existing.intervall,
        naechste_ausfuehrung: existing.naechste_ausfuehrung.slice(0, 10),
        ausfuehrungstag: existing.ausfuehrungstag || 'erster',
        ausfuehrungs_monat: existing.ausfuehrungs_monat ?? undefined,
        aktiv: existing.aktiv,
      });
    } else {
      setForm(empty);
    }
  // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [existing, open]);

  return (
    <Dialog open={open} onClose={onClose} maxWidth="sm" fullWidth>
      <DialogTitle>{existing ? 'Wiederkehrende Buchung bearbeiten' : 'Wiederkehrende Buchung anlegen'}</DialogTitle>
      <DialogContent>
        <Stack spacing={2} sx={{ mt: 1 }}>
          <TextField label="Bezeichnung" value={form.bezeichnung} onChange={e => setForm(f => ({ ...f, bezeichnung: e.target.value }))} required />
          <FormControl fullWidth required>
            <InputLabel>Typ</InputLabel>
            <Select value={form.typ} label="Typ" onChange={e => setForm(f => ({ ...f, typ: e.target.value as 'einnahme' | 'ausgabe' }))}>
              <MenuItem value="ausgabe">Ausgabe</MenuItem>
              <MenuItem value="einnahme">Einnahme</MenuItem>
            </Select>
          </FormControl>
          <TextField label="Betrag (€)" type="number" value={form.betrag} onChange={e => setForm(f => ({ ...f, betrag: parseFloat(e.target.value) || 0 }))} inputProps={{ step: '0.01', min: '0' }} required />
          <FormControl fullWidth required>
            <InputLabel>Intervall</InputLabel>
            <Select value={form.intervall} label="Intervall" onChange={e => setForm(f => ({ ...f, intervall: e.target.value as WiederkehrendIntervall }))}>
              {(Object.entries(INTERVALL_LABELS) as [WiederkehrendIntervall, string][]).map(([v, l]) => <MenuItem key={v} value={v}>{l}</MenuItem>)}
            </Select>
          </FormControl>
          <FormControl fullWidth>
            <InputLabel>Ausführungstag</InputLabel>
            <Select value={form.ausfuehrungstag ?? 'erster'} label="Ausführungstag" onChange={e => setForm(f => ({ ...f, ausfuehrungstag: e.target.value as 'erster' | 'mitte' | 'letzter' }))}>
              <MenuItem value="erster">Erster des Monats</MenuItem>
              <MenuItem value="mitte">Mitte des Monats (15.)</MenuItem>
              <MenuItem value="letzter">Letzter des Monats</MenuItem>
            </Select>
          </FormControl>
          {form.intervall === 'jaehrlich' && (
            <FormControl fullWidth>
              <InputLabel>Ausführungsmonat</InputLabel>
              <Select value={form.ausfuehrungs_monat ?? ''} label="Ausführungsmonat" onChange={e => setForm(f => ({ ...f, ausfuehrungs_monat: e.target.value ? Number(e.target.value) : undefined }))}>
                <MenuItem value=""><em>Nicht festgelegt</em></MenuItem>
                {['Januar','Februar','März','April','Mai','Juni','Juli','August','September','Oktober','November','Dezember'].map((m, i) => (
                  <MenuItem key={i + 1} value={i + 1}>{m}</MenuItem>
                ))}
              </Select>
            </FormControl>
          )}
          <TextField label="Nächste Ausführung" type="date" value={form.naechste_ausfuehrung} onChange={e => setForm(f => ({ ...f, naechste_ausfuehrung: e.target.value }))} InputLabelProps={{ shrink: true }} required />
          <FormControl fullWidth>
            <InputLabel>Konto</InputLabel>
            <Select value={form.konto_id ?? ''} label="Konto" onChange={e => setForm(f => ({ ...f, konto_id: e.target.value ? Number(e.target.value) : null }))}>
              <MenuItem value=""><em>Kein Konto</em></MenuItem>
              {konten.map(k => <MenuItem key={k.id} value={k.id}>{k.kontonummer} – {k.bezeichnung}</MenuItem>)}
            </Select>
          </FormControl>
          <FormControl fullWidth>
            <InputLabel>Bankkonto</InputLabel>
            <Select value={form.bankkonto_id ?? ''} label="Bankkonto" onChange={e => setForm(f => ({ ...f, bankkonto_id: e.target.value ? Number(e.target.value) : null }))}>
              <MenuItem value=""><em>Kein Bankkonto</em></MenuItem>
              {bankkonten.map(bk => <MenuItem key={bk.id} value={bk.id}>{bk.bezeichnung}</MenuItem>)}
            </Select>
          </FormControl>
          <TextField label="Beschreibung" value={form.beschreibung} onChange={e => setForm(f => ({ ...f, beschreibung: e.target.value }))} />
          <TextField label="Empfänger/Auftraggeber" value={form.empfaenger_auftraggeber} onChange={e => setForm(f => ({ ...f, empfaenger_auftraggeber: e.target.value }))} />
          <FormControlLabel
            control={<Switch checked={form.aktiv !== false} onChange={e => setForm(f => ({ ...f, aktiv: e.target.checked }))} />}
            label="Aktiv"
          />
        </Stack>
      </DialogContent>
      <DialogActions>
        <Button onClick={onClose}>Abbrechen</Button>
        <Button variant="contained" onClick={() => onSave(form)} disabled={!form.bezeichnung || !form.betrag || !form.naechste_ausfuehrung}>Speichern</Button>
      </DialogActions>
    </Dialog>
  );
}

function KontenTab({ haushaltsjahre, selectedJahrId, onJahrChange }: {
  haushaltsjahre: Haushaltsjahr[];
  selectedJahrId: number | null;
  onJahrChange: (id: number) => void;
}) {
  const qc = useQueryClient();
  const navigate = useNavigate();
  const { showSuccess, showError } = useNotification();
  const { hasPermission } = usePermissionContext();
  const [subTab, setSubTab] = useState(0);
  const [kontoDialog, setKontoDialog] = useState<{ open: boolean; existing?: Konto }>({ open: false });
  const [kontoSaveError, setKontoSaveError] = useState<string | null>(null);
  const [bankDialog, setBankDialog] = useState<{ open: boolean; existing?: Bankkonto }>({ open: false });
  const [jahrDialog, setJahrDialog] = useState<{ open: boolean; existing?: Haushaltsjahr }>({ open: false });

  const { data: kontenFlat = [] } = useQuery({
    queryKey: ['buchhaltung-konten', selectedJahrId],
    queryFn: () => buchhaltungApi.getKonten(selectedJahrId!),
    enabled: selectedJahrId != null,
  });
  const { data: kontenTreeData = [] } = useQuery({
    queryKey: ['kontenTree', selectedJahrId],
    queryFn: () => buchhaltungApi.getKontenTree(selectedJahrId!),
    enabled: selectedJahrId != null,
  });
  const kontenTree = buildTree(kontenTreeData);
  const konten = kontenFlat;
  const { data: bankkonten = [] } = useQuery({ queryKey: ['bankkonten'], queryFn: buchhaltungApi.getBankkonten });
  const { data: kategorien = [] } = useQuery({
    queryKey: ['buchhaltung-kategorien', selectedJahrId],
    queryFn: () => buchhaltungApi.getKategorien(selectedJahrId!),
    enabled: selectedJahrId != null,
  });

  const [newKategorie, setNewKategorie] = useState('');
  const [addingKategorie, setAddingKategorie] = useState(false);

  // ── Einstellungen state ────────────────────────────────────────────────────
  const [kontoTypDialog, setKontoTypDialog] = useState<{ open: boolean; existing?: KontoTyp }>({ open: false });
  const [kontoTypForm, setKontoTypForm] = useState<{ bezeichnung: string; art: string; sort_order: number }>({ bezeichnung: '', art: 'ausgabe', sort_order: 0 });
  const [alertThreshold, setAlertThreshold] = useState<string>('80');

  const { data: kontoTypen = [] } = useQuery({ queryKey: ['konto-typen'], queryFn: buchhaltungApi.getKontoTypen });
  const { data: einstellungen } = useQuery({
    queryKey: ['buchhaltung-einstellungen'],
    queryFn: buchhaltungApi.getEinstellungen,
    enabled: hasPermission('buchhaltung:manage_settings'),
  });

  useEffect(() => {
    if (einstellungen?.default_alert_threshold) {
      setAlertThreshold(String(einstellungen.default_alert_threshold));
    }
  }, [einstellungen]);

  const createKontoTypMut = useMutation({
    mutationFn: buchhaltungApi.createKontoTyp,
    onSuccess: () => { qc.invalidateQueries({ queryKey: ['konto-typen'] }); setKontoTypDialog({ open: false }); showSuccess('Konto-Typ erstellt'); },
    onError: () => showError('Konto-Typ konnte nicht erstellt werden'),
  });
  const updateKontoTypMut = useMutation({
    mutationFn: ({ id, data }: { id: number; data: Partial<{ bezeichnung: string; art: string; sort_order: number }> }) => buchhaltungApi.updateKontoTyp(id, data),
    onSuccess: () => { qc.invalidateQueries({ queryKey: ['konto-typen'] }); setKontoTypDialog({ open: false }); showSuccess('Konto-Typ aktualisiert'); },
    onError: () => showError('Konto-Typ konnte nicht aktualisiert werden'),
  });
  const deleteKontoTypMut = useMutation({
    mutationFn: buchhaltungApi.deleteKontoTyp,
    onSuccess: () => { qc.invalidateQueries({ queryKey: ['konto-typen'] }); showSuccess('Konto-Typ gelöscht'); },
    onError: (err: any) => showError(err?.response?.data?.message || 'Konto-Typ konnte nicht gelöscht werden'),
  });
  const saveEinstellungenMut = useMutation({
    mutationFn: buchhaltungApi.setEinstellungen,
    onSuccess: () => { qc.invalidateQueries({ queryKey: ['buchhaltung-einstellungen'] }); showSuccess('Einstellungen gespeichert'); },
    onError: () => showError('Einstellungen konnten nicht gespeichert werden'),
  });

  const createKategorieMut = useMutation({
    mutationFn: buchhaltungApi.createKategorie,
    onSuccess: () => { qc.invalidateQueries({ queryKey: ['buchhaltung-kategorien'] }); setNewKategorie(''); setAddingKategorie(false); showSuccess('Kategorie erstellt'); },
    onError: () => showError('Kategorie konnte nicht erstellt werden'),
  });
  const deleteKategorieMut = useMutation({
    mutationFn: buchhaltungApi.deleteKategorie,
    onSuccess: () => { qc.invalidateQueries({ queryKey: ['buchhaltung-kategorien'] }); qc.invalidateQueries({ queryKey: ['kontenTree'] }); showSuccess('Kategorie gelöscht'); },
    onError: () => showError('Kategorie konnte nicht gelöscht werden'),
  });

  const canManage = hasPermission('buchhaltung:manage_accounts');

  const createKontoMut = useMutation({
    mutationFn: buchhaltungApi.createKonto,
    onSuccess: () => { qc.invalidateQueries({ queryKey: ['buchhaltung-konten'] }); qc.invalidateQueries({ queryKey: ['kontenTree'] }); setKontoDialog({ open: false }); setKontoSaveError(null); showSuccess('Konto erstellt'); },
    onError: (err: any) => {
      const msg = err?.response?.data?.message || err?.message || 'Konto konnte nicht erstellt werden';
      if (err?.response?.status === 400) { setKontoSaveError(msg); } else { showError(msg); }
    },
  });
  const updateKontoMut = useMutation({
    mutationFn: ({ id, data }: { id: number; data: Partial<KontoFormData> }) => buchhaltungApi.updateKonto(id, data),
    onSuccess: () => { qc.invalidateQueries({ queryKey: ['buchhaltung-konten'] }); qc.invalidateQueries({ queryKey: ['kontenTree'] }); setKontoDialog({ open: false }); setKontoSaveError(null); showSuccess('Konto aktualisiert'); },
    onError: (err: any) => {
      const msg = err?.response?.data?.message || err?.message || 'Konto konnte nicht aktualisiert werden';
      if (err?.response?.status === 400) { setKontoSaveError(msg); } else { showError(msg); }
    },
  });
  const createBankMut = useMutation({
    mutationFn: buchhaltungApi.createBankkonto,
    onSuccess: () => { qc.invalidateQueries({ queryKey: ['bankkonten'] }); setBankDialog({ open: false }); showSuccess('Bankkonto erstellt'); },
    onError: () => showError('Bankkonto konnte nicht erstellt werden'),
  });
  const updateBankMut = useMutation({
    mutationFn: ({ id, data }: { id: number; data: Partial<BankkontoFormData> }) => buchhaltungApi.updateBankkonto(id, data),
    onSuccess: () => { qc.invalidateQueries({ queryKey: ['bankkonten'] }); setBankDialog({ open: false }); showSuccess('Bankkonto aktualisiert'); },
    onError: () => showError('Bankkonto konnte nicht aktualisiert werden'),
  });
  const deleteBankMut = useMutation({
    mutationFn: buchhaltungApi.deleteBankkonto,
    onSuccess: () => { qc.invalidateQueries({ queryKey: ['bankkonten'] }); showSuccess('Bankkonto deaktiviert'); },
    onError: () => showError('Löschen fehlgeschlagen'),
  });

  const createJahrMut = useMutation({
    mutationFn: buchhaltungApi.createHaushaltsjahr,
    onSuccess: (hj) => { qc.invalidateQueries({ queryKey: ['haushaltsjahre'] }); setJahrDialog({ open: false }); onJahrChange(hj.id); showSuccess('Haushaltsjahr erstellt'); },
    onError: () => showError('Haushaltsjahr konnte nicht erstellt werden'),
  });
  const updateJahrMut = useMutation({
    mutationFn: ({ id, data }: { id: number; data: Partial<HaushaltsjahrFormData> }) => buchhaltungApi.updateHaushaltsjahr(id, data),
    onSuccess: () => { qc.invalidateQueries({ queryKey: ['haushaltsjahre'] }); setJahrDialog({ open: false }); showSuccess('Haushaltsjahr aktualisiert'); },
    onError: () => showError('Aktualisierung fehlgeschlagen'),
  });
  const closeJahrMut = useMutation({
    mutationFn: (id: number) => buchhaltungApi.closeHaushaltsjahr(id),
    onSuccess: () => { qc.invalidateQueries({ queryKey: ['haushaltsjahre'] }); showSuccess('Haushaltsjahr abgeschlossen'); },
    onError: (e: Error) => showError(e.message || 'Abschluss fehlgeschlagen'),
  });

  return (
    <Box>
      <Box sx={{ borderBottom: 1, borderColor: 'divider', mb: 2 }}>
        <Tabs value={subTab} onChange={(_, v) => setSubTab(v)}>
          <Tab label="Konten" />
          <Tab label="Bankkonten" />
          <Tab label="Haushaltsjahre" />
          {hasPermission('buchhaltung:manage_settings') && <Tab label="Einstellungen" />}
        </Tabs>
      </Box>

      {/* Sub-Tab 0: Konten */}
      {subTab === 0 && (
        <Box>
          <Box sx={{ mb: 2, display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}>
            <FormControl sx={{ minWidth: 240 }}>
              <InputLabel>Haushaltsjahr</InputLabel>
              <Select size="small" value={selectedJahrId ?? ''} label="Haushaltsjahr" onChange={e => onJahrChange(Number(e.target.value))}>
                {haushaltsjahre.map(hj => <MenuItem key={hj.id} value={hj.id}>{hj.bezeichnung}</MenuItem>)}
              </Select>
            </FormControl>
            {canManage && <Button variant="contained" startIcon={<AddIcon />} disabled={!selectedJahrId} onClick={() => setKontoDialog({ open: true })}>Konto anlegen</Button>}
          </Box>
          {selectedJahrId && canManage && (
            <Box sx={{ mb: 2, display: 'flex', gap: 1, flexWrap: 'wrap', alignItems: 'center' }}>
              {kategorien.map(kat => (
                <Chip key={kat.id} label={kat.bezeichnung} onDelete={() => deleteKategorieMut.mutate(kat.id)} size="small" />
              ))}
              {addingKategorie ? (
                <TextField
                  size="small"
                  placeholder="Name..."
                  value={newKategorie}
                  onChange={e => setNewKategorie(e.target.value)}
                  onKeyDown={e => {
                    if (e.key === 'Enter' && newKategorie.trim() && selectedJahrId) {
                      createKategorieMut.mutate({ haushaltsjahr_id: selectedJahrId, bezeichnung: newKategorie.trim() });
                    } else if (e.key === 'Escape') {
                      setAddingKategorie(false); setNewKategorie('');
                    }
                  }}
                  onBlur={() => { setAddingKategorie(false); setNewKategorie(''); }}
                  autoFocus
                  sx={{ width: 160 }}
                />
              ) : (
                <Chip label="+ Kategorie" variant="outlined" size="small" onClick={() => setAddingKategorie(true)} />
              )}
            </Box>
          )}
          {(() => {
            const grouped = new Map<number | null, KontoTreeNode[]>();
            kontenTree.forEach(k => {
              const key = k.kategorie_id ?? null;
              if (!grouped.has(key)) grouped.set(key, []);
              grouped.get(key)!.push(k);
            });
            const categoryOrder = kategorien.map(kat => kat.id);
            const sortedKeys = [...grouped.keys()].sort((a, b) => {
              if (a === null) return 1;
              if (b === null) return -1;
              return categoryOrder.indexOf(a) - categoryOrder.indexOf(b);
            });
            return sortedKeys.map(key => {
              const katName = key !== null ? kategorien.find(k => k.id === key)?.bezeichnung : 'Ohne Kategorie';
              const items = grouped.get(key)!;
              return (
                <Box key={key ?? 'none'} sx={{ mb: 2 }}>
                  {(sortedKeys.length > 1 || key !== null) && (
                    <Typography variant="subtitle2" color="text.secondary" sx={{ mb: 0.5 }}>{katName}</Typography>
                  )}
                  <TableContainer component={Paper}>
                    <Table size="small">
                      <TableHead>
                        <TableRow>
                          <TableCell>Konto</TableCell>
                          <TableCell align="right">GWG</TableCell>
                          <TableCell align="right">Anlagen</TableCell>
                          <TableCell align="right">Instandh.</TableCell>
                          <TableCell align="right">Gesamt</TableCell>
                          <TableCell sx={{ width: 40 }} />
                        </TableRow>
                      </TableHead>
                      <TableBody>
                        {items.map(k => (
                          <KontoManageRow
                            key={k.id}
                            konto={k}
                            onNavigate={(id) => navigate('/buchhaltung/konto/' + id + '/verwalten')}
                          />
                        ))}
                      </TableBody>
                    </Table>
                  </TableContainer>
                </Box>
              );
            });
          })()}
          {kontenTree.length === 0 && selectedJahrId && (
            <Paper><Box sx={{ p: 2, textAlign: 'center' }}><Typography color="text.secondary">Keine Konten</Typography></Box></Paper>
          )}
          {selectedJahrId && <KontoDialog
            open={kontoDialog.open}
            onClose={() => { setKontoDialog({ open: false }); setKontoSaveError(null); }}
            haushaltsjahrId={selectedJahrId}
            existing={kontoDialog.existing}
            konten={konten}
            kategorien={kategorien}
            externalError={kontoSaveError}
            onSave={data => kontoDialog.existing
              ? updateKontoMut.mutate({ id: kontoDialog.existing.id, data })
              : createKontoMut.mutate(data)
            }
          />}
        </Box>
      )}

      {/* Sub-Tab 1: Bankkonten */}
      {subTab === 1 && (
        <Box>
          <Box sx={{ mb: 2, display: 'flex', justifyContent: 'flex-end' }}>
            {canManage && <Button variant="contained" startIcon={<AddIcon />} onClick={() => setBankDialog({ open: true })}>Bankkonto anlegen</Button>}
          </Box>
          <TableContainer component={Paper}>
            <Table size="small">
              <TableHead>
                <TableRow>
                  <TableCell>Bezeichnung</TableCell>
                  <TableCell>IBAN</TableCell>
                  <TableCell>Institut</TableCell>
                  <TableCell>Standard</TableCell>
                  {canManage && <TableCell>Aktionen</TableCell>}
                </TableRow>
              </TableHead>
              <TableBody>
                {bankkonten.length === 0 && <TableRow><TableCell colSpan={5} align="center"><Typography color="text.secondary">Keine Bankkonten</Typography></TableCell></TableRow>}
                {bankkonten.map((bk: Bankkonto) => (
                  <TableRow key={bk.id} hover onClick={() => navigate(`/buchhaltung/bankkonto/${bk.id}`)} sx={{ cursor: 'pointer' }}>
                    <TableCell>{bk.bezeichnung}</TableCell>
                    <TableCell>{bk.iban || '–'}</TableCell>
                    <TableCell>{bk.institut || '–'}</TableCell>
                    <TableCell>{bk.ist_standard ? <Chip label="Standard" size="small" color="primary" /> : '–'}</TableCell>
                    {canManage && (
                      <TableCell>
                        <IconButton size="small" onClick={() => setBankDialog({ open: true, existing: bk })}><Edit fontSize="small" /></IconButton>
                        <IconButton size="small" color="error" onClick={() => deleteBankMut.mutate(bk.id)}><Delete fontSize="small" /></IconButton>
                      </TableCell>
                    )}
                  </TableRow>
                ))}
              </TableBody>
            </Table>
          </TableContainer>
          <BankkontoDialog
            open={bankDialog.open}
            onClose={() => setBankDialog({ open: false })}
            existing={bankDialog.existing}
            onSave={data => bankDialog.existing
              ? updateBankMut.mutate({ id: bankDialog.existing.id, data })
              : createBankMut.mutate(data)
            }
          />
        </Box>
      )}

      {/* Sub-Tab 2: Haushaltsjahre */}
      {subTab === 2 && (
        <Box>
          <Box sx={{ mb: 2, display: 'flex', justifyContent: 'flex-end' }}>
            {canManage && <Button variant="contained" startIcon={<AddIcon />} onClick={() => setJahrDialog({ open: true })}>Haushaltsjahr anlegen</Button>}
          </Box>
          <TableContainer component={Paper}>
            <Table size="small">
              <TableHead>
                <TableRow>
                  <TableCell>Jahr</TableCell>
                  <TableCell>Bezeichnung</TableCell>
                  <TableCell>Beginn</TableCell>
                  <TableCell>Ende</TableCell>
                  <TableCell>Status</TableCell>
                  {canManage && <TableCell>Aktionen</TableCell>}
                </TableRow>
              </TableHead>
              <TableBody>
                {haushaltsjahre.length === 0 && <TableRow><TableCell colSpan={6} align="center"><Typography color="text.secondary">Keine Haushaltsjahre</Typography></TableCell></TableRow>}
                {haushaltsjahre.map((hj: Haushaltsjahr) => (
                  <TableRow key={hj.id} hover>
                    <TableCell>{hj.jahr}</TableCell>
                    <TableCell>{hj.bezeichnung}</TableCell>
                    <TableCell>{fmtDate(hj.beginn)}</TableCell>
                    <TableCell>{fmtDate(hj.ende)}</TableCell>
                    <TableCell>{hj.abgeschlossen ? <Chip label="Abgeschlossen" size="small" color="default" /> : <Chip label="Aktiv" size="small" color="success" />}</TableCell>
                    {canManage && (
                      <TableCell>
                        <IconButton size="small" onClick={() => setJahrDialog({ open: true, existing: hj })}><Edit fontSize="small" /></IconButton>
                        {!hj.abgeschlossen && (
                          <Tooltip title="Abschließen">
                            <IconButton size="small" color="warning" onClick={() => closeJahrMut.mutate(hj.id)}><Lock fontSize="small" /></IconButton>
                          </Tooltip>
                        )}
                      </TableCell>
                    )}
                  </TableRow>
                ))}
              </TableBody>
            </Table>
          </TableContainer>
          <HaushaltsjahrDialog
            open={jahrDialog.open}
            onClose={() => setJahrDialog({ open: false })}
            existing={jahrDialog.existing}
            onSave={data => jahrDialog.existing
              ? updateJahrMut.mutate({ id: jahrDialog.existing.id, data })
              : createJahrMut.mutate(data)
            }
          />
        </Box>
      )}

      {/* Sub-Tab 3: Einstellungen */}
      {subTab === 3 && hasPermission('buchhaltung:manage_settings') && (
        <Box>
          {/* Konto-Typen CRUD */}
          <Typography variant="h6" sx={{ mb: 2 }}>Konto-Typen</Typography>
          <Box sx={{ mb: 2, display: 'flex', justifyContent: 'flex-end' }}>
            <Button variant="contained" startIcon={<AddIcon />} onClick={() => { setKontoTypForm({ bezeichnung: '', art: 'ausgabe', sort_order: 0 }); setKontoTypDialog({ open: true }); }}>Konto-Typ anlegen</Button>
          </Box>
          <TableContainer component={Paper} sx={{ mb: 4 }}>
            <Table size="small">
              <TableHead>
                <TableRow>
                  <TableCell>Bezeichnung</TableCell>
                  <TableCell>Art</TableCell>
                  <TableCell align="right">Sortierung</TableCell>
                  <TableCell>Aktionen</TableCell>
                </TableRow>
              </TableHead>
              <TableBody>
                {kontoTypen.length === 0 && <TableRow><TableCell colSpan={4} align="center"><Typography color="text.secondary">Keine Konto-Typen</Typography></TableCell></TableRow>}
                {kontoTypen.map((kt: KontoTyp) => (
                  <TableRow key={kt.id} hover>
                    <TableCell>{kt.bezeichnung}</TableCell>
                    <TableCell>{KONTO_ART_LABELS[kt.art] || kt.art}</TableCell>
                    <TableCell align="right">{kt.sort_order}</TableCell>
                    <TableCell>
                      <IconButton size="small" onClick={() => { setKontoTypForm({ bezeichnung: kt.bezeichnung, art: kt.art, sort_order: kt.sort_order }); setKontoTypDialog({ open: true, existing: kt }); }}><Edit fontSize="small" /></IconButton>
                      <IconButton size="small" color="error" onClick={() => deleteKontoTypMut.mutate(kt.id)}><Delete fontSize="small" /></IconButton>
                    </TableCell>
                  </TableRow>
                ))}
              </TableBody>
            </Table>
          </TableContainer>

          {/* Alert-Schwellwert */}
          <Typography variant="h6" sx={{ mb: 2 }}>Budget-Warnung</Typography>
          <Paper sx={{ p: 3 }}>
            <Stack direction="row" spacing={2} alignItems="center">
              <TextField
                label="Standard-Schwellwert"
                type="number"
                value={alertThreshold}
                onChange={e => setAlertThreshold(e.target.value)}
                InputProps={{ endAdornment: <InputAdornment position="end">%</InputAdornment> }}
                helperText="Budget-Warnung wird ausgelöst, wenn die Auslastung diesen Wert erreicht"
                sx={{ width: 280 }}
              />
              <Button
                variant="contained"
                startIcon={<Save />}
                onClick={() => saveEinstellungenMut.mutate({ default_alert_threshold: alertThreshold })}
                disabled={saveEinstellungenMut.isPending}
              >
                Speichern
              </Button>
            </Stack>
          </Paper>

          {/* Konto-Typ Dialog */}
          <Dialog open={kontoTypDialog.open} onClose={() => setKontoTypDialog({ open: false })} maxWidth="sm" fullWidth>
            <DialogTitle>{kontoTypDialog.existing ? 'Konto-Typ bearbeiten' : 'Neuer Konto-Typ'}</DialogTitle>
            <DialogContent>
              <Stack spacing={2} sx={{ mt: 1 }}>
                <TextField label="Bezeichnung" value={kontoTypForm.bezeichnung} onChange={e => setKontoTypForm(f => ({ ...f, bezeichnung: e.target.value }))} required />
                <FormControl fullWidth>
                  <InputLabel>Art</InputLabel>
                  <Select value={kontoTypForm.art} label="Art" onChange={e => setKontoTypForm(f => ({ ...f, art: e.target.value }))}>
                    <MenuItem value="einnahme">Einnahmen</MenuItem>
                    <MenuItem value="ausgabe">Ausgaben</MenuItem>
                    <MenuItem value="vermoegen">Vermögen</MenuItem>
                    <MenuItem value="verbindlichkeit">Verbindlichkeiten</MenuItem>
                  </Select>
                </FormControl>
                <TextField label="Sortierung" type="number" value={kontoTypForm.sort_order} onChange={e => setKontoTypForm(f => ({ ...f, sort_order: parseInt(e.target.value, 10) || 0 }))} />
              </Stack>
            </DialogContent>
            <DialogActions>
              <Button onClick={() => setKontoTypDialog({ open: false })}>Abbrechen</Button>
              <Button variant="contained" onClick={() => {
                if (kontoTypDialog.existing) {
                  updateKontoTypMut.mutate({ id: kontoTypDialog.existing.id, data: kontoTypForm });
                } else {
                  createKontoTypMut.mutate(kontoTypForm);
                }
              }}>Speichern</Button>
            </DialogActions>
          </Dialog>
        </Box>
      )}
    </Box>
  );
}

// ─── Main Page ────────────────────────────────────────────────────────────────

export default function Buchhaltung() {
  const [searchParams, setSearchParams] = useSearchParams();
  const tabValue = parseInt(searchParams.get('tab') || '0', 10);
  const handleTabChange = (_: React.SyntheticEvent, newValue: number) => {
    setSearchParams({ tab: String(newValue) });
  };
  const [selectedJahrId, setSelectedJahrId] = useState<number | null>(null);

  const { data: haushaltsjahre = [] } = useQuery({
    queryKey: ['haushaltsjahre'],
    queryFn: buchhaltungApi.getHaushaltsjahre,
  });

  useEffect(() => {
    if (haushaltsjahre.length > 0 && !selectedJahrId) {
      const openYear = haushaltsjahre.find((hj: Haushaltsjahr) => !hj.abgeschlossen) || haushaltsjahre[0];
      setSelectedJahrId(openYear.id);
    }
  }, [haushaltsjahre]);

  return (
    <DashboardLayout>
      <Box sx={{ display: 'flex', alignItems: 'center', gap: 1, mb: 3 }}>
        <Typography variant="h4" sx={{ flexGrow: 1 }}>Buchhaltung</Typography>
      </Box>
      <Box sx={{ borderBottom: 1, borderColor: 'divider' }}>
        <Tabs value={tabValue} onChange={handleTabChange} variant="scrollable" scrollButtons="auto">
          <Tab label="Transaktionen" />
          <Tab label="Übersicht" />
          <Tab label="Konten" />
        </Tabs>
      </Box>
      <TabPanel value={tabValue} index={0}>
        <TransaktionenTab
          haushaltsjahre={haushaltsjahre}
          selectedJahrId={selectedJahrId}
          onJahrChange={setSelectedJahrId}
        />
      </TabPanel>
      <TabPanel value={tabValue} index={1}>
        <UebersichtTab
          haushaltsjahre={haushaltsjahre}
          selectedJahrId={selectedJahrId}
          onJahrChange={setSelectedJahrId}
        />
      </TabPanel>
      <TabPanel value={tabValue} index={2}>
        <KontenTab
          haushaltsjahre={haushaltsjahre}
          selectedJahrId={selectedJahrId}
          onJahrChange={setSelectedJahrId}
        />
      </TabPanel>
    </DashboardLayout>
  );
}
