import { Request, Response } from 'express';
import buchhaltungService from '../services/buchhaltung.service';
import logger from '../utils/logger';

const param = (req: Request, key: string): string => req.params[key] as string;

class BuchhaltungController {

  // ── Kategorien ──────────────────────────────────────────────────────────────

  async listKategorien(req: Request, res: Response): Promise<void> {
    const haushaltsjahrId = parseInt(req.query.haushaltsjahr_id as string, 10);
    if (isNaN(haushaltsjahrId)) { res.status(400).json({ success: false, message: 'haushaltsjahr_id erforderlich' }); return; }
    try {
      const data = await buchhaltungService.getKategorien(haushaltsjahrId);
      res.json({ success: true, data });
    } catch (error) {
      logger.error('BuchhaltungController.listKategorien', { error });
      res.status(500).json({ success: false, message: 'Kategorien konnten nicht geladen werden' });
    }
  }

  async createKategorie(req: Request, res: Response): Promise<void> {
    try {
      const data = await buchhaltungService.createKategorie(req.body);
      res.status(201).json({ success: true, data });
    } catch (error) {
      logger.error('BuchhaltungController.createKategorie', { error });
      res.status(500).json({ success: false, message: 'Kategorie konnte nicht erstellt werden' });
    }
  }

  async updateKategorie(req: Request, res: Response): Promise<void> {
    const id = parseInt(param(req, 'id'), 10);
    if (isNaN(id)) { res.status(400).json({ success: false, message: 'Ungültige ID' }); return; }
    try {
      const data = await buchhaltungService.updateKategorie(id, req.body);
      if (!data) { res.status(404).json({ success: false, message: 'Kategorie nicht gefunden' }); return; }
      res.json({ success: true, data });
    } catch (error) {
      logger.error('BuchhaltungController.updateKategorie', { error });
      res.status(500).json({ success: false, message: 'Kategorie konnte nicht aktualisiert werden' });
    }
  }

  async deleteKategorie(req: Request, res: Response): Promise<void> {
    const id = parseInt(param(req, 'id'), 10);
    if (isNaN(id)) { res.status(400).json({ success: false, message: 'Ungültige ID' }); return; }
    try {
      await buchhaltungService.deleteKategorie(id);
      res.json({ success: true });
    } catch (error) {
      logger.error('BuchhaltungController.deleteKategorie', { error });
      res.status(500).json({ success: false, message: 'Kategorie konnte nicht gelöscht werden' });
    }
  }

  // ── Haushaltsjahre ──────────────────────────────────────────────────────────

  async listHaushaltsjahre(_req: Request, res: Response): Promise<void> {
    try {
      const data = await buchhaltungService.getAllHaushaltsjahre();
      res.json({ success: true, data });
    } catch (error) {
      logger.error('BuchhaltungController.listHaushaltsjahre', { error });
      res.status(500).json({ success: false, message: 'Haushaltsjahre konnten nicht geladen werden' });
    }
  }

  async createHaushaltsjahr(req: Request, res: Response): Promise<void> {
    try {
      const data = await buchhaltungService.createHaushaltsjahr(req.body, req.user!.id);
      res.status(201).json({ success: true, data });
    } catch (error) {
      logger.error('BuchhaltungController.createHaushaltsjahr', { error });
      res.status(500).json({ success: false, message: 'Haushaltsjahr konnte nicht erstellt werden' });
    }
  }

  async updateHaushaltsjahr(req: Request, res: Response): Promise<void> {
    const id = parseInt(param(req, 'id'), 10);
    if (isNaN(id)) { res.status(400).json({ success: false, message: 'Ungültige ID' }); return; }
    try {
      const data = await buchhaltungService.updateHaushaltsjahr(id, req.body);
      if (!data) { res.status(404).json({ success: false, message: 'Haushaltsjahr nicht gefunden' }); return; }
      res.json({ success: true, data });
    } catch (error) {
      logger.error('BuchhaltungController.updateHaushaltsjahr', { error });
      res.status(500).json({ success: false, message: String(error) });
    }
  }

  async closeHaushaltsjahr(req: Request, res: Response): Promise<void> {
    const id = parseInt(param(req, 'id'), 10);
    if (isNaN(id)) { res.status(400).json({ success: false, message: 'Ungültige ID' }); return; }
    try {
      const data = await buchhaltungService.closeHaushaltsjahr(id);
      if (!data) { res.status(404).json({ success: false, message: 'Haushaltsjahr nicht gefunden' }); return; }
      res.json({ success: true, data });
    } catch (error) {
      logger.error('BuchhaltungController.closeHaushaltsjahr', { error });
      res.status(400).json({ success: false, message: String(error) });
    }
  }

