# views/dms.py
# Phase 3: Django-natives DMS – Dokumentenverwaltung ohne Paperless-NGX

import os
from datetime import date

from django.contrib import messages
from django.contrib.auth.decorators import login_required
from django.contrib.postgres.search import SearchQuery, SearchRank
from django.core.paginator import Paginator
from django.http import FileResponse, Http404, JsonResponse
from django.shortcuts import get_object_or_404, redirect, render
from django.utils import timezone
from django.views.decorators.http import require_POST

from stiftung.models import (
    Destinataer, DokumentDatei, Foerderung, Land, LandVerpachtung, Paechter, Rentmeister
)


# ---------------------------------------------------------------------------
# Hilfsfunktionen
# ---------------------------------------------------------------------------

def _save_upload(request, instance: DokumentDatei):
    """Speichert Upload-Metadaten (Dateityp, Größe, FTS)."""
    if instance.datei:
        f = instance.datei
        instance.dateiname_original = os.path.basename(f.name)
        instance.dateityp = getattr(f, "content_type", "") or ""
        instance.dateigroesse = f.size if hasattr(f, "size") else 0
        instance.erstellt_von = request.user
        instance.save()
        instance.update_suchvektor()


# ---------------------------------------------------------------------------
# DMS Hauptseiten
# ---------------------------------------------------------------------------

@login_required
def dms_list(request):
    """Dokumenten-Übersicht mit Filter und Suche."""
    q = request.GET.get("q", "").strip()
    kontext_filter = request.GET.get("kontext", "")
    entity_filter = request.GET.get("entity", "")   # z.B. "destinataer"
    entity_id = request.GET.get("entity_id", "")

    qs = DokumentDatei.objects.select_related(
        "destinataer", "land", "paechter", "verpachtung", "erstellt_von"
    )

    # Volltextsuche
    if q:
        search_query = SearchQuery(q, config="german")
        qs = qs.annotate(rank=SearchRank("suchvektor", search_query)).filter(
            rank__gt=0.01
        ).order_by("-rank")
    else:
        qs = qs.order_by("-erstellt_am")

    if kontext_filter:
        qs = qs.filter(kontext=kontext_filter)

    if entity_filter == "destinataer" and entity_id:
        qs = qs.filter(destinataer_id=entity_id)
    elif entity_filter == "land" and entity_id:
        qs = qs.filter(land_id=entity_id)
    elif entity_filter == "paechter" and entity_id:
        qs = qs.filter(paechter_id=entity_id)
    elif entity_filter == "verpachtung" and entity_id:
        qs = qs.filter(verpachtung_id=entity_id)

    paginator = Paginator(qs, 25)
    page_obj = paginator.get_page(request.GET.get("page"))

    context = {
        "page_obj": page_obj,
        "q": q,
        "kontext_filter": kontext_filter,
        "kontext_choices": DokumentDatei.KONTEXT_CHOICES,
        "gesamt": qs.count() if not q else paginator.count,
    }
    return render(request, "stiftung/dms/list.html", context)


@login_required
def dms_detail(request, pk):
    """Dokument-Detailseite mit Download-Link."""
    dok = get_object_or_404(DokumentDatei, pk=pk)
    context = {"dok": dok}
    return render(request, "stiftung/dms/detail.html", context)


@login_required
def dms_download(request, pk):
    """Direkter Datei-Download."""
    dok = get_object_or_404(DokumentDatei, pk=pk)
    if not dok.datei or not dok.datei.storage.exists(dok.datei.name):
        raise Http404("Datei nicht gefunden.")
    response = FileResponse(
        dok.datei.open("rb"),
        as_attachment=True,
        filename=dok.dateiname_original or os.path.basename(dok.datei.name),
    )
    return response


