# views/finanzen.py
# Phase 0: Vision 2026 – Code-Refactoring

import csv
import io
import json
import os
import time
from datetime import datetime, timedelta, date
from decimal import Decimal

import qrcode
import qrcode.image.svg
import requests
from django.conf import settings
from django.contrib import messages
from django.contrib.auth.decorators import login_required
from django.core.paginator import Paginator
from django.db.models import (Avg, Count, DecimalField, F, IntegerField, Q,
                              Sum, Value)
from django.db.models.functions import Cast, Coalesce, NullIf, Replace
from django.http import HttpResponse, JsonResponse
from django.shortcuts import get_object_or_404, redirect, render
from django.urls import reverse
from django.utils import timezone
from django.views.decorators.csrf import csrf_exempt
from django_otp.decorators import otp_required
from django_otp.plugins.otp_totp.models import TOTPDevice
from django_otp.plugins.otp_static.models import StaticDevice, StaticToken
from django_otp.util import random_hex
from rest_framework.decorators import api_view
from rest_framework.response import Response

from stiftung.models import (AppConfiguration, AuditLog, BackupJob, BankTransaction,
                     BriefVorlage, CSVImport, Destinataer,
                     DestinataerEmailEingang, DestinataerNotiz,
                     DestinataerUnterstuetzung,
                     DokumentLink, Foerderung, GeschichteBild, GeschichteSeite,
                     Land, LandAbrechnung, LandVerpachtung, Paechter, Person,
                     Rentmeister, StiftungsKalenderEintrag, StiftungsKonto,
                     UnterstuetzungWiederkehrend, Veranstaltung,
                     Veranstaltungsteilnehmer, Verwaltungskosten,
                     VierteljahresNachweis)
from stiftung.forms import (
    DestinataerForm, DestinataerUnterstuetzungForm, DestinataerNotizForm,
    FoerderungForm, GeschichteBildForm, GeschichteSeiteForm,
    LandForm, LandVerpachtungForm, LandAbrechnungForm,
    PaechterForm, DokumentLinkForm,
    RentmeisterForm, StiftungsKontoForm, VerwaltungskostenForm,
    BankTransactionForm, BankImportForm,
    UnterstuetzungForm, UnterstuetzungWiederkehrendForm,
    UnterstuetzungMarkAsPaidForm, VierteljahresNachweisForm,
    UserCreationForm, UserUpdateForm, PasswordChangeForm, UserPermissionForm,
    TwoFactorSetupForm, TwoFactorVerifyForm, TwoFactorDisableForm,
    BackupTokenRegenerateForm, PersonForm,
    VeranstaltungForm, VeranstaltungsteilnehmerForm,
)


@login_required
def bericht_list(request):
    """List available reports with modular report builder"""
    # Get available years from data
    jahre = sorted(
        set(
            list(Foerderung.objects.values_list("jahr", flat=True))
            + list(LandVerpachtung.objects.values_list("pachtbeginn__year", flat=True))
        ),
        reverse=True,
    )

    # Statistics for overview tiles
    total_destinataere = Destinataer.objects.count()
    total_laendereien = Land.objects.count()
    total_verpachtungen = LandVerpachtung.objects.count()
    total_foerderungen = Foerderung.objects.count()

    context = {
        "jahre": jahre,
        "title": "Berichte",
        "total_destinataere": total_destinataere,
        "total_laendereien": total_laendereien,
        "total_verpachtungen": total_verpachtungen,
        "total_foerderungen": total_foerderungen,
        "bericht_vorlagen": BERICHT_VORLAGEN,
        "bericht_sektionen": BERICHT_SEKTIONEN,
    }
    return render(request, "stiftung/bericht_list.html", context)


def _get_corporate_context():
    """Holt Corporate-Identity-Einstellungen und CSS für Berichte."""
    from stiftung.utils.pdf_generator import pdf_generator
    corporate_settings = pdf_generator.get_corporate_settings()
    logo_base64 = pdf_generator.get_logo_base64(corporate_settings.get("logo_path", ""))
    css_content = pdf_generator.get_base_css(corporate_settings)
    return {
        "corporate_settings": corporate_settings,
        "logo_base64": logo_base64,
        "css_content": css_content,
    }