  // ── Konto-Typen ─────────────────────────────────────────────────────────────

  async listKontoTypen(_req: Request, res: Response): Promise<void> {
    try {
      const data = await buchhaltungService.getAllKontoTypen();
      res.json({ success: true, data });
    } catch (error) {
      logger.error('BuchhaltungController.listKontoTypen', { error });
      res.status(500).json({ success: false, message: 'Kontotypen konnten nicht geladen werden' });
    }
  }

  async createKontoTyp(req: Request, res: Response): Promise<void> {
    try {
      const data = await buchhaltungService.createKontoTyp(req.body);
      res.status(201).json({ success: true, data });
    } catch (error) {
      logger.error('BuchhaltungController.createKontoTyp', { error });
      res.status(500).json({ success: false, message: 'Kontotyp konnte nicht erstellt werden' });
    }
  }

  async updateKontoTyp(req: Request, res: Response): Promise<void> {
    const id = parseInt(param(req, 'id'), 10);
    if (isNaN(id)) { res.status(400).json({ success: false, message: 'Ungültige ID' }); return; }
    try {
      const data = await buchhaltungService.updateKontoTyp(id, req.body);
      res.json({ success: true, data });
    } catch (error) {
      logger.error('BuchhaltungController.updateKontoTyp', { error });
      res.status(500).json({ success: false, message: 'Kontotyp konnte nicht aktualisiert werden' });
    }
  }

  async deleteKontoTyp(req: Request, res: Response): Promise<void> {
    const id = parseInt(param(req, 'id'), 10);
    if (isNaN(id)) { res.status(400).json({ success: false, message: 'Ungültige ID' }); return; }
    try {
      await buchhaltungService.deleteKontoTyp(id);
      res.json({ success: true });
    } catch (error) {
      const statusCode = (error as any).statusCode;
      if (statusCode === 409) {
        res.status(409).json({ success: false, message: (error as Error).message });
        return;
      }
      logger.error('BuchhaltungController.deleteKontoTyp', { error });
      res.status(500).json({ success: false, message: 'Kontotyp konnte nicht gelöscht werden' });
    }
  }

  // ── Bankkonten ───────────────────────────────────────────────────────────────

  async listBankkonten(_req: Request, res: Response): Promise<void> {
    try {
      const data = await buchhaltungService.getAllBankkonten();
      res.json({ success: true, data });
    } catch (error) {
      logger.error('BuchhaltungController.listBankkonten', { error });
      res.status(500).json({ success: false, message: 'Bankkonten konnten nicht geladen werden' });
    }
  }

  async createBankkonto(req: Request, res: Response): Promise<void> {
    try {
      const data = await buchhaltungService.createBankkonto(req.body, req.user!.id);
      res.status(201).json({ success: true, data });
    } catch (error) {
      logger.error('BuchhaltungController.createBankkonto', { error });
      res.status(500).json({ success: false, message: 'Bankkonto konnte nicht erstellt werden' });
    }
  }

  async updateBankkonto(req: Request, res: Response): Promise<void> {
    const id = parseInt(param(req, 'id'), 10);
    if (isNaN(id)) { res.status(400).json({ success: false, message: 'Ungültige ID' }); return; }
    try {
      const data = await buchhaltungService.updateBankkonto(id, req.body);
      if (!data) { res.status(404).json({ success: false, message: 'Bankkonto nicht gefunden' }); return; }
      res.json({ success: true, data });
    } catch (error) {
      logger.error('BuchhaltungController.updateBankkonto', { error });
      res.status(500).json({ success: false, message: 'Bankkonto konnte nicht aktualisiert werden' });
    }
  }

  async deleteBankkonto(req: Request, res: Response): Promise<void> {
    const id = parseInt(param(req, 'id'), 10);
    if (isNaN(id)) { res.status(400).json({ success: false, message: 'Ungültige ID' }); return; }
    try {
      await buchhaltungService.deactivateBankkonto(id);
      res.json({ success: true });
    } catch (error) {
      logger.error('BuchhaltungController.deleteBankkonto', { error });
      res.status(500).json({ success: false, message: 'Bankkonto konnte nicht deaktiviert werden' });
    }
  }

