"""Kassabuch-Verwaltung: Rechnungsnummern-Datei anlegen, befüllen, Batch-Zusammenfassung."""

import os
import logging
from datetime import timedelta

import pandas as pd
from openpyxl import load_workbook, Workbook
from openpyxl.styles import Font, PatternFill

from core.models import RECHNUNG_COLUMNS, Mitglied

logger = logging.getLogger(__name__)


def init_kassabuch(path: str) -> int:
    """Legt das Kassabuch-Excel neu an (falls nicht vorhanden) und gibt die letzte Rechnungsnummer zurück.

    Zeile 1 = Überschriften, Zeile 2 = manuelle Anfangssaldo-Eingabe (gelb hinterlegt).
    Gibt 0 zurück wenn das Kassabuch neu angelegt oder leer ist.
    """
    import re as _re
    from datetime import datetime

    current_year = datetime.now().year

    if not os.path.exists(path):
        wb_new = Workbook()
        ws_new = wb_new.active
        ws_new.title = "Kassabuch"

        headers = RECHNUNG_COLUMNS + ["Link", "Steuerschuld RC (€)", "Steuerschuld kumuliert (€)"]
        ws_new.append(headers)
        for col_i, _ in enumerate(headers, start=1):
            ws_new.cell(row=1, column=col_i).font = Font(bold=True)

        ws_new.append([
            "",
            "",
            "",
            "→ Anfangssaldo (bitte eintragen)",
            "",
            "",
            "",
            "",
            0.00,
            "=I2",
            "",
        ])
        yellow = PatternFill("solid", fgColor="FFF9C4")
        for col_i in range(1, 12):
            ws_new.cell(row=2, column=col_i).fill = yellow
        ws_new.cell(row=2, column=4).font = Font(bold=True, color="7B5800")
        ws_new.cell(row=2, column=9).number_format = "#,##0.00 €"
        ws_new.cell(row=2, column=10).number_format = "#,##0.00 €"

        ws_new.column_dimensions["A"].width = 4
        ws_new.column_dimensions["B"].width = 14
        ws_new.column_dimensions["C"].width = 14
        ws_new.column_dimensions["D"].width = 42
        ws_new.column_dimensions["E"].width = 22
        ws_new.column_dimensions["F"].width = 20
        ws_new.column_dimensions["G"].width = 18
        ws_new.column_dimensions["H"].width = 14
        ws_new.column_dimensions["I"].width = 13
        ws_new.column_dimensions["J"].width = 13
        ws_new.column_dimensions["K"].width = 14
        ws_new.column_dimensions["L"].width = 18
        ws_new.column_dimensions["M"].width = 22

        wb_new.save(path)
        return 0

    df = pd.read_excel(path)
    if df.empty or "Rechnungsnummer" not in df.columns:
        return 0

    current_year_numbers = df["Rechnungsnummer"].astype(str).str.extract(
        rf"^{current_year}_(\d+)"
    )[0].dropna()

    if current_year_numbers.empty:
        return 0

    return current_year_numbers.astype(int).max()