def _jahresbericht_context(jahr):
    """Phase 4: Aggregiert alle Daten für den Jahresbericht."""
    from stiftung.models import (
        DestinataerUnterstuetzung, LandAbrechnung, Verwaltungskosten,
    )

    # Förderungen (legacy)
    foerderungen = Foerderung.objects.filter(jahr=jahr).select_related("destinataer", "person")
    total_foerderungen_legacy = foerderungen.aggregate(total=Sum("betrag"))["total"] or 0

    # Unterstützungen (Phase 2 – neue Pipeline)
    unterstuetzungen = DestinataerUnterstuetzung.objects.filter(
        faellig_am__year=jahr
    ).exclude(status="storniert").select_related("destinataer", "konto")
    unterstuetzungen_ausgezahlt = unterstuetzungen.filter(
        status__in=["ausgezahlt", "abgeschlossen"]
    )
    total_unterstuetzungen = unterstuetzungen_ausgezahlt.aggregate(total=Sum("betrag"))["total"] or 0

    # Gesamtausgaben Förderung
    total_ausgaben_foerderung = total_foerderungen_legacy + total_unterstuetzungen

    # Verpachtungen
    verpachtungen = LandVerpachtung.objects.filter(
        pachtbeginn__year__lte=jahr
    ).filter(
        Q(pachtende__isnull=True) | Q(pachtende__year__gte=jahr)
    ).select_related("land", "paechter")
    total_pachtzins = verpachtungen.aggregate(total=Sum("pachtzins_pauschal"))["total"] or 0

    # Landabrechnungen für das Jahr
    landabrechnungen = LandAbrechnung.objects.filter(
        abrechnungsjahr=jahr
    ).select_related("land")
    pacht_vereinnahmt = landabrechnungen.aggregate(total=Sum("pacht_vereinnahmt"))["total"] or 0
    grundsteuer_gesamt = landabrechnungen.aggregate(total=Sum("grundsteuer_betrag"))["total"] or 0

    # Verwaltungskosten
    verwaltungskosten_qs = Verwaltungskosten.objects.filter(datum__year=jahr)
    total_verwaltungskosten = verwaltungskosten_qs.aggregate(total=Sum("betrag"))["total"] or 0
    verwaltungskosten_nach_kategorie = (
        verwaltungskosten_qs
        .values("kategorie")
        .annotate(summe=Sum("betrag"), anzahl=Count("id"))
        .order_by("-summe")
    )

    # Gesamtbilanz
    total_einnahmen = pacht_vereinnahmt if pacht_vereinnahmt else total_pachtzins
    total_ausgaben = total_ausgaben_foerderung + total_verwaltungskosten
    netto = total_einnahmen - total_ausgaben

    context = {
        "jahr": jahr,
        "title": f"Jahresbericht {jahr}",
        "foerderungen": foerderungen,
        "total_foerderungen_legacy": total_foerderungen_legacy,
        "unterstuetzungen": unterstuetzungen,
        "unterstuetzungen_ausgezahlt": unterstuetzungen_ausgezahlt,
        "total_unterstuetzungen": total_unterstuetzungen,
        "total_ausgaben_foerderung": total_ausgaben_foerderung,
        "verpachtungen": verpachtungen,
        "total_pachtzins": total_pachtzins,
        "landabrechnungen": landabrechnungen,
        "pacht_vereinnahmt": pacht_vereinnahmt,
        "grundsteuer_gesamt": grundsteuer_gesamt,
        "verwaltungskosten_nach_kategorie": verwaltungskosten_nach_kategorie,
        "total_verwaltungskosten": total_verwaltungskosten,
        "total_einnahmen": total_einnahmen,
        "total_ausgaben": total_ausgaben,
        "netto": netto,
        "total_foerderungen": total_ausgaben_foerderung,
        "show_cover": True,
        "bericht_titel": f"Jahresbericht {jahr}",
        "bericht_untertitel": "Gesamtübersicht des Geschäftsjahres",
        "berichtszeitraum": str(jahr),
    }
    context.update(_get_corporate_context())
    return context


@login_required
def jahresbericht_generate(request, jahr):
    """Phase 4: Jahresbericht mit aggregierten Finanzdaten."""
    context = _jahresbericht_context(jahr)
    return render(request, "stiftung/jahresbericht.html", context)


@login_required
def jahresbericht_generate_redirect(request):
    """Redirects the GET form without path param to the proper URL using the provided query param 'jahr'."""
    jahr = request.GET.get("jahr")
    if jahr and str(jahr).isdigit():
        return redirect("stiftung:jahresbericht_generate", jahr=int(jahr))
    messages.error(request, "Bitte wählen Sie ein gültiges Jahr aus.")
    return redirect("stiftung:bericht_list")


@login_required
def jahresbericht_pdf(request, jahr):
    """Phase 4: PDF-Export des Jahresberichts via PDFGenerator."""
    from django.template.loader import render_to_string
    from stiftung.utils.pdf_generator import pdf_generator

    context = _jahresbericht_context(jahr)
    html_string = render_to_string("stiftung/jahresbericht.html", context)
    return pdf_generator.generate_pdf_response(
        html_string, f"jahresbericht_{jahr}.pdf", context.get("css_content")
    )


# =============================================================================
# MODULARE BERICHTE – Berichts-Baukasten
# =============================================================================

# Verfügbare Sektionen mit Metadaten
BERICHT_SEKTIONEN = {
    "bilanz": {"label": "Jahresbilanz", "icon": "fa-balance-scale", "needs_jahr": True},
    "unterstuetzungen": {"label": "Unterstützungszahlungen", "icon": "fa-hand-holding-heart", "needs_jahr": True},
    "foerderungen": {"label": "Förderungen", "icon": "fa-gift", "needs_jahr": True},
    "grundstuecke": {"label": "Grundstücksverwaltung", "icon": "fa-map", "needs_jahr": True},
    "verwaltungskosten": {"label": "Verwaltungskosten", "icon": "fa-file-invoice-dollar", "needs_jahr": True},
    "destinataere_uebersicht": {"label": "Destinatär-Übersicht", "icon": "fa-users", "needs_jahr": False},
    "konten_uebersicht": {"label": "Kontenübersicht", "icon": "fa-university", "needs_jahr": False},
    "verpachtungen": {"label": "Pachtbericht", "icon": "fa-handshake", "needs_jahr": False},
}