  async getBankkontoStatement(req: Request, res: Response): Promise<void> {
    const id = parseInt(param(req, 'id'), 10);
    if (isNaN(id)) { res.status(400).json({ success: false, message: 'Ungültige ID' }); return; }
    try {
      const filters = {
        von: req.query.von as string | undefined,
        bis: req.query.bis as string | undefined,
      };
      const data = await buchhaltungService.getBankkontoStatement(id, filters);
      if (!data) { res.status(404).json({ success: false, message: 'Bankkonto nicht gefunden' }); return; }
      res.json({ success: true, data });
    } catch (error) {
      logger.error('BuchhaltungController.getBankkontoStatement', { error });
      res.status(500).json({ success: false, message: 'Kontoauszug konnte nicht geladen werden' });
    }
  }

  // ── Konten ───────────────────────────────────────────────────────────────────

  async listKonten(req: Request, res: Response): Promise<void> {
    const haushaltsjahrId = parseInt(req.query.haushaltsjahr_id as string, 10);
    if (isNaN(haushaltsjahrId)) { res.status(400).json({ success: false, message: 'haushaltsjahr_id erforderlich' }); return; }
    try {
      const data = await buchhaltungService.getAllKonten(haushaltsjahrId);
      res.json({ success: true, data });
    } catch (error) {
      logger.error('BuchhaltungController.listKonten', { error });
      res.status(500).json({ success: false, message: 'Konten konnten nicht geladen werden' });
    }
  }

  async getKontenTree(req: Request, res: Response): Promise<void> {
    const haushaltsjahrId = req.query.haushaltsjahr_id ? parseInt(req.query.haushaltsjahr_id as string, 10) : undefined;
    if (!haushaltsjahrId || isNaN(haushaltsjahrId)) { res.status(400).json({ success: false, message: 'haushaltsjahr_id erforderlich' }); return; }
    try {
      const tree = await buchhaltungService.getKontenTree(haushaltsjahrId);
      res.json(tree);
    } catch (error) {
      logger.error('BuchhaltungController.getKontenTree', { error });
      res.status(500).json({ error: 'Fehler beim Laden des Kontenbaums' });
    }
  }

  async getKontoDetail(req: Request, res: Response): Promise<void> {
    const id = parseInt(param(req, 'id'), 10);
    if (isNaN(id)) { res.status(400).json({ success: false, message: 'Ungültige ID' }); return; }
    try {
      const detail = await buchhaltungService.getKontoDetail(id);
      if (!detail) { res.status(404).json({ error: 'Konto nicht gefunden' }); return; }
      res.json(detail);
    } catch (error) {
      logger.error('BuchhaltungController.getKontoDetail', { error });
      res.status(500).json({ error: 'Fehler beim Laden des Kontos' });
    }
  }

  async getPendingCount(req: Request, res: Response): Promise<void> {
    try {
      const haushaltsjahrId = req.query.haushaltsjahr_id ? parseInt(req.query.haushaltsjahr_id as string, 10) : undefined;
      const count = await buchhaltungService.getPendingCount(haushaltsjahrId);
      res.json({ count });
    } catch (error) {
      logger.error('BuchhaltungController.getPendingCount', { error });
      res.status(500).json({ error: 'Fehler' });
    }
  }

  async createKonto(req: Request, res: Response): Promise<void> {
    try {
      const data = await buchhaltungService.createKonto(req.body, req.user!.id);
      res.status(201).json({ success: true, data });
    } catch (error: any) {
      logger.error('BuchhaltungController.createKonto', { error });
      const status = error.statusCode || 500;
      res.status(status).json({ success: false, message: error.message || 'Konto konnte nicht erstellt werden' });
    }
  }

  async updateKonto(req: Request, res: Response): Promise<void> {
    const id = parseInt(param(req, 'id'), 10);
    if (isNaN(id)) { res.status(400).json({ success: false, message: 'Ungültige ID' }); return; }
    try {
      const data = await buchhaltungService.updateKonto(id, req.body);
      if (!data) { res.status(404).json({ success: false, message: 'Konto nicht gefunden' }); return; }
      res.json({ success: true, data });
    } catch (error: any) {
      logger.error('BuchhaltungController.updateKonto', { error });
      const status = error.statusCode || 500;
      res.status(status).json({ success: false, message: error.message || 'Konto konnte nicht aktualisiert werden' });
    }
  }

