"""Views für den web-basierten Dokument-Vorlagen-Editor."""

from django.contrib import messages
from django.contrib.auth.decorators import login_required
from django.http import HttpResponse, JsonResponse
from django.shortcuts import get_object_or_404, redirect, render
from django.views.decorators.http import require_POST

from stiftung.models import DokumentVorlage
from stiftung.utils.vorlagen import get_vorlage_original


@login_required
def vorlagen_liste(request):
    """Übersicht aller Dokument-Vorlagen nach Kategorie."""
    vorlagen = DokumentVorlage.objects.select_related("zuletzt_bearbeitet_von").all()

    kategorien = {}
    for v in vorlagen:
        if v.kategorie not in kategorien:
            kategorien[v.kategorie] = []
        kategorien[v.kategorie].append(v)

    # Kategorie-Labels
    kategorie_labels = dict(DokumentVorlage.KATEGORIE_CHOICES)

    return render(request, "stiftung/vorlagen_liste.html", {
        "kategorien": kategorien,
        "kategorie_labels": kategorie_labels,
        "vorlagen_count": vorlagen.count(),
    })


@login_required
def vorlage_editor(request, pk):
    """Editor für eine einzelne Vorlage."""
    vorlage = get_object_or_404(DokumentVorlage, pk=pk)

    if request.method == "POST":
        html_inhalt = request.POST.get("html_inhalt", "")
        vorlage.html_inhalt = html_inhalt
        vorlage.zuletzt_bearbeitet_von = request.user
        vorlage.save()
        messages.success(request, f'Vorlage „{vorlage.bezeichnung}" wurde gespeichert.')
        return redirect("stiftung:vorlage_editor", pk=pk)

    try:
        original = get_vorlage_original(vorlage.schluessel)
        hat_original = True
    except FileNotFoundError:
        original = None
        hat_original = False

    import json
    from django.utils.safestring import mark_safe
    # JSON-encode and escape </script> to prevent XSS in script tag
    html_json = json.dumps(vorlage.html_inhalt)
    html_json = html_json.replace("<", "\\u003c").replace(">", "\\u003e")

    # All templates contain Django template tags ({{ }}, {% %}) that
    # Summernote WYSIWYG mangles on save. Use plain code editor for all.
    use_code_editor = True

    return render(request, "stiftung/vorlage_editor.html", {
        "vorlage": vorlage,
        "hat_original": hat_original,
        "variablen": vorlage.verfuegbare_variablen,
        "html_inhalt_json": mark_safe(html_json),
        "use_code_editor": use_code_editor,
    })


@login_required
@require_POST
def vorlage_zuruecksetzen(request, pk):
    """Setzt eine Vorlage auf den Datei-Original-Inhalt zurück."""
    vorlage = get_object_or_404(DokumentVorlage, pk=pk)
    try:
        original = get_vorlage_original(vorlage.schluessel)
        vorlage.html_inhalt = original
        vorlage.zuletzt_bearbeitet_von = request.user
        vorlage.save()
        messages.success(request, f'Vorlage „{vorlage.bezeichnung}" wurde auf die Original-Datei zurückgesetzt.')
    except FileNotFoundError:
        messages.error(request, "Original-Datei nicht gefunden. Zurücksetzen nicht möglich.")
    return redirect("stiftung:vorlage_editor", pk=pk)


@login_required
@require_POST
def vorlagen_alle_zuruecksetzen(request):
    """Setzt ALLE Vorlagen auf die Original-Datei-Inhalte zurück."""
    vorlagen = DokumentVorlage.objects.all()
    restored = 0
    for vorlage in vorlagen:
        try:
            original = get_vorlage_original(vorlage.schluessel)
            vorlage.html_inhalt = original
            vorlage.zuletzt_bearbeitet_von = request.user
            vorlage.save()
            restored += 1
        except FileNotFoundError:
            pass
    messages.success(request, f"{restored} Vorlage(n) auf Original zurückgesetzt.")
    return redirect("stiftung:vorlagen_liste")


@login_required
def vorlage_vorschau(request, pk):
    """Rendert eine Vorschau der Vorlage mit Beispieldaten (JSON-Response)."""
    vorlage = get_object_or_404(DokumentVorlage, pk=pk)

    # Rohinhalt aus POST (live-preview) oder aus DB
    html_inhalt = request.POST.get("html_inhalt") if request.method == "POST" else vorlage.html_inhalt

    # Einfache Beispieldaten je Kategorie
    beispiel_context = _get_beispiel_context(vorlage.schluessel)

    try:
        from django.template import Context, Engine
        engine = Engine.get_default()
        t = engine.from_string(html_inhalt)
        rendered = t.render(Context(beispiel_context))
        return HttpResponse(rendered, content_type="text/html; charset=utf-8")
    except Exception as exc:
        return HttpResponse(
            f"<pre style='color:red'>Template-Fehler: {exc}</pre>",
            content_type="text/html; charset=utf-8",
        )


def _get_beispiel_context(schluessel: str) -> dict:
    """Gibt Beispieldaten für Vorschau-Rendering zurück."""
    from datetime import date, time

    class FakeObj(dict):
        def __getattr__(self, k):
            return self.get(k, "")

    destinataer = FakeObj(
        vorname="Maria",
        nachname="Mustermann",
        anrede="Frau",
        strasse="Musterstraße 1",
        plz="46499",
        ort="Hamminkeln",
        email="m.mustermann@example.com",
    )

    einladung = FakeObj(
        vorname="Maria",
        nachname="Mustermann",
        email="m.mustermann@example.com",
    )

    base = {
        "destinataer": destinataer,
        "einladung": einladung,
        "datum": date.today(),
        "zeitraum": "01.01.2025 – 31.12.2025",
        "betrag_quartal": 500,
        "betrag_jaehrlich": 2000,
        "gesamtbetrag": 2000,
        "zweck": "Studienförderung",
        "unterstuetzungen": [],
        "halbjahr_label": "1. Halbjahr 2025",
        "upload_url": "https://vhtv-stiftung.de/portal/upload/beispiel-token/",
        "gueltig_bis": date.today(),
        "qr_code_base64": "",
        "ist_erinnerung": False,
        "onboarding_url": "https://vhtv-stiftung.de/portal/onboarding/beispiel/",
        "veranstaltung": FakeObj(titel="Stiftungsessen 2025"),
        "teilnehmer_list": [],
    }

    # Serienbrief-Vorlage: vollständige Veranstaltungs- und Teilnehmer-Beispieldaten
    if "serienbrief" in schluessel:
        base["veranstaltung"] = FakeObj(
            titel="Stiftungsessen 2025",
            datum=date.today(),
            uhrzeit=time(18, 0),
            ort="Gasthaus zur Linde",
            adresse="Lindenstraße 12, 46499 Hamminkeln",
            betreff="",
            briefvorlage="",
            unterschrift_1_name="Katrin Kleinpaß",
            unterschrift_1_titel="Rentmeisterin",
            unterschrift_2_name="Jan Remmer Siebels",
            unterschrift_2_titel="Rentmeister",
        )
        base["teilnehmer"] = [
            FakeObj(
                anrede="Frau",
                vorname="Maria",
                nachname="Mustermann",
                strasse="Musterstraße 1",
                plz="46499",
                ort="Hamminkeln",
            ),
            FakeObj(
                anrede="Herr",
                vorname="Hans",
                nachname="Beispiel",
                strasse="Beispielweg 7",
                plz="46499",
                ort="Hamminkeln",
            ),
        ]

    return base