# Vordefinierte Berichtstypen
BERICHT_VORLAGEN = {
    "jahresbericht": {
        "label": "Jahresbericht",
        "beschreibung": "Vollständige Übersicht eines Geschäftsjahres",
        "sektionen": ["bilanz", "unterstuetzungen", "foerderungen", "grundstuecke", "verwaltungskosten"],
        "needs_jahr": True,
        "icon": "fa-calendar-alt",
    },
    "destinataerbericht": {
        "label": "Destinatärbericht",
        "beschreibung": "Übersicht aller Destinatäre mit Förderstatus",
        "sektionen": ["destinataere_uebersicht", "unterstuetzungen", "foerderungen"],
        "needs_jahr": True,
        "icon": "fa-users",
    },
    "grundstuecksbericht": {
        "label": "Grundstücksbericht",
        "beschreibung": "Liegenschaftsübersicht mit Pachtverträgen",
        "sektionen": ["grundstuecke", "verpachtungen"],
        "needs_jahr": True,
        "icon": "fa-map",
    },
    "finanzbericht": {
        "label": "Finanzbericht",
        "beschreibung": "Einnahmen/Ausgaben und Kontenübersicht",
        "sektionen": ["bilanz", "konten_uebersicht", "verwaltungskosten"],
        "needs_jahr": True,
        "icon": "fa-euro-sign",
    },
    "foerderbericht": {
        "label": "Förderbericht",
        "beschreibung": "Detailansicht aller Förderungen",
        "sektionen": ["foerderungen", "unterstuetzungen"],
        "needs_jahr": True,
        "icon": "fa-gift",
    },
    "pachtbericht": {
        "label": "Pachtbericht",
        "beschreibung": "Pachtzinseinnahmen und Vertragsübersicht",
        "sektionen": ["verpachtungen", "grundstuecke"],
        "needs_jahr": True,
        "icon": "fa-handshake",
    },
}


def _build_section_context(sektionen, jahr=None):
    """Baut den Context für die gewählten Sektionen zusammen."""
    from stiftung.models import (
        DestinataerUnterstuetzung, LandAbrechnung, Verwaltungskosten,
    )
    context = {}

    if jahr:
        context["jahr"] = jahr

    needs_jahresbericht = any(s in sektionen for s in [
        "bilanz", "unterstuetzungen", "foerderungen", "grundstuecke", "verwaltungskosten"
    ])
    if needs_jahresbericht and jahr:
        jb = _jahresbericht_context(jahr)
        context.update(jb)

    if "destinataere_uebersicht" in sektionen:
        from django.db.models import Count, Sum as DSum
        qs = Destinataer.objects.all()
        context["destinataere_aktiv"] = qs.filter(aktiv=True).count()
        context["destinataere_gesamt"] = qs.count()

        # Annotate with support stats
        if jahr:
            dest_qs = qs.annotate(
                unterstuetzung_count=Count(
                    "unterstuetzungen",
                    filter=Q(unterstuetzungen__faellig_am__year=jahr),
                ),
                unterstuetzung_summe=Coalesce(
                    DSum(
                        "unterstuetzungen__betrag",
                        filter=Q(
                            unterstuetzungen__faellig_am__year=jahr,
                            unterstuetzungen__status__in=["ausgezahlt", "abgeschlossen"],
                        ),
                    ),
                    Decimal("0"),
                ),
            )
        else:
            dest_qs = qs.annotate(
                unterstuetzung_count=Count("unterstuetzungen"),
                unterstuetzung_summe=Coalesce(
                    DSum(
                        "unterstuetzungen__betrag",
                        filter=Q(unterstuetzungen__status__in=["ausgezahlt", "abgeschlossen"]),
                    ),
                    Decimal("0"),
                ),
            )
        context["destinataere_liste"] = dest_qs.order_by("nachname", "vorname")
        context["destinataere_total_unterstuetzung"] = (
            dest_qs.aggregate(total=DSum("unterstuetzung_summe"))["total"] or 0
        )

    if "konten_uebersicht" in sektionen:
        konten = StiftungsKonto.objects.filter(aktiv=True).order_by("bank_name", "kontoname")
        context["konten_liste"] = konten
        context["konten_anzahl"] = konten.count()
        context["konten_gesamtsaldo"] = konten.aggregate(total=Sum("saldo"))["total"] or 0

    if "verpachtungen" in sektionen:
        from datetime import timedelta
        heute = date.today()
        in_12_monaten = heute + timedelta(days=365)

        aktive = LandVerpachtung.objects.filter(
            status="aktiv"
        ).select_related("land", "paechter")

        auslaufend = aktive.filter(
            pachtende__isnull=False,
            pachtende__lte=in_12_monaten,
            pachtende__gte=heute,
        ).order_by("pachtende")

        total_flaeche = aktive.aggregate(total=Sum("verpachtete_flaeche"))["total"] or 0
        total_pz = aktive.aggregate(total=Sum("pachtzins_pauschal"))["total"] or 0

        context["pacht_statistik"] = {
            "aktive_vertraege": aktive.count(),
            "total_pachtzins": total_pz,
            "total_flaeche": total_flaeche,
            "auslaufend_12m": auslaufend.count(),
        }
        context["pacht_auslaufend"] = auslaufend
        # Also provide full list if not already from jahresbericht
        if "verpachtungen" not in context or not context.get("verpachtungen"):
            if jahr:
                context["verpachtungen"] = LandVerpachtung.objects.filter(
                    pachtbeginn__year__lte=jahr
                ).filter(
                    Q(pachtende__isnull=True) | Q(pachtende__year__gte=jahr)
                ).select_related("land", "paechter")
            else:
                context["verpachtungen"] = aktive

    return context