  async deleteKonto(req: Request, res: Response): Promise<void> {
    const id = parseInt(param(req, 'id'), 10);
    if (isNaN(id)) { res.status(400).json({ success: false, message: 'Ungültige ID' }); return; }
    try {
      await buchhaltungService.deleteKonto(id);
      res.json({ success: true });
    } catch (error) {
      logger.error('BuchhaltungController.deleteKonto', { error });
      res.status(500).json({ success: false, message: 'Konto konnte nicht gelöscht werden' });
    }
  }

  async getKontoBudget(req: Request, res: Response): Promise<void> {
    const id = parseInt(param(req, 'id'), 10);
    if (isNaN(id)) { res.status(400).json({ success: false, message: 'Ungültige ID' }); return; }
    try {
      const data = await buchhaltungService.getBudgetUtilisation(id);
      if (!data) { res.status(404).json({ success: false, message: 'Konto nicht gefunden' }); return; }
      res.json({ success: true, data });
    } catch (error) {
      logger.error('BuchhaltungController.getKontoBudget', { error });
      res.status(500).json({ success: false, message: 'Budgetauslastung konnte nicht geladen werden' });
    }
  }

  // ── Stats ────────────────────────────────────────────────────────────────────

  async getStats(req: Request, res: Response): Promise<void> {
    const haushaltsjahrId = parseInt(req.query.haushaltsjahr_id as string, 10);
    if (isNaN(haushaltsjahrId)) { res.status(400).json({ success: false, message: 'haushaltsjahr_id erforderlich' }); return; }
    try {
      const data = await buchhaltungService.getOverview(haushaltsjahrId);
      res.json({ success: true, data });
    } catch (error) {
      logger.error('BuchhaltungController.getStats', { error });
      res.status(500).json({ success: false, message: 'Statistik konnte nicht geladen werden' });
    }
  }

  // ── Transaktionen ────────────────────────────────────────────────────────────

  async listTransaktionen(req: Request, res: Response): Promise<void> {
    try {
      const filters = {
        haushaltsjahr_id: req.query.haushaltsjahr_id ? parseInt(req.query.haushaltsjahr_id as string, 10) : undefined,
        konto_id:         req.query.konto_id         ? parseInt(req.query.konto_id as string, 10)         : undefined,
        status:           req.query.status  as string | undefined,
        typ:              req.query.typ     as string | undefined,
        datum_von:        req.query.datum_von as string | undefined,
        datum_bis:        req.query.datum_bis as string | undefined,
        search:           req.query.search  as string | undefined,
      };
      const data = await buchhaltungService.listTransaktionen(filters);
      res.json({ success: true, data });
    } catch (error) {
      logger.error('BuchhaltungController.listTransaktionen', { error });
      res.status(500).json({ success: false, message: 'Transaktionen konnten nicht geladen werden' });
    }
  }

  async getTransaktion(req: Request, res: Response): Promise<void> {
    const id = parseInt(param(req, 'id'), 10);
    if (isNaN(id)) { res.status(400).json({ success: false, message: 'Ungültige ID' }); return; }
    try {
      const data = await buchhaltungService.getTransaktionById(id);
      if (!data) { res.status(404).json({ success: false, message: 'Transaktion nicht gefunden' }); return; }
      res.json({ success: true, data });
    } catch (error) {
      logger.error('BuchhaltungController.getTransaktion', { error });
      res.status(500).json({ success: false, message: 'Transaktion konnte nicht geladen werden' });
    }
  }

  async createTransaktion(req: Request, res: Response): Promise<void> {
    try {
      const data = await buchhaltungService.createTransaktion(req.body, req.user!.id);
      res.status(201).json({ success: true, data });
    } catch (error) {
      logger.error('BuchhaltungController.createTransaktion', { error });
      res.status(500).json({ success: false, message: 'Transaktion konnte nicht erstellt werden' });
    }
  }

  async updateTransaktion(req: Request, res: Response): Promise<void> {
    const id = parseInt(param(req, 'id'), 10);
    if (isNaN(id)) { res.status(400).json({ success: false, message: 'Ungültige ID' }); return; }
    try {
      const data = await buchhaltungService.updateTransaktion(id, req.body, req.user!.id);
      if (!data) { res.status(404).json({ success: false, message: 'Transaktion nicht gefunden oder nicht mehr bearbeitbar' }); return; }
      res.json({ success: true, data });
    } catch (error) {
      logger.error('BuchhaltungController.updateTransaktion', { error });
      res.status(500).json({ success: false, message: 'Transaktion konnte nicht aktualisiert werden' });
    }
  }

