# models/dokumente.py
# Phase 3: Django-natives DMS – ersetzt Paperless-NGX-Integration
import uuid
import os

from django.contrib.postgres.indexes import GinIndex
from django.contrib.postgres.search import SearchVector, SearchVectorField
from django.db import models
from django.utils import timezone


def dokument_upload_path(instance, filename):
    """Speichert Dateien in MEDIA_ROOT/dokumente/YYYY/MM/<uuid>/<original_filename>"""
    ext = os.path.splitext(filename)[1].lower()
    safe_name = os.path.basename(filename)[:100]
    return f"dokumente/{timezone.now().strftime('%Y/%m')}/{instance.id}/{safe_name}"


class DokumentDatei(models.Model):
    """Nativ gespeicherte Datei im Django-DMS – ersetzt Paperless-Referenzen."""

    KONTEXT_CHOICES = [
        ("pachtvertrag", "Pachtvertrag"),
        ("antrag", "Antrag / Förderantrag"),
        ("verwendungsnachweis", "Verwendungsnachweis"),
        ("studiennachweis", "Studiennachweis"),
        ("rechnung", "Rechnung"),
        ("vertrag", "Vertrag"),
        ("bericht", "Bericht"),
        ("landkarte", "Landkarte / Kataster"),
        ("korrespondenz", "Korrespondenz / Brief"),
        ("bescheid", "Bescheid / Behörde"),
        ("stiftungsgeschichte", "Stiftungsgeschichte / Archiv"),
        ("email", "E-Mail-Nachricht"),
        ("anderes", "Sonstiges"),
    ]

    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    titel = models.CharField(max_length=255, verbose_name="Titel")
    beschreibung = models.TextField(blank=True, verbose_name="Beschreibung")
    kontext = models.CharField(
        max_length=30,
        choices=KONTEXT_CHOICES,
        default="anderes",
        verbose_name="Dokumententyp",
    )
    datei = models.FileField(
        upload_to=dokument_upload_path,
        verbose_name="Datei",
    )
    dateiname_original = models.CharField(
        max_length=255, blank=True, verbose_name="Originaldateiname"
    )
    dateityp = models.CharField(
        max_length=100, blank=True, verbose_name="MIME-Typ"
    )
    dateigroesse = models.PositiveIntegerField(
        default=0, verbose_name="Dateigröße (Bytes)"
    )

    # Volltext-Index (PostgreSQL FTS, befüllt per Signal)
    inhaltstext = models.TextField(
        blank=True,
        verbose_name="Extrahierter Textinhalt",
        help_text="Automatisch befüllt für PDF/TXT-Dateien. Basis für Volltextsuche.",
    )
    suchvektor = SearchVectorField(
        null=True, blank=True, verbose_name="Such-Vektor (FTS)"
    )

    # Zuordnungsfelder – optional, ein Dokument kann mehreren Entitäten gehören
    land = models.ForeignKey(
        "Land",
        on_delete=models.SET_NULL,
        null=True, blank=True,
        related_name="dms_dokumente",
        verbose_name="Länderei",
    )
    paechter = models.ForeignKey(
        "Paechter",
        on_delete=models.SET_NULL,
        null=True, blank=True,
        related_name="dms_dokumente",
        verbose_name="Pächter",
    )
    verpachtung = models.ForeignKey(
        "LandVerpachtung",
        on_delete=models.SET_NULL,
        null=True, blank=True,
        related_name="dms_dokumente",
        verbose_name="Verpachtung",
    )
    destinataer = models.ForeignKey(
        "Destinataer",
        on_delete=models.SET_NULL,
        null=True, blank=True,
        related_name="dms_dokumente",
        verbose_name="Destinatär",
    )
    foerderung = models.ForeignKey(
        "Foerderung",
        on_delete=models.SET_NULL,
        null=True, blank=True,
        related_name="dms_dokumente",
        verbose_name="Förderung",
    )
    rentmeister = models.ForeignKey(
        "Rentmeister",
        on_delete=models.SET_NULL,
        null=True, blank=True,
        related_name="dms_dokumente",
        verbose_name="Rentmeister",
    )
    verwaltungskosten = models.ForeignKey(
        "Verwaltungskosten",
        on_delete=models.SET_NULL,
        null=True, blank=True,
        related_name="dms_dokumente",
        verbose_name="Verwaltungskosten / Rechnung",
    )

    # Herkunft (optional: Verweis auf altes Paperless-Dokument zur Rückverfolgung)
    paperless_dokument_id = models.IntegerField(
        null=True, blank=True,
        verbose_name="Paperless-ID (Migration)",
        help_text="Wird nach vollständiger Migration entfernt.",
    )

    # Audit
    erstellt_von = models.ForeignKey(
        "auth.User",
        on_delete=models.SET_NULL,
        null=True, blank=True,
        related_name="hochgeladene_dokumente",
        verbose_name="Erstellt von",
    )
    erstellt_am = models.DateTimeField(auto_now_add=True, verbose_name="Erstellt am")
    aktualisiert_am = models.DateTimeField(auto_now=True, verbose_name="Aktualisiert am")

    class Meta:
        verbose_name = "Dokument"
        verbose_name_plural = "Dokumente (DMS)"
        ordering = ["-erstellt_am"]
        indexes = [
            # PostgreSQL GIN-Index für Volltextsuche
            GinIndex(fields=["suchvektor"], name="dms_suchvektor_gin_idx"),
            models.Index(fields=["kontext"]),
            models.Index(fields=["destinataer", "kontext"]),
            models.Index(fields=["land", "kontext"]),
            models.Index(fields=["paechter", "kontext"]),
        ]

    def __str__(self):
        return self.titel or self.dateiname_original or str(self.id)

    def save(self, *args, **kwargs):
        # Originaldateiname aus FileField ableiten
        if self.datei and not self.dateiname_original:
            self.dateiname_original = os.path.basename(self.datei.name)
        super().save(*args, **kwargs)

    def update_suchvektor(self):
        """Aktualisiert den Such-Vektor aus Titel, Beschreibung und Inhaltstext."""
        DokumentDatei.objects.filter(pk=self.pk).update(
            suchvektor=SearchVector("titel", weight="A")
            + SearchVector("beschreibung", weight="B")
            + SearchVector("inhaltstext", weight="C"),
        )

    def get_datei_url(self):
        """Gibt die Download-URL zurück."""
        if self.datei:
            return self.datei.url
        return None

    def is_pdf(self):
        return self.dateityp == "application/pdf" or (
            self.dateiname_original and self.dateiname_original.lower().endswith(".pdf")
        )

    def get_human_size(self):
        """Gibt die Dateigröße leserlich zurück."""
        size = self.dateigroesse
        if size < 1024:
            return f"{size} B"
        elif size < 1024 * 1024:
            return f"{size / 1024:.1f} KB"
        else:
            return f"{size / (1024 * 1024):.1f} MB"