@login_required
def bericht_zusammenstellen(request):
    """Modularer Bericht: Sektionen auswählen und zusammenstellen."""
    if request.method == "POST":
        sektionen = request.POST.getlist("sektionen")
        jahr_str = request.POST.get("jahr", "")
        show_cover = request.POST.get("show_cover") == "on"
        output_format = request.POST.get("format", "html")
        vorlage = request.POST.get("vorlage", "")

        # Vorlage anwenden falls gewählt
        if vorlage and vorlage in BERICHT_VORLAGEN and not sektionen:
            sektionen = BERICHT_VORLAGEN[vorlage]["sektionen"]

        if not sektionen:
            messages.error(request, "Bitte wählen Sie mindestens eine Sektion aus.")
            return redirect("stiftung:bericht_list")

        jahr = int(jahr_str) if jahr_str and jahr_str.isdigit() else None

        # Build context
        context = _build_section_context(sektionen, jahr)
        context["sektionen"] = sektionen
        context["show_cover"] = show_cover

        # Set titles
        if vorlage and vorlage in BERICHT_VORLAGEN:
            titel = BERICHT_VORLAGEN[vorlage]["label"]
        else:
            titel = "Bericht"
        if jahr:
            context["bericht_titel"] = f"{titel} {jahr}"
            context["berichtszeitraum"] = str(jahr)
        else:
            context["bericht_titel"] = titel
            context["berichtszeitraum"] = "Aktuell"

        context["bericht_untertitel"] = BERICHT_VORLAGEN.get(vorlage, {}).get("beschreibung", "")

        # Add corporate context if not already present
        if "corporate_settings" not in context:
            context.update(_get_corporate_context())

        if output_format == "pdf":
            from django.template.loader import render_to_string
            from stiftung.utils.pdf_generator import pdf_generator
            html_string = render_to_string("berichte/bericht_modular.html", context)
            filename = f"bericht_{vorlage or 'custom'}_{jahr or 'aktuell'}.pdf"
            return pdf_generator.generate_pdf_response(
                html_string, filename, context.get("css_content")
            )
        else:
            return render(request, "berichte/bericht_modular.html", context)

    # GET: Redirect to bericht_list
    return redirect("stiftung:bericht_list")


@login_required
def bericht_vorlage(request, vorlage_key):
    """Schnellzugriff: Vordefinierte Berichtsvorlage generieren."""
    if vorlage_key not in BERICHT_VORLAGEN:
        messages.error(request, f"Unbekannter Berichtstyp: {vorlage_key}")
        return redirect("stiftung:bericht_list")

    vorlage = BERICHT_VORLAGEN[vorlage_key]
    jahr_str = request.GET.get("jahr", "")
    jahr = int(jahr_str) if jahr_str and jahr_str.isdigit() else None
    output_format = request.GET.get("format", "html")

    if vorlage["needs_jahr"] and not jahr:
        messages.error(request, "Bitte wählen Sie ein Jahr für diesen Bericht.")
        return redirect("stiftung:bericht_list")

    context = _build_section_context(vorlage["sektionen"], jahr)
    context["sektionen"] = vorlage["sektionen"]
    context["show_cover"] = True
    context["bericht_titel"] = f"{vorlage['label']}" + (f" {jahr}" if jahr else "")
    context["bericht_untertitel"] = vorlage["beschreibung"]
    context["berichtszeitraum"] = str(jahr) if jahr else "Aktuell"

    if "corporate_settings" not in context:
        context.update(_get_corporate_context())

    if output_format == "pdf":
        from django.template.loader import render_to_string
        from stiftung.utils.pdf_generator import pdf_generator
        html_string = render_to_string("berichte/bericht_modular.html", context)
        filename = f"{vorlage_key}_{jahr or 'aktuell'}.pdf"
        return pdf_generator.generate_pdf_response(
            html_string, filename, context.get("css_content")
        )
    else:
        return render(request, "berichte/bericht_modular.html", context)