  async deleteTransaktion(req: Request, res: Response): Promise<void> {
    const id = parseInt(param(req, 'id'), 10);
    if (isNaN(id)) { res.status(400).json({ success: false, message: 'Ungültige ID' }); return; }
    try {
      const deleted = await buchhaltungService.deleteTransaktion(id);
      if (!deleted) { res.status(404).json({ success: false, message: 'Transaktion nicht gefunden oder nicht löschbar' }); return; }
      res.json({ success: true });
    } catch (error) {
      logger.error('BuchhaltungController.deleteTransaktion', { error });
      res.status(500).json({ success: false, message: 'Transaktion konnte nicht gelöscht werden' });
    }
  }

  async buchenTransaktion(req: Request, res: Response): Promise<void> {
    const id = parseInt(param(req, 'id'), 10);
    if (isNaN(id)) { res.status(400).json({ success: false, message: 'Ungültige ID' }); return; }
    try {
      const data = await buchhaltungService.bookTransaktion(id, req.user!.id);
      if (!data) { res.status(404).json({ success: false, message: 'Transaktion nicht gefunden oder bereits gebucht' }); return; }
      res.json({ success: true, data });
    } catch (error) {
      logger.error('BuchhaltungController.buchenTransaktion', { error });
      res.status(500).json({ success: false, message: 'Transaktion konnte nicht gebucht werden' });
    }
  }

  async stornoTransaktion(req: Request, res: Response): Promise<void> {
    const id = parseInt(param(req, 'id'), 10);
    if (isNaN(id)) { res.status(400).json({ success: false, message: 'Ungültige ID' }); return; }
    try {
      const data = await buchhaltungService.stornoTransaktion(id, req.user!.id);
      if (!data) { res.status(404).json({ success: false, message: 'Transaktion nicht stornierbar' }); return; }
      res.json({ success: true, data });
    } catch (error) {
      logger.error('BuchhaltungController.stornoTransaktion', { error });
      res.status(500).json({ success: false, message: 'Transaktion konnte nicht storniert werden' });
    }
  }

  // ── Transfers ─────────────────────────────────────────────────────────────────

  async createTransfer(req: Request, res: Response): Promise<void> {
    try {
      const data = await buchhaltungService.createTransfer(req.body, req.user!.id);
      res.status(201).json({ success: true, data });
    } catch (error) {
      logger.error('BuchhaltungController.createTransfer', { error });
      res.status(500).json({ success: false, message: 'Umbuchung konnte nicht erstellt werden' });
    }
  }

  // ── Belege ───────────────────────────────────────────────────────────────────

  async uploadBeleg(req: Request, res: Response): Promise<void> {
    const id = parseInt(param(req, 'id'), 10);
    if (isNaN(id)) { res.status(400).json({ success: false, message: 'Ungültige ID' }); return; }
    if (!req.file)  { res.status(400).json({ success: false, message: 'Keine Datei hochgeladen' }); return; }
    try {
      const f = req.file as Express.Multer.File;
      const data = await buchhaltungService.uploadBeleg(id, { filename: f.filename, originalname: f.originalname, mimetype: f.mimetype, size: f.size }, req.user!.id);
      res.status(201).json({ success: true, data });
    } catch (error) {
      logger.error('BuchhaltungController.uploadBeleg', { error });
      res.status(500).json({ success: false, message: 'Beleg konnte nicht hochgeladen werden' });
    }
  }

  async deleteBeleg(req: Request, res: Response): Promise<void> {
    const id = parseInt(param(req, 'id'), 10);
    if (isNaN(id)) { res.status(400).json({ success: false, message: 'Ungültige ID' }); return; }
    try {
      const deleted = await buchhaltungService.deleteBeleg(id);
      if (!deleted) { res.status(404).json({ success: false, message: 'Beleg nicht gefunden' }); return; }
      res.json({ success: true });
    } catch (error) {
      logger.error('BuchhaltungController.deleteBeleg', { error });
      res.status(500).json({ success: false, message: 'Beleg konnte nicht gelöscht werden' });
    }
  }

  // ── Einstellungen ────────────────────────────────────────────────────────────

  async getEinstellungen(_req: Request, res: Response): Promise<void> {
    try {
      const data = await buchhaltungService.getEinstellungen();
      res.json({ success: true, data });
    } catch (error) {
      logger.error('BuchhaltungController.getEinstellungen', { error });
      res.status(500).json({ success: false, message: 'Einstellungen konnten nicht geladen werden' });
    }
  }

  async setEinstellungen(req: Request, res: Response): Promise<void> {
    try {
      await buchhaltungService.setEinstellungen(req.body);
      res.json({ success: true });
    } catch (error) {
      logger.error('BuchhaltungController.setEinstellungen', { error });
      res.status(500).json({ success: false, message: 'Einstellungen konnten nicht gespeichert werden' });
    }
  }

  // ── Wiederkehrend ────────────────────────────────────────────────────────────

  async listWiederkehrend(_req: Request, res: Response): Promise<void> {
    try {
      const data = await buchhaltungService.getAllWiederkehrend();
      res.json({ success: true, data });
    } catch (error) {
      logger.error('BuchhaltungController.listWiederkehrend', { error });
      res.status(500).json({ success: false, message: 'Wiederkehrende Buchungen konnten nicht geladen werden' });
    }
  }

  async createWiederkehrend(req: Request, res: Response): Promise<void> {
    try {
      const data = await buchhaltungService.createWiederkehrend(req.body, req.user!.id);
      res.status(201).json({ success: true, data });
    } catch (error) {
      logger.error('BuchhaltungController.createWiederkehrend', { error });
      res.status(500).json({ success: false, message: 'Wiederkehrende Buchung konnte nicht erstellt werden' });
    }
  }

  async updateWiederkehrend(req: Request, res: Response): Promise<void> {
    const id = parseInt(param(req, 'id'), 10);
    if (isNaN(id)) { res.status(400).json({ success: false, message: 'Ungültige ID' }); return; }
    try {
      const data = await buchhaltungService.updateWiederkehrend(id, req.body);
      if (!data) { res.status(404).json({ success: false, message: 'Wiederkehrende Buchung nicht gefunden' }); return; }
      res.json({ success: true, data });
    } catch (error) {
      logger.error('BuchhaltungController.updateWiederkehrend', { error });
      res.status(500).json({ success: false, message: 'Wiederkehrende Buchung konnte nicht aktualisiert werden' });
    }
  }

  async deleteWiederkehrend(req: Request, res: Response): Promise<void> {
    const id = parseInt(param(req, 'id'), 10);
    if (isNaN(id)) { res.status(400).json({ success: false, message: 'Ungültige ID' }); return; }
    try {
      await buchhaltungService.deleteWiederkehrend(id);
      res.json({ success: true });
    } catch (error) {
      logger.error('BuchhaltungController.deleteWiederkehrend', { error });
      res.status(500).json({ success: false, message: 'Wiederkehrende Buchung konnte nicht gelöscht werden' });
    }
  }

  // ── CSV Export ───────────────────────────────────────────────────────────────

  async exportCsv(req: Request, res: Response): Promise<void> {
    const haushaltsjahrId = parseInt(req.query.haushaltsjahr_id as string, 10);
    if (isNaN(haushaltsjahrId)) { res.status(400).json({ success: false, message: 'haushaltsjahr_id erforderlich' }); return; }
    try {
      const csv = await buchhaltungService.exportTransaktionenCsv(haushaltsjahrId);
      res.setHeader('Content-Type', 'text/csv; charset=utf-8');
      res.setHeader('Content-Disposition', `attachment; filename="transaktionen_${haushaltsjahrId}.csv"`);
      res.send(csv);
    } catch (error) {
      logger.error('BuchhaltungController.exportCsv', { error });
      res.status(500).json({ success: false, message: 'CSV-Export fehlgeschlagen' });
    }
  }

  // ── Audit ────────────────────────────────────────────────────────────────────

  async getAudit(req: Request, res: Response): Promise<void> {
    const id = parseInt(param(req, 'transaktionId'), 10);
    if (isNaN(id)) { res.status(400).json({ success: false, message: 'Ungültige ID' }); return; }
    try {
      const data = await buchhaltungService.getAuditByTransaktion(id);
      res.json({ success: true, data });
    } catch (error) {
      logger.error('BuchhaltungController.getAudit', { error });
      res.status(500).json({ success: false, message: 'Audit konnte nicht geladen werden' });
    }
  }

