# views/foerderung.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,
                     DokumentDatei, 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 foerderung_list(request):
    """List all funding grants with filtering and pagination"""
    foerderungen = Foerderung.objects.select_related(
        "destinataer", "verwendungsnachweis"
    ).all()

    # Check for export request - handle both GET and POST
    export_format = (
        request.POST.get("format")
        if request.method == "POST"
        else request.GET.get("format", "")
    )
    selected_ids_param = (
        request.POST.get("selected_entries", "")
        if request.method == "POST"
        else request.GET.get("selected_entries", "")
    )
    selected_ids = (
        [id for id in selected_ids_param.split(",") if id] if selected_ids_param else []
    )

    # Filtering
    jahr = request.GET.get("jahr")
    kategorie = request.GET.get("kategorie")
    status = request.GET.get("status")
    destinataer = request.GET.get("destinataer")

    if jahr:
        foerderungen = foerderungen.filter(jahr=int(jahr))
    if kategorie:
        foerderungen = foerderungen.filter(kategorie=kategorie)
    if status:
        foerderungen = foerderungen.filter(status=status)
    if destinataer:
        foerderungen = foerderungen.filter(destinataer__nachname__icontains=destinataer)

    # Handle exports
    if export_format == "csv":
        return export_foerderungen_csv(request, foerderungen, selected_ids)
    elif export_format == "pdf":
        return export_foerderungen_pdf(request, foerderungen, selected_ids)

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

    # Statistics
    total_betrag = foerderungen.aggregate(total=Sum("betrag"))["total"] or 0
    avg_betrag = foerderungen.aggregate(avg=Avg("betrag"))["avg"] or 0

    # Year choices for filters
    jahre = sorted(
        set(list(Foerderung.objects.values_list("jahr", flat=True))), reverse=True
    )

    context = {
        "page_obj": page_obj,
        "foerderungen": foerderungen,  # Add for counting
        "total_betrag": total_betrag,
        "avg_betrag": avg_betrag,
        "kategorien": Foerderung.KATEGORIE_CHOICES,
        "status_choices": Foerderung.STATUS_CHOICES,
        "filter_jahr": jahr,
        "filter_kategorie": kategorie,
        "filter_status": status,
        "filter_person": destinataer,
        "jahre": jahre,
    }
    return render(request, "stiftung/foerderung_list.html", context)


@login_required
def foerderung_detail(request, pk):
    """Show details of a specific funding grant"""
    foerderung = get_object_or_404(
        Foerderung.objects.select_related("person", "verwendungsnachweis"), pk=pk
    )

    # Alle mit dieser Förderung verknüpften Dokumente laden
    verknuepfte_dokumente = DokumentDatei.objects.filter(
        foerderung=foerderung
    ).order_by("kontext", "titel")

    context = {
        "foerderung": foerderung,
        "verknuepfte_dokumente": verknuepfte_dokumente,
        "title": f"Förderung: {foerderung}",
    }
    return render(request, "stiftung/foerderung_detail.html", context)


@login_required
def foerderung_create(request):
    """Create a new funding grant"""
    # Get destinataer from URL parameter if provided
    destinataer_id = request.GET.get("destinataer")
    initial = {}
    if destinataer_id:
        initial["destinataer"] = destinataer_id

    if request.method == "POST":
        form = FoerderungForm(request.POST)
        if form.is_valid():
            foerderung = form.save()
            messages.success(
                request,
                f"Förderung für {foerderung.destinataer} wurde erfolgreich erstellt.",
            )
            return redirect("stiftung:foerderung_detail", pk=foerderung.pk)
    else:
        form = FoerderungForm(initial=initial)

    context = {
        "form": form,
        "title": "Neue Förderung erstellen",
    }
    return render(request, "stiftung/foerderung_form.html", context)


@login_required
def foerderung_update(request, pk):
    """Update an existing funding grant"""
    foerderung = get_object_or_404(Foerderung, pk=pk)

    if request.method == "POST":
        form = FoerderungForm(request.POST, instance=foerderung)
        if form.is_valid():
            form.save()
            messages.success(
                request,
                f"Förderung für {foerderung.person} wurde erfolgreich aktualisiert.",
            )
            return redirect("stiftung:foerderung_detail", pk=foerderung.pk)
    else:
        form = FoerderungForm(instance=foerderung)

    context = {
        "form": form,
        "foerderung": foerderung,
        "title": f"Förderung bearbeiten: {foerderung}",
    }
    return render(request, "stiftung/foerderung_form.html", context)


@login_required
def foerderung_delete(request, pk):
    """Delete a funding grant"""
    foerderung = get_object_or_404(Foerderung, pk=pk)

    if request.method == "POST":
        # Get the recipient name before deletion
        recipient_name = (
            foerderung.destinataer.get_full_name()
            if foerderung.destinataer
            else (
                foerderung.person.get_full_name()
                if foerderung.person
                else "Unbekannter Empfänger"
            )
        )

        foerderung.delete()
        messages.success(
            request, f"Förderung für {recipient_name} wurde erfolgreich gelöscht."
        )
        return redirect("stiftung:foerderung_list")

    context = {
        "foerderung": foerderung,
        "title": f"Förderung löschen: {foerderung}",
    }
    return render(request, "stiftung/foerderung_confirm_delete.html", context)


# DokumentLink Views