# API Views for AJAX
@login_required
def geschaeftsfuehrung(request):
    """Hauptansicht für die Geschäftsführung mit Übersicht"""
    from datetime import datetime, timedelta

    from django.db.models import Count, Sum

    from stiftung.models import Rentmeister, StiftungsKonto, Verwaltungskosten

    # Rentmeister-Übersicht
    rentmeister = Rentmeister.objects.filter(aktiv=True).order_by("nachname", "vorname")

    # Konten-Übersicht
    konten = StiftungsKonto.objects.filter(aktiv=True).order_by(
        "bank_name", "kontoname"
    )
    gesamtsaldo = konten.aggregate(total=Sum("saldo"))["total"] or 0

    # Aktuelle Kosten (letzten 30 Tage)
    heute = datetime.now().date()
    vor_30_tagen = heute - timedelta(days=30)

    aktuelle_kosten = Verwaltungskosten.objects.filter(
        datum__gte=vor_30_tagen
    ).order_by("-datum")[:10]

    # Statistiken
    kosten_summe_monat = (
        Verwaltungskosten.objects.filter(datum__gte=vor_30_tagen).aggregate(
            total=Sum("betrag")
        )["total"]
        or 0
    )

    kosten_statistik = (
        Verwaltungskosten.objects.filter(datum__gte=vor_30_tagen)
        .values("kategorie")
        .annotate(summe=Sum("betrag"), anzahl=Count("id"))
        .order_by("-summe")
    )

    context = {
        "rentmeister": rentmeister,
        "konten": konten,
        "gesamtsaldo": gesamtsaldo,
        "aktuelle_kosten": aktuelle_kosten,
        "kosten_summe_monat": kosten_summe_monat,
        "kosten_statistik": kosten_statistik,
    }

    return render(request, "stiftung/geschaeftsfuehrung.html", context)


@login_required
def konto_list(request):
    """Liste aller Stiftungskonten"""
    from django.db.models import Sum

    from stiftung.models import StiftungsKonto

    konten = StiftungsKonto.objects.all().order_by("bank_name", "kontoname")
    gesamtsaldo = konten.aggregate(total=Sum("saldo"))["total"] or 0

    context = {
        "konten": konten,
        "gesamtsaldo": gesamtsaldo,
    }

    return render(request, "stiftung/konto_list.html", context)


@login_required
def verwaltungskosten_list(request):
    """Liste aller Verwaltungskosten"""
    from django.core.paginator import Paginator

    from stiftung.models import Verwaltungskosten

    kosten = Verwaltungskosten.objects.all().order_by("-datum", "-erstellt_am")

    # Filter nach Kategorie
    kategorie_filter = request.GET.get("kategorie")
    if kategorie_filter:
        kosten = kosten.filter(kategorie=kategorie_filter)

    # Filter nach Status
    status_filter = request.GET.get("status")
    if status_filter:
        kosten = kosten.filter(status=status_filter)

    # Pagination
    paginator = Paginator(kosten, 25)
    page_number = request.GET.get("page")
    page_obj = paginator.get_page(page_number)

    # Für Filter-Dropdowns
    kategorien = Verwaltungskosten.KATEGORIE_CHOICES
    status_choices = Verwaltungskosten.STATUS_CHOICES

    context = {
        "page_obj": page_obj,
        "kategorien": kategorien,
        "status_choices": status_choices,
        "kategorie_filter": kategorie_filter,
        "status_filter": status_filter,
    }

    return render(request, "stiftung/verwaltungskosten_list.html", context)


@login_required
def verwaltungskosten_detail(request, pk):
    """Detailansicht einer Verwaltungskosten-Position mit verknüpften Dokumenten und E-Mails."""
    from stiftung.models import DokumentDatei, EmailEingang, Verwaltungskosten

    vk = get_object_or_404(Verwaltungskosten, pk=pk)

    if request.method == "POST":
        action = request.POST.get("action")
        if action == "set_status":
            new_status = request.POST.get("status", "")
            if new_status in dict(Verwaltungskosten.STATUS_CHOICES):
                vk.status = new_status
                vk.save()
                messages.success(request, f"Status auf '{vk.get_status_display()}' gesetzt.")
        return redirect("stiftung:verwaltungskosten_detail", pk=pk)

    # Verknüpfte DMS-Dokumente
    dms_dokumente = DokumentDatei.objects.filter(verwaltungskosten=vk).order_by("erstellt_am")

    # Verknüpfte E-Mails
    email_eingaenge = EmailEingang.objects.filter(verwaltungskosten=vk).order_by("-eingangsdatum")

    context = {
        "vk": vk,
        "dms_dokumente": dms_dokumente,
        "email_eingaenge": email_eingaenge,
        "status_choices": Verwaltungskosten.STATUS_CHOICES,
    }
    return render(request, "stiftung/verwaltungskosten_detail.html", context)


@login_required
def rentmeister_list(request):
    """Liste aller Rentmeister"""
    from stiftung.models import Rentmeister

    rentmeister = Rentmeister.objects.all().order_by("nachname", "vorname")

    # Aktive/Inaktive aufteilen
    aktive_rentmeister = rentmeister.filter(aktiv=True)
    ehemalige_rentmeister = rentmeister.filter(aktiv=False)

    context = {
        "aktive_rentmeister": aktive_rentmeister,
        "ehemalige_rentmeister": ehemalige_rentmeister,
        "total_count": rentmeister.count(),
    }

    return render(request, "stiftung/rentmeister_list.html", context)