@login_required
def dms_upload(request):
    """HTMX-Drag&Drop-Upload – unterstützt normale POST-Anfragen und HTMX-Requests."""
    # Pre-fill entity links from GET params
    initial = {
        "destinataer_id": request.GET.get("destinataer", ""),
        "land_id": request.GET.get("land", ""),
        "paechter_id": request.GET.get("paechter", ""),
        "verpachtung_id": request.GET.get("verpachtung", ""),
        "foerderung_id": request.GET.get("foerderung", ""),
        "kontext": request.GET.get("kontext", "anderes"),
    }

    if request.method == "POST":
        datei = request.FILES.get("datei")
        titel = request.POST.get("titel", "").strip()
        beschreibung = request.POST.get("beschreibung", "").strip()
        kontext = request.POST.get("kontext", "anderes")

        if not datei:
            if request.htmx:
                return JsonResponse({"error": "Keine Datei übermittelt."}, status=400)
            messages.error(request, "Bitte eine Datei auswählen.")
        else:
            if not titel:
                titel = os.path.splitext(datei.name)[0][:255]

            dok = DokumentDatei(
                titel=titel,
                beschreibung=beschreibung,
                kontext=kontext,
                datei=datei,
            )

            # Entity links
            dest_id = request.POST.get("destinataer_id", "").strip()
            land_id = request.POST.get("land_id", "").strip()
            paechter_id = request.POST.get("paechter_id", "").strip()
            verp_id = request.POST.get("verpachtung_id", "").strip()
            foerd_id = request.POST.get("foerderung_id", "").strip()

            if dest_id:
                try:
                    dok.destinataer_id = dest_id
                except Exception:
                    pass
            if land_id:
                try:
                    dok.land_id = land_id
                except Exception:
                    pass
            if paechter_id:
                try:
                    dok.paechter_id = paechter_id
                except Exception:
                    pass
            if verp_id:
                try:
                    dok.verpachtung_id = verp_id
                except Exception:
                    pass
            if foerd_id:
                try:
                    dok.foerderung_id = foerd_id
                except Exception:
                    pass

            _save_upload(request, dok)

            if request.htmx:
                return render(request, "stiftung/dms/partials/upload_success.html", {"dok": dok})

            messages.success(request, f'Dokument \u201e{dok.titel}\u201c erfolgreich hochgeladen.')
            return redirect("stiftung:dms_detail", pk=dok.pk)

    # GET: zeige Upload-Formular
    destinataere = Destinataer.objects.filter(aktiv=True).order_by("nachname", "vorname")
    laendereien = Land.objects.filter(aktiv=True).order_by("lfd_nr")
    paechter_qs = Paechter.objects.filter(aktiv=True).order_by("nachname")

    context = {
        "initial": initial,
        "kontext_choices": DokumentDatei.KONTEXT_CHOICES,
        "destinataere": destinataere,
        "laendereien": laendereien,
        "paechter_qs": paechter_qs,
    }
    return render(request, "stiftung/dms/upload.html", context)


@login_required
@require_POST
def dms_delete(request, pk):
    """Löscht ein Dokument inkl. Datei."""
    dok = get_object_or_404(DokumentDatei, pk=pk)
    titel = dok.titel
    # Datei physisch löschen
    if dok.datei:
        try:
            dok.datei.delete(save=False)
        except Exception:
            pass
    dok.delete()
    messages.success(request, f'Dokument \u201e{titel}\u201c gel\u00f6scht.')

    next_url = request.POST.get("next") or "stiftung:dms_list"
    if next_url.startswith("/"):
        return redirect(next_url)
    return redirect(next_url)


@login_required
def dms_search_api(request):
    """HTMX-Suche: gibt gerendertes Partial mit Suchergebnissen zurück."""
    q = request.GET.get("q", "").strip()
    if not q:
        return render(request, "stiftung/dms/partials/search_results.html", {"results": []})

    search_query = SearchQuery(q, config="german")
    results = (
        DokumentDatei.objects.annotate(rank=SearchRank("suchvektor", search_query))
        .filter(rank__gt=0.01)
        .select_related("destinataer", "land")
        .order_by("-rank")[:20]
    )
    return render(
        request,
        "stiftung/dms/partials/search_results.html",
        {"results": results, "q": q},
    )


@login_required
def dms_edit(request, pk):
    """Bearbeite Metadaten eines Dokuments (kein Datei-Austausch)."""
    dok = get_object_or_404(DokumentDatei, pk=pk)

    if request.method == "POST":
        dok.titel = request.POST.get("titel", dok.titel).strip()[:255]
        dok.beschreibung = request.POST.get("beschreibung", "").strip()
        dok.kontext = request.POST.get("kontext", dok.kontext)

        # Entity assignments
        dest_id = request.POST.get("destinataer_id", "").strip()
        land_id = request.POST.get("land_id", "").strip()
        paechter_id = request.POST.get("paechter_id", "").strip()
        verp_id = request.POST.get("verpachtung_id", "").strip()

        dok.destinataer_id = dest_id if dest_id else None
        dok.land_id = land_id if land_id else None
        dok.paechter_id = paechter_id if paechter_id else None
        dok.verpachtung_id = verp_id if verp_id else None

        dok.save()
        dok.update_suchvektor()
        messages.success(request, "Metadaten gespeichert.")
        return redirect("stiftung:dms_detail", pk=dok.pk)

    destinataere = Destinataer.objects.filter(aktiv=True).order_by("nachname", "vorname")
    laendereien = Land.objects.filter(aktiv=True).order_by("lfd_nr")
    paechter_qs = Paechter.objects.filter(aktiv=True).order_by("nachname")
    verpachtungen = LandVerpachtung.objects.select_related("land", "paechter").order_by("-pachtbeginn")[:50]

    context = {
        "dok": dok,
        "kontext_choices": DokumentDatei.KONTEXT_CHOICES,
        "destinataere": destinataere,
        "laendereien": laendereien,
        "paechter_qs": paechter_qs,
        "verpachtungen": verpachtungen,
    }
    return render(request, "stiftung/dms/edit.html", context)