  // ── Erstattungen ────────────────────────────────────────────────────────────

  async createErstattung(req: Request, res: Response): Promise<void> {
    try {
      const data = await buchhaltungService.createErstattung({
        ...req.body,
        erstellt_von: req.user!.id,
      });
      res.status(201).json({ success: true, data });
    } catch (error) {
      logger.error('BuchhaltungController.createErstattung', { error });
      res.status(500).json({ success: false, message: 'Erstattung konnte nicht erstellt werden' });
    }
  }

  async getErstattungLinks(req: Request, res: Response): Promise<void> {
    const id = parseInt(param(req, 'id'), 10);
    if (isNaN(id)) { res.status(400).json({ success: false, message: 'Ungültige ID' }); return; }
    try {
      const data = await buchhaltungService.getErstattungLinks(id);
      res.json({ success: true, data });
    } catch (error) {
      logger.error('BuchhaltungController.getErstattungLinks', { error });
      res.status(500).json({ success: false, message: 'Erstattungsverknüpfungen konnten nicht geladen werden' });
    }
  }

  // ── Planung ─────────────────────────────────────────────────────────────────

  async listPlanungen(_req: Request, res: Response): Promise<void> {
    try {
      const data = await buchhaltungService.listPlanungen();
      res.json({ success: true, data });
    } catch (error) {
      logger.error('BuchhaltungController.listPlanungen', { error });
      res.status(500).json({ success: false, message: 'Planungen konnten nicht geladen werden' });
    }
  }

  async getPlanung(req: Request, res: Response): Promise<void> {
    const id = parseInt(param(req, 'id'), 10);
    if (isNaN(id)) { res.status(400).json({ success: false, message: 'Ungültige ID' }); return; }
    try {
      const data = await buchhaltungService.getPlanungById(id);
      if (!data) { res.status(404).json({ success: false, message: 'Planung nicht gefunden' }); return; }
      res.json({ success: true, data });
    } catch (error) {
      logger.error('BuchhaltungController.getPlanung', { error });
      res.status(500).json({ success: false, message: 'Planung konnte nicht geladen werden' });
    }
  }

  async createPlanung(req: Request, res: Response): Promise<void> {
    try {
      const data = await buchhaltungService.createPlanung(req.body, req.user!.id);
      res.status(201).json({ success: true, data });
    } catch (error) {
      logger.error('BuchhaltungController.createPlanung', { error });
      res.status(500).json({ success: false, message: 'Planung konnte nicht erstellt werden' });
    }
  }

  async updatePlanung(req: Request, res: Response): Promise<void> {
    const id = parseInt(param(req, 'id'), 10);
    if (isNaN(id)) { res.status(400).json({ success: false, message: 'Ungültige ID' }); return; }
    try {
      const data = await buchhaltungService.updatePlanung(id, req.body);
      if (!data) { res.status(404).json({ success: false, message: 'Planung nicht gefunden' }); return; }
      res.json({ success: true, data });
    } catch (error) {
      logger.error('BuchhaltungController.updatePlanung', { error });
      res.status(500).json({ success: false, message: 'Planung konnte nicht aktualisiert werden' });
    }
  }

  async deletePlanung(req: Request, res: Response): Promise<void> {
    const id = parseInt(param(req, 'id'), 10);
    if (isNaN(id)) { res.status(400).json({ success: false, message: 'Ungültige ID' }); return; }
    try {
      await buchhaltungService.deletePlanung(id);
      res.json({ success: true });
    } catch (error) {
      logger.error('BuchhaltungController.deletePlanung', { error });
      res.status(500).json({ success: false, message: 'Planung konnte nicht gelöscht werden' });
    }
  }

  async createPlanposition(req: Request, res: Response): Promise<void> {
    const planungId = parseInt(param(req, 'id'), 10);
    if (isNaN(planungId)) { res.status(400).json({ success: false, message: 'Ungültige ID' }); return; }
    try {
      const data = await buchhaltungService.createPlanposition(planungId, req.body);
      res.status(201).json({ success: true, data });
    } catch (error) {
      logger.error('BuchhaltungController.createPlanposition', { error });
      res.status(500).json({ success: false, message: 'Planposition konnte nicht erstellt werden' });
    }
  }