@login_required
def rentmeister_detail(request, pk):
    """Detailansicht eines Rentmeisters mit seinen Ausgaben"""
    from datetime import datetime, timedelta

    from django.db.models import Count, Q, Sum

    from stiftung.models import Rentmeister, Verwaltungskosten

    rentmeister = get_object_or_404(Rentmeister, pk=pk)

    # Ausgaben des Rentmeisters
    ausgaben = Verwaltungskosten.objects.filter(rentmeister=rentmeister).order_by(
        "-datum"
    )

    # Statistiken
    heute = datetime.now().date()
    aktueller_monat = heute.replace(day=1)
    aktuelles_jahr = heute.replace(month=1, day=1)

    stats = {
        "gesamt_ausgaben": ausgaben.aggregate(total=Sum("betrag"))["total"] or 0,
        "monat_ausgaben": ausgaben.filter(datum__gte=aktueller_monat).aggregate(
            total=Sum("betrag")
        )["total"]
        or 0,
        "jahr_ausgaben": ausgaben.filter(datum__gte=aktuelles_jahr).aggregate(
            total=Sum("betrag")
        )["total"]
        or 0,
        "anzahl_ausgaben": ausgaben.count(),
        "offene_ausgaben": ausgaben.exclude(status="bezahlt").count(),
    }

    # Kategorie-Aufschlüsselung
    kategorie_stats = (
        ausgaben.values("kategorie")
        .annotate(summe=Sum("betrag"), anzahl=Count("id"))
        .order_by("-summe")
    )

    # Aktuelle Ausgaben (letzten 30 Tage)
    vor_30_tagen = heute - timedelta(days=30)
    aktuelle_ausgaben = ausgaben.filter(datum__gte=vor_30_tagen)[:10]

    # Verknüpfte Dokumente laden
    from stiftung.models import DokumentLink

    verknuepfte_dokumente = DokumentLink.objects.filter(
        rentmeister_id=rentmeister.id
    ).order_by("-id")[
        :10
    ]  # Neueste 10 Dokumente

    context = {
        "rentmeister": rentmeister,
        "ausgaben": ausgaben[:20],  # Nur erste 20 für Übersicht
        "stats": stats,
        "kategorie_stats": kategorie_stats,
        "aktuelle_ausgaben": aktuelle_ausgaben,
        "verknuepfte_dokumente": verknuepfte_dokumente,
    }

    return render(request, "stiftung/rentmeister_detail.html", context)


@login_required
def rentmeister_ausgaben(request, pk):
    """Vollständige Ausgabenliste eines Rentmeisters mit PDF Export"""
    from django.core.paginator import Paginator
    from django.db import models
    from django.db.models import Count, Q, Sum

    from stiftung.models import Rentmeister, Verwaltungskosten

    rentmeister = get_object_or_404(Rentmeister, pk=pk)

    # Handle PDF export request
    if request.method == "POST" and "export_pdf" in request.POST:
        selected_ids = request.POST.getlist("selected_expenses")
        if selected_ids:
            # Update status to 'in_bearbeitung' and log each change
            from stiftung.audit import log_action

            expenses_to_update = Verwaltungskosten.objects.filter(
                id__in=selected_ids, rentmeister=rentmeister
            )

            updated_count = 0
            for expense in expenses_to_update:
                old_status = expense.status
                expense.status = "in_bearbeitung"
                expense.save()
                updated_count += 1

                # Log the status change
                log_action(
                    request=request,
                    action="update",
                    entity_type="verwaltungskosten",
                    entity_id=str(expense.pk),
                    entity_name=expense.bezeichnung,
                    description=f'Ausgaben-Status für PDF-Export geändert von "{old_status}" zu "in_bearbeitung"',
                    changes={"status": {"old": old_status, "new": "in_bearbeitung"}},
                )

            messages.success(
                request,
                f"{updated_count} Ausgaben wurden zur Bearbeitung markiert und sind bereit für PDF Export.",
            )
            return redirect(
                "stiftung:rentmeister_ausgaben_pdf",
                pk=pk,
                expense_ids=",".join(selected_ids),
            )

    # Get expenses grouped by status
    ausgaben_by_status = {}
    for status_code, status_name in Verwaltungskosten.STATUS_CHOICES:
        ausgaben_by_status[status_code] = {
            "name": status_name,
            "ausgaben": Verwaltungskosten.objects.filter(
                rentmeister=rentmeister, status=status_code
            ).order_by("-datum", "-erstellt_am"),
            "total": Verwaltungskosten.objects.filter(
                rentmeister=rentmeister, status=status_code
            ).aggregate(total=Sum("betrag"))["total"]
            or 0,
        }

    # Get statistics
    stats = Verwaltungskosten.objects.filter(rentmeister=rentmeister).aggregate(
        total_count=Count("id"),
        total_amount=Sum("betrag"),
        geplant_count=Count("id", filter=Q(status="geplant")),
        geplant_amount=Sum("betrag", filter=Q(status="geplant")),
        in_bearbeitung_count=Count("id", filter=Q(status="in_bearbeitung")),
        in_bearbeitung_amount=Sum("betrag", filter=Q(status="in_bearbeitung")),
        bezahlt_count=Count("id", filter=Q(status="bezahlt")),
        bezahlt_amount=Sum("betrag", filter=Q(status="bezahlt")),
    )

    context = {
        "rentmeister": rentmeister,
        "ausgaben_by_status": ausgaben_by_status,
        "stats": stats,
        "kategorien": Verwaltungskosten.KATEGORIE_CHOICES,
        "status_choices": Verwaltungskosten.STATUS_CHOICES,
    }

    return render(request, "stiftung/rentmeister_ausgaben.html", context)


@login_required
def rentmeister_create(request):
    """Erstelle einen neuen Rentmeister"""
    from stiftung.forms import RentmeisterForm

    if request.method == "POST":
        form = RentmeisterForm(request.POST)
        if form.is_valid():
            rentmeister = form.save()
            messages.success(
                request,
                f"Rentmeister {rentmeister.get_full_name()} wurde erfolgreich angelegt.",
            )
            return redirect("stiftung:rentmeister_detail", pk=rentmeister.pk)
    else:
        form = RentmeisterForm()

    context = {
        "form": form,
        "title": "Neuen Rentmeister anlegen",
        "submit_text": "Rentmeister anlegen",
    }

    return render(request, "stiftung/rentmeister_form.html", context)


@login_required
def rentmeister_edit(request, pk):
    """Bearbeite einen bestehenden Rentmeister"""
    from stiftung.forms import RentmeisterForm
    from stiftung.models import Rentmeister

    rentmeister = get_object_or_404(Rentmeister, pk=pk)

    if request.method == "POST":
        form = RentmeisterForm(request.POST, instance=rentmeister)
        if form.is_valid():
            rentmeister = form.save()
            messages.success(
                request,
                f"Rentmeister {rentmeister.get_full_name()} wurde erfolgreich aktualisiert.",
            )
            return redirect("stiftung:rentmeister_detail", pk=rentmeister.pk)
    else:
        form = RentmeisterForm(instance=rentmeister)

    context = {
        "form": form,
        "rentmeister": rentmeister,
        "title": f"{rentmeister.get_full_name()} bearbeiten",
        "submit_text": "Änderungen speichern",
    }

    return render(request, "stiftung/rentmeister_form.html", context)


@login_required
def konto_create(request):
    """Erstelle ein neues Stiftungskonto"""
    from stiftung.forms import StiftungsKontoForm

    if request.method == "POST":
        form = StiftungsKontoForm(request.POST)
        if form.is_valid():
            konto = form.save()
            messages.success(
                request, f"Konto {konto.kontoname} wurde erfolgreich angelegt."
            )
            return redirect("stiftung:konto_list")
    else:
        form = StiftungsKontoForm()

    context = {
        "form": form,
        "title": "Neues Konto anlegen",
        "submit_text": "Konto anlegen",
    }

    return render(request, "stiftung/konto_form.html", context)


@login_required
def konto_edit(request, pk):
    """Bearbeite ein bestehendes Stiftungskonto"""
    from stiftung.forms import StiftungsKontoForm
    from stiftung.models import StiftungsKonto

    konto = get_object_or_404(StiftungsKonto, pk=pk)

    if request.method == "POST":
        form = StiftungsKontoForm(request.POST, instance=konto)
        if form.is_valid():
            konto = form.save()
            messages.success(
                request, f"Konto {konto.kontoname} wurde erfolgreich aktualisiert."
            )
            return redirect("stiftung:konto_list")
    else:
        form = StiftungsKontoForm(instance=konto)

    context = {
        "form": form,
        "konto": konto,
        "title": f"Konto {konto.kontoname} bearbeiten",
        "submit_text": "Änderungen speichern",
    }

    return render(request, "stiftung/konto_form.html", context)


@login_required
def konto_detail(request, pk):
    """Zeige Details eines Stiftungskontos"""
    from django.db import models
    from django.db.models import Count, Max, Q, Sum

    from stiftung.models import BankTransaction, StiftungsKonto

    konto = get_object_or_404(StiftungsKonto, pk=pk)

    # Get transaction statistics
    transactions = BankTransaction.objects.filter(konto=konto)
    transaction_stats = transactions.aggregate(
        total_count=Count("id"),
        total_eingang=Sum("betrag", filter=Q(betrag__gt=0)),
        total_ausgang=Sum("betrag", filter=Q(betrag__lt=0)),
        last_transaction_date=Max("datum"),
    )

    # Recent transactions
    recent_transactions = transactions.order_by("-datum", "-importiert_am")[:10]

    context = {
        "konto": konto,
        "transaction_stats": transaction_stats,
        "recent_transactions": recent_transactions,
    }

    return render(request, "stiftung/konto_detail.html", context)


@login_required
def verwaltungskosten_create(request):
    """Erstelle neue Verwaltungskosten"""
    from stiftung.forms import VerwaltungskostenForm
    from stiftung.models import Rentmeister

    # Check if we're coming from a specific Rentmeister
    rentmeister_id = request.GET.get("rentmeister")
    initial_data = {}
    redirect_url = "stiftung:verwaltungskosten_list"

    if rentmeister_id:
        try:
            rentmeister = Rentmeister.objects.get(pk=rentmeister_id)
            initial_data["rentmeister"] = rentmeister
            redirect_url = "stiftung:rentmeister_detail"
        except Rentmeister.DoesNotExist:
            pass

    if request.method == "POST":
        form = VerwaltungskostenForm(request.POST)
        if form.is_valid():
            kosten = form.save()
            messages.success(
                request,
                f'Verwaltungskosten "{kosten.bezeichnung}" wurden erfolgreich angelegt.',
            )
            if rentmeister_id:
                return redirect(redirect_url, pk=rentmeister_id)
            return redirect("stiftung:verwaltungskosten_list")
    else:
        form = VerwaltungskostenForm(initial=initial_data)

    context = {
        "form": form,
        "title": "Neue Verwaltungskosten anlegen",
        "submit_text": "Kosten anlegen",
    }

    return render(request, "stiftung/verwaltungskosten_form.html", context)


@login_required
def verwaltungskosten_edit(request, pk):
    """Bearbeite bestehende Verwaltungskosten"""
    from stiftung.forms import VerwaltungskostenForm
    from stiftung.models import DokumentDatei, Verwaltungskosten

    verwaltungskosten = get_object_or_404(Verwaltungskosten, pk=pk)

    if request.method == "POST":
        form = VerwaltungskostenForm(request.POST, instance=verwaltungskosten)
        if form.is_valid():
            verwaltungskosten = form.save()
            messages.success(
                request,
                f'Verwaltungskosten "{verwaltungskosten.bezeichnung}" wurden erfolgreich aktualisiert.',
            )
            return redirect("stiftung:verwaltungskosten_detail", pk=pk)
    else:
        form = VerwaltungskostenForm(instance=verwaltungskosten)

    # Verknüpfte DMS-Dokumente
    dms_dokumente = DokumentDatei.objects.filter(verwaltungskosten=verwaltungskosten).order_by("erstellt_am")

    context = {
        "form": form,
        "verwaltungskosten": verwaltungskosten,
        "dms_dokumente": dms_dokumente,
        "title": f"Verwaltungskosten bearbeiten: {verwaltungskosten.bezeichnung}",
        "submit_text": "Änderungen speichern",
    }

    return render(request, "stiftung/verwaltungskosten_form.html", context)


@login_required
def verwaltungskosten_delete(request, pk):
    """Lösche Verwaltungskosten"""
    from stiftung.models import Verwaltungskosten

    verwaltungskosten = get_object_or_404(Verwaltungskosten, pk=pk)

    if request.method == "POST":
        bezeichnung = verwaltungskosten.bezeichnung
        
        # Log the deletion
        from stiftung.audit import log_action
        log_action(
            request=request,
            action="delete",
            entity_type="verwaltungskosten",
            entity_id=str(verwaltungskosten.pk),
            entity_name=bezeichnung,
            description=f'Verwaltungskosten "{bezeichnung}" wurden gelöscht',
        )
        
        verwaltungskosten.delete()
        messages.success(
            request,
            f'Verwaltungskosten "{bezeichnung}" wurden erfolgreich gelöscht.',
        )
        return redirect("stiftung:verwaltungskosten_list")

    context = {
        "verwaltungskosten": verwaltungskosten,
        "title": f"Verwaltungskosten löschen: {verwaltungskosten.bezeichnung}",
    }

    return render(request, "stiftung/verwaltungskosten_delete.html", context)


@login_required
def mark_expense_paid(request):
    """Markiere eine Ausgabe als bezahlt"""
    if request.method == "POST":
        expense_id = request.POST.get("expense_id")
        if expense_id:
            try:
                from stiftung.models import Verwaltungskosten

                expense = Verwaltungskosten.objects.get(pk=expense_id)
                old_status = expense.status
                expense.status = "bezahlt"
                expense.save()

                # Log the status change
                from stiftung.audit import log_action

                log_action(
                    request=request,
                    action="update",
                    entity_type="verwaltungskosten",
                    entity_id=str(expense.pk),
                    entity_name=expense.bezeichnung,
                    description=f'Ausgaben-Status geändert von "{old_status}" zu "bezahlt"',
                    changes={"status": {"old": old_status, "new": "bezahlt"}},
                )

                messages.success(
                    request,
                    f'Ausgabe "{expense.bezeichnung}" wurde als bezahlt markiert.',
                )
                return redirect(
                    "stiftung:rentmeister_ausgaben", pk=expense.rentmeister.pk
                )
            except Verwaltungskosten.DoesNotExist:
                messages.error(request, "Ausgabe nicht gefunden.")

    return redirect("stiftung:verwaltungskosten_list")


# =============================================================================
# ADMINISTRATION VIEWS
# =============================================================================