def update_kassabuch(
    path: str,
    mitglied: Mitglied,
    description: str,
    msgid: str,
    config: dict,
    datum_rechnung,
    datum_abbuchung,
    folder_rechnungen: str,
) -> int:
    """Fügt eine Mitglieds-Zeile ins Kassabuch-Excel ein.

    Gibt die Zeilennummer der neu geschriebenen Zeile zurück (für Gruppen-Tracking).
    Abbuchungen (positive Kosten) → rote Zeile; Gutschriften → grüne Zeile.
    """
    try:
        if not os.path.exists(path):
            init_kassabuch(path)
        wb = load_workbook(path)
        ws = wb.active

        # Steuerinfo-Suffix + Steuerschuld für Spalte L (RC-MwSt ans Finanzamt)
        _kb_kleinunt = str(config.get("Kleinunternehmer", "Ja")).strip().lower() == "ja"
        _kb_rc_kt    = config.get("RC_Kostentraeger", "Mitglied").strip()
        _steuer_suffix = ""
        _steuerschuld  = None

        if mitglied.Steuersatz == 20 and mitglied.Generation > 0:
            if _kb_kleinunt:
                _traeger = "Mitgl." if _kb_rc_kt == "Mitglied" else "EEG"
                _steuer_suffix = f" | RC 20% ({_traeger})"
                try:
                    _t_e = float(str(config.get("Tarif_Einspeisung", "0")).replace(",", "."))
                    _steuerschuld = round(mitglied.Generation * _t_e / 7, 2)
                except Exception:
                    pass
            else:
                _steuer_suffix = " | USt 20%"
        elif mitglied.Steuersatz == 13 and mitglied.Generation > 0:
            _steuer_suffix = " | RC 13%" if _kb_kleinunt else " | USt 13%"
        elif mitglied.Steuersatz == 0 and mitglied.Generation > 0 and _kb_kleinunt:
            _steuer_suffix = " | KU-befreit"

        new_row_data = [
            "",
            datum_rechnung.strftime("%d.%m.%Y"),
            datum_abbuchung.strftime("%d.%m.%Y"),
            msgid,
            description,
            mitglied.Name,
            _steuer_suffix.lstrip(" |").strip(),
            mitglied.Rechnungsnummer,
            round(mitglied.Kosten, 2),
        ]
        ws.append(new_row_data)
        row_idx = ws.max_row

        # J: laufendes Saldo
        kassa_cell = ws.cell(row=row_idx, column=10)
        kassa_cell.value = f"=J{row_idx - 1}+I{row_idx}"
        kassa_cell.number_format = "#,##0.00 €"

        ws.cell(row=row_idx, column=9).number_format = "#,##0.00 €"

        # Zeilenfarbe
        if mitglied.Kosten > 0:
            row_fill    = PatternFill("solid", fgColor="FFEBEE")
            betrag_font = Font(color="B71C1C")
        else:
            row_fill    = PatternFill("solid", fgColor="E8F5E9")
            betrag_font = Font(color="1B5E20")

        for col_i in range(1, 11):
            ws.cell(row=row_idx, column=col_i).fill = row_fill
        ws.cell(row=row_idx, column=9).font = betrag_font

        # K: Hyperlink zur Rechnungsdatei
        invoice_path = None
        if folder_rechnungen and os.path.exists(folder_rechnungen):
            base = f"Rechnung_{mitglied.Rechnungsnummer}_{mitglied.Name4Rechnung}"
            for ext in (".pdf", ".docx", ".xlsx"):
                candidate = os.path.join(folder_rechnungen, base + ext)
                if os.path.exists(candidate):
                    invoice_path = candidate
                    break
        if invoice_path:
            link_cell = ws.cell(row=row_idx, column=11)
            kassabuch_dir = os.path.dirname(path)
            rel = os.path.relpath(invoice_path, kassabuch_dir)
            url = rel.replace("\\", "/")
            link_cell.value     = "Rechnung öffnen"
            link_cell.hyperlink = url
            link_cell.font      = Font(color="0563C1", underline="single")

        # L: Steuerschuld RC (€)
        if _steuerschuld is not None:
            steuerschuld_cell = ws.cell(row=row_idx, column=12)
            steuerschuld_cell.value         = _steuerschuld
            steuerschuld_cell.number_format = "#,##0.00 €"
            steuerschuld_cell.font          = Font(color="E65100")

        # M: Steuerschuld kumuliert
        kum_cell = ws.cell(row=row_idx, column=13)
        if _steuerschuld is not None:
            kum_cell.value = f"=IF(ISNUMBER(M{row_idx-1}),M{row_idx-1},0)+L{row_idx}"
        else:
            kum_cell.value = f"=IF(ISNUMBER(M{row_idx-1}),M{row_idx-1},0)"
        kum_cell.number_format = "#,##0.00 €"
        kum_cell.font          = Font(color="E65100")

        wb.save(path)
        return row_idx

    except Exception as e:
        logger.error(f"Fehler beim Aktualisieren des Kassabuchs: {e}")
        raise


def write_kassabuch_batch_summary(
    path: str,
    ls_rows: list,
    gs_rows: list,
    ls_msgid: str,
    gs_msgid: str,
    ls_ctrlsum: float,
    gs_ctrlsum: float,
    datum_abbuchung,
) -> None:
    """Schreibt je eine Zusammenfassungszeile pro SEPA-Batch und klappt Detail-Zeilen ein.

    ls_rows / gs_rows: Liste der Zeilennummern der jeweiligen Mitglieds-Zeilen.
    """
    if not os.path.exists(path):
        return
    try:
        wb = load_workbook(path)
        ws = wb.active

        ws.sheet_properties.outlinePr.summaryBelow = True

        datum_ls = datum_abbuchung.strftime("%d.%m.%Y")
        datum_gs = (datum_abbuchung + timedelta(days=1)).strftime("%d.%m.%Y")

        batches = []
        if ls_ctrlsum > 0 and ls_rows:
            batches.append((
                datum_ls, datum_ls, ls_msgid,
                f"SEPA Lastschrift Batch (∑ {ls_ctrlsum:.2f} €)",
                PatternFill("solid", fgColor="FFCDD2"),
                ls_rows,
            ))
        if gs_ctrlsum > 0 and gs_rows:
            batches.append((
                datum_gs, datum_gs, gs_msgid,
                f"SEPA Gutschrift Batch (∑ {gs_ctrlsum:.2f} €)",
                PatternFill("solid", fgColor="C8E6C9"),
                gs_rows,
            ))

        for rd, bd, msgid, beschr, fill, detail_rows in batches:
            ws.append([
                "", rd, bd, msgid, beschr,
                "", "", "", "",
            ])
            summary_row = ws.max_row

            kassa_cell = ws.cell(row=summary_row, column=10)
            kassa_cell.value          = f"=J{summary_row - 1}"
            kassa_cell.number_format  = "#,##0.00 €"

            for col_i in range(1, 11):
                cell       = ws.cell(row=summary_row, column=col_i)
                cell.fill  = fill
                cell.font  = Font(bold=True)

            for r in detail_rows:
                ws.row_dimensions[r].outline_level = 1
                ws.row_dimensions[r].hidden        = True
            ws.row_dimensions[summary_row].collapsed = True

        wb.save(path)
    except Exception as e:
        logger.error(f"Fehler beim Schreiben der Kassabuch-Batchzeilen: {e}")