  async updatePlanposition(req: Request, res: Response): Promise<void> {
    const id = parseInt(param(req, 'id'), 10);
    if (isNaN(id)) { res.status(400).json({ success: false, message: 'Ungültige ID' }); return; }
    try {
      const data = await buchhaltungService.updatePlanposition(id, req.body);
      if (!data) { res.status(404).json({ success: false, message: 'Planposition nicht gefunden' }); return; }
      res.json({ success: true, data });
    } catch (error) {
      logger.error('BuchhaltungController.updatePlanposition', { error });
      res.status(500).json({ success: false, message: 'Planposition konnte nicht aktualisiert werden' });
    }
  }

  async deletePlanposition(req: Request, res: Response): Promise<void> {
    const id = parseInt(param(req, 'id'), 10);
    if (isNaN(id)) { res.status(400).json({ success: false, message: 'Ungültige ID' }); return; }
    try {
      await buchhaltungService.deletePlanposition(id);
      res.json({ success: true });
    } catch (error) {
      logger.error('BuchhaltungController.deletePlanposition', { error });
      res.status(500).json({ success: false, message: 'Planposition konnte nicht gelöscht werden' });
    }
  }

  async listPlanpositionen(req: Request, res: Response): Promise<void> {
    const planungId = parseInt(param(req, 'id'), 10);
    if (isNaN(planungId)) { res.status(400).json({ success: false, message: 'Ungültige ID' }); return; }
    try {
      const data = await buchhaltungService.getPlanpositionenByPlanung(planungId);
      res.json({ success: true, data });
    } catch (error) {
      logger.error('BuchhaltungController.listPlanpositionen', { error });
      res.status(500).json({ success: false, message: 'Planpositionen konnten nicht geladen werden' });
    }
  }

  async createHaushaltsjahrFromPlan(req: Request, res: Response): Promise<void> {
    const id = parseInt(param(req, 'id'), 10);
    if (isNaN(id)) { res.status(400).json({ success: false, message: 'Ungültige ID' }); return; }
    try {
      const data = await buchhaltungService.createHaushaltsjahrFromPlan(id, req.user!.id);
      res.status(201).json({ success: true, data });
    } catch (error: any) {
      logger.error('BuchhaltungController.createHaushaltsjahrFromPlan', { error });
      const status = error.statusCode || 500;
      res.status(status).json({ success: false, message: error.message || 'Haushaltsjahr konnte nicht erstellt werden' });
    }
  }

  // ── Freigaben ────────────────────────────────────────────────────────────────

  async requestFreigabe(req: Request, res: Response): Promise<void> {
    const id = parseInt(param(req, 'id'), 10);
    if (isNaN(id)) { res.status(400).json({ success: false, message: 'Ungültige ID' }); return; }
    try {
      const data = await buchhaltungService.createFreigabe(id, req.user!.id);
      res.status(201).json({ success: true, data });
    } catch (error) {
      logger.error('BuchhaltungController.requestFreigabe', { error });
      res.status(500).json({ success: false, message: 'Freigabe konnte nicht angefragt werden' });
    }
  }

  async approveFreigabe(req: Request, res: Response): Promise<void> {
    const id = parseInt(param(req, 'id'), 10);
    if (isNaN(id)) { res.status(400).json({ success: false, message: 'Ungültige ID' }); return; }
    try {
      const data = await buchhaltungService.approveFreigabe(id, req.body.kommentar, req.user!.id);
      if (!data) { res.status(404).json({ success: false, message: 'Freigabe nicht gefunden' }); return; }
      res.json({ success: true, data });
    } catch (error) {
      logger.error('BuchhaltungController.approveFreigabe', { error });
      res.status(500).json({ success: false, message: 'Freigabe konnte nicht genehmigt werden' });
    }
  }

  async rejectFreigabe(req: Request, res: Response): Promise<void> {
    const id = parseInt(param(req, 'id'), 10);
    if (isNaN(id)) { res.status(400).json({ success: false, message: 'Ungültige ID' }); return; }
    try {
      const data = await buchhaltungService.rejectFreigabe(id, req.body.kommentar, req.user!.id);
      if (!data) { res.status(404).json({ success: false, message: 'Freigabe nicht gefunden' }); return; }
      res.json({ success: true, data });
    } catch (error) {
      logger.error('BuchhaltungController.rejectFreigabe', { error });
      res.status(500).json({ success: false, message: 'Freigabe konnte nicht abgelehnt werden' });
    }
  }
}

export default new BuchhaltungController();
