# logic/berechne_betrieb_ausgaben.py
import json
from collections import defaultdict
from datetime import datetime, date
from calendar import monthrange
import os

SRC_PATH = "data/betrieb_ein_ausgaben.json"
OUT_PATH = "data/exchange/betrieb_ausgaben.json"

# -----------------------
# Helpers
# -----------------------
def parse_date(s):
    try:
        return datetime.strptime(s, "%Y-%m-%d").date()
    except Exception:
        return None

def monatsliste():
    return [f"{y}-{m:02d}" for y in range(2026, 2029) for m in range(1, 13)]

def betrag_float(x):
    try:
        return float(str(x).replace(",", "."))
    except Exception:
        return 0.0

def month_window(y, m):
    d = monthrange(y, m)[1]
    return date(y, m, 1), date(y, m, d)

def overlap_days(a_start, a_end, b_start, b_end):
    start = max(a_start, b_start)
    end = min(a_end, b_end)
    return max(0, (end - start).days + 1)

def norm(s: str) -> str:
    """kleine Normalisierung für robuste Vergleiche"""
    t = str(s or "").strip().lower()
    t = (
        t.replace("ä", "ae")
         .replace("ö", "oe")
         .replace("ü", "ue")
         .replace("ß", "ss")
    )
    return t

# -----------------------
# Core
# -----------------------
def berechne_monatliche_betriebsausgaben(daten):
    werte = defaultdict(float)

    # erlaubte Typ-Schreibweisen
    erlaubte_typen = {
        "betriebliche ausgabe",
        "betrieb ausgabe",
        "betrieblich ausgabe",
        "betriebliche ausgaben",
        "ausgabe",
    }

    for e in daten:
        typ = norm(e.get("typ", ""))
        if typ not in erlaubte_typen:
            continue

        betrag = betrag_float(e.get("betrag", 0))
        if betrag == 0:
            # 0-Beträge sparen Arbeit – sie verändern nichts
            continue

        turnus = norm(e.get("turnus", ""))
        zeitfilter = norm(e.get("zeitfilter", ""))
        gd = parse_date(e.get("gueltig_datum", ""))  # kann None sein

        # Gültigkeitsfenster für tages-/wochenlogik
        valid_start = date(1900, 1, 1)
        valid_end = date(2999, 12, 31)
        if zeitfilter == "ab" and gd:
            valid_start = gd
        elif zeitfilter == "bis" and gd:
            valid_end = gd

        for monat in monatsliste():
            y, m = map(int, monat.split("-"))
            m_start, m_end = month_window(y, m)

            # Tages-/Wochenlogik
            if turnus in ("taeglich", "taeg", "taegl", "taegliche", "taeglicher", "taegliches", "taeg"):
                daily = betrag
                tage = overlap_days(valid_start, valid_end, m_start, m_end)
                if zeitfilter == "einmalig":
                    if gd and gd.year == y and gd.month == m:
                        werte[monat] += betrag
                elif tage > 0:
                    werte[monat] += daily * tage
                continue

            if turnus in ("woechentlich", "woechentl", "woech", "woechentliche", "woechentlicher"):
                # Betrag ist Wochenbetrag → auf Tage verteilen
                daily = betrag / 7.0
                tage = overlap_days(valid_start, valid_end, m_start, m_end)
                if zeitfilter == "einmalig":
                    if gd and gd.year == y and gd.month == m:
                        werte[monat] += betrag
                elif tage > 0:
                    werte[monat] += daily * tage
                continue

            # Monats-/Quartals-/Halbjahres-/Jahres-/Einmalig
            # Zeitfilter prüfen (für nicht tagesbasierte Turni)
            if zeitfilter == "ab" and gd and m_start < gd:
                continue
            if zeitfilter == "bis" and gd and m_start > gd:
                continue
            if zeitfilter == "einmalig":
                if gd and gd.year == y and gd.month == m:
                    werte[monat] += betrag
                continue

            if turnus == "monatlich":
                werte[monat] += betrag
            elif turnus in ("vierteljaehrlich", "vierteljaehrl", "vierteljaehr", "vierteljaehrige", "vierteljaehriger", "vierteljaehriges", "vierteljaehrlich", "vierteljaehrlich?") or turnus == "vierteljaehrlich" or turnus == "vierteljaehrlich?":
                # robust gegen diverse Einträge – Kern ist "vierteljaehrlich"
                if gd:
                    diff = (y - gd.year) * 12 + (m - gd.month)
                    if diff >= 0 and diff % 3 == 0:
                        werte[monat] += betrag
            elif turnus in ("halbjaehrlich", "halbjaehrl", "halbjaehr"):
                if gd:
                    diff = (y - gd.year) * 12 + (m - gd.month)
                    if diff >= 0 and diff % 6 == 0:
                        werte[monat] += betrag
            elif turnus in ("jaehrlich", "jaehrl", "jaehr"):
                if gd and gd.month == m:
                    werte[monat] += betrag
            else:
                # unbekannter Turnus → vorsichtshalber nichts tun
                pass

    # auf 2 Nachkommastellen runden
    return {k: round(v, 2) for k, v in werte.items()}

def main():
    if not os.path.exists(SRC_PATH):
        data = []
    else:
        with open(SRC_PATH, "r", encoding="utf-8") as f:
            data = json.load(f)

    werte = berechne_monatliche_betriebsausgaben(data)

    # fehlende Monate mit 0 auffüllen
    for m in monatsliste():
        werte.setdefault(m, 0.0)

    with open(OUT_PATH, "w", encoding="utf-8") as f:
        json.dump(werte, f, indent=2, ensure_ascii=False)

if __name__ == "__main__":
    main()