import uuid

from django.db import models


class Rentmeister(models.Model):
    """Geschäftsführer der Stiftung (natürliche Personen)"""

    ANREDE_CHOICES = [
        ("herr", "Herr"),
        ("frau", "Frau"),
        ("dr", "Dr."),
        ("prof", "Prof."),
        ("prof_dr", "Prof. Dr."),
    ]

    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    anrede = models.CharField(
        max_length=10, choices=ANREDE_CHOICES, blank=True, verbose_name="Anrede"
    )
    vorname = models.CharField(max_length=100, verbose_name="Vorname")
    nachname = models.CharField(max_length=100, verbose_name="Nachname")
    titel = models.CharField(max_length=50, blank=True, verbose_name="Titel")

    # Kontaktdaten
    email = models.EmailField(blank=True, verbose_name="E-Mail")
    telefon = models.CharField(max_length=20, blank=True, verbose_name="Telefon")
    mobil = models.CharField(max_length=20, blank=True, verbose_name="Mobil")

    # Adresse
    strasse = models.CharField(max_length=200, blank=True, verbose_name="Straße")
    plz = models.CharField(max_length=10, blank=True, verbose_name="PLZ")
    ort = models.CharField(max_length=100, blank=True, verbose_name="Ort")

    # Bankdaten für Abrechnungen
    iban = models.CharField(max_length=34, blank=True, verbose_name="IBAN")
    bic = models.CharField(max_length=11, blank=True, verbose_name="BIC")
    bank_name = models.CharField(max_length=100, blank=True, verbose_name="Bank")

    # Stiftungs-spezifisch
    seit_datum = models.DateField(verbose_name="Rentmeister seit")
    bis_datum = models.DateField(null=True, blank=True, verbose_name="Rentmeister bis")
    aktiv = models.BooleanField(default=True, verbose_name="Aktiv")

    # Vergütung/Aufwandsentschädigung
    monatliche_verguetung = models.DecimalField(
        max_digits=8,
        decimal_places=2,
        null=True,
        blank=True,
        verbose_name="Monatliche Vergütung (€)",
    )
    km_pauschale = models.DecimalField(
        max_digits=4,
        decimal_places=2,
        default=0.30,
        verbose_name="Kilometerpauschale (€/km)",
    )

    notizen = models.TextField(blank=True, verbose_name="Notizen")

    erstellt_am = models.DateTimeField(auto_now_add=True)
    aktualisiert_am = models.DateTimeField(auto_now=True)

    class Meta:
        verbose_name = "Rentmeister"
        verbose_name_plural = "Rentmeister"
        ordering = ["nachname", "vorname"]

    def __str__(self):
        name_parts = []
        if self.anrede:
            name_parts.append(self.get_anrede_display())
        if self.vorname:
            name_parts.append(self.vorname)
        name_parts.append(self.nachname)
        if self.titel:
            name_parts.append(f"({self.titel})")
        return " ".join(name_parts)

    def get_full_name(self):
        """Vollständiger Name ohne Anrede"""
        if self.vorname:
            return f"{self.vorname} {self.nachname}"
        return self.nachname

    def get_address(self):
        """Vollständige Adresse als String"""
        parts = []
        if self.strasse:
            parts.append(self.strasse)
        if self.plz and self.ort:
            parts.append(f"{self.plz} {self.ort}")
        elif self.ort:
            parts.append(self.ort)
        return ", ".join(parts)


class StiftungsKonto(models.Model):
    """Bankkonten der Stiftung"""

    KONTO_TYP_CHOICES = [
        ("girokonto", "Girokonto"),
        ("sparkonto", "Sparkonto"),
        ("festgeld", "Festgeld"),
        ("tagesgeld", "Tagesgeld"),
        ("depot", "Depot"),
        ("sonstiges", "Sonstiges"),
    ]

    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    kontoname = models.CharField(max_length=200, verbose_name="Kontoname")
    bank_name = models.CharField(max_length=200, verbose_name="Bank")
    iban = models.CharField(max_length=34, verbose_name="IBAN")
    bic = models.CharField(max_length=11, blank=True, verbose_name="BIC")
    konto_typ = models.CharField(
        max_length=20,
        choices=KONTO_TYP_CHOICES,
        default="girokonto",
        verbose_name="Kontotyp",
    )
    saldo = models.DecimalField(
        max_digits=10, decimal_places=2, default=0.00, verbose_name="Aktueller Saldo"
    )
    saldo_datum = models.DateField(null=True, blank=True, verbose_name="Saldo-Datum")
    zinssatz = models.DecimalField(
        max_digits=5,
        decimal_places=2,
        null=True,
        blank=True,
        verbose_name="Zinssatz (%)",
    )
    laufzeit_bis = models.DateField(null=True, blank=True, verbose_name="Laufzeit bis")
    aktiv = models.BooleanField(default=True, verbose_name="Aktiv")
    notizen = models.TextField(blank=True, verbose_name="Notizen")

    erstellt_am = models.DateTimeField(auto_now_add=True)
    aktualisiert_am = models.DateTimeField(auto_now=True)

    class Meta:
        verbose_name = "Stiftungskonto"
        verbose_name_plural = "Stiftungskonten"
        ordering = ["bank_name", "kontoname"]

    def __str__(self):
        return f"{self.bank_name} - {self.kontoname}"


class BankTransaction(models.Model):
    """Banktransaktionen aus importierten Kontodaten"""

    TRANSACTION_TYPE_CHOICES = [
        ("eingang", "Eingang"),
        ("ausgang", "Ausgang"),
        ("lastschrift", "Lastschrift"),
        ("ueberweisung", "Überweisung"),
        ("dauerauftrag", "Dauerauftrag"),
        ("kartenzahlung", "Kartenzahlung"),
        ("zinsen", "Zinsen"),
        ("gebuehren", "Gebühren"),
        ("sonstiges", "Sonstiges"),
    ]

    STATUS_CHOICES = [
        ("imported", "Importiert"),
        ("verified", "Geprüft"),
        ("assigned", "Zugeordnet"),
        ("ignored", "Ignoriert"),
    ]

    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    konto = models.ForeignKey(
        StiftungsKonto, on_delete=models.CASCADE, verbose_name="Konto"
    )

    # Transaktionsdaten
    datum = models.DateField(verbose_name="Buchungsdatum")
    valuta = models.DateField(null=True, blank=True, verbose_name="Valutadatum")
    betrag = models.DecimalField(
        max_digits=12, decimal_places=2, verbose_name="Betrag (€)"
    )
    waehrung = models.CharField(max_length=3, default="EUR", verbose_name="Währung")

    # Transaktionsdetails
    verwendungszweck = models.TextField(verbose_name="Verwendungszweck")
    empfaenger_zahlungspflichtiger = models.CharField(
        max_length=200, blank=True, verbose_name="Empfänger/Zahlungspflichtiger"
    )
    iban_gegenpartei = models.CharField(
        max_length=34, blank=True, verbose_name="IBAN Gegenpartei"
    )
    bic_gegenpartei = models.CharField(
        max_length=11, blank=True, verbose_name="BIC Gegenpartei"
    )

    # Bankspezifische Daten
    referenz = models.CharField(
        max_length=100, blank=True, verbose_name="Referenz/Transaktions-ID"
    )
    transaction_type = models.CharField(
        max_length=20,
        choices=TRANSACTION_TYPE_CHOICES,
        default="sonstiges",
        verbose_name="Transaktionsart",
    )

    # Verwaltung
    status = models.CharField(
        max_length=20, choices=STATUS_CHOICES, default="imported", verbose_name="Status"
    )
    kommentare = models.TextField(blank=True, verbose_name="Kommentare")
    verwaltungskosten = models.ForeignKey(
        "Verwaltungskosten",
        null=True,
        blank=True,
        on_delete=models.SET_NULL,
        verbose_name="Zugeordnete Verwaltungskosten",
    )

    # Import-Metadaten
    import_datei = models.CharField(
        max_length=255, blank=True, verbose_name="Import-Datei"
    )
    importiert_am = models.DateTimeField(
        auto_now_add=True, verbose_name="Importiert am"
    )
    saldo_nach_buchung = models.DecimalField(
        max_digits=12,
        decimal_places=2,
        null=True,
        blank=True,
        verbose_name="Saldo nach Buchung",
    )

    class Meta:
        verbose_name = "Banktransaktion"
        verbose_name_plural = "Banktransaktionen"
        ordering = ["-datum", "-importiert_am"]
        unique_together = ["konto", "datum", "betrag", "referenz"]  # Prevent duplicates

    def __str__(self):
        return f"{self.datum} - {self.betrag}€ - {self.verwendungszweck[:50]}"

    def is_income(self):
        """Prüft ob es sich um einen Geldeingang handelt"""
        return self.betrag > 0

    def get_absolute_amount(self):
        """Gibt den absoluten Betrag zurück"""
        return abs(self.betrag)


class Verwaltungskosten(models.Model):
    """Administrative Kosten und Ausgaben der Stiftung"""

    KATEGORIE_CHOICES = [
        ("rechnung_intern", "Interne Rechnung"),
        ("bueroausstattung", "Büroausstattung"),
        ("fahrtkosten", "Fahrtkosten"),
        ("porto", "Porto & Versand"),
        ("telefon_internet", "Telefon & Internet"),
        ("software", "Software & Lizenzen"),
        ("beratung", "Beratung & Dienstleistungen"),
        ("versicherung", "Versicherungen"),
        ("steuerberatung", "Steuerberatung"),
        ("bankgebuehren", "Bankgebühren"),
        ("sonstiges", "Sonstiges"),
    ]

    STATUS_CHOICES = [
        ("geplant", "Geplant"),
        ("bestellt", "Bestellt"),
        ("erhalten", "Erhalten"),
        ("in_bearbeitung", "In Bearbeitung"),
        ("bezahlt", "Bezahlt"),
        ("storniert", "Storniert"),
    ]

    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    bezeichnung = models.CharField(max_length=200, verbose_name="Bezeichnung")
    kategorie = models.CharField(
        max_length=30, choices=KATEGORIE_CHOICES, verbose_name="Kategorie"
    )
    betrag = models.DecimalField(
        max_digits=10, decimal_places=2, verbose_name="Betrag (€)"
    )
    datum = models.DateField(verbose_name="Datum")
    lieferant_firma = models.CharField(
        max_length=200, blank=True, verbose_name="Lieferant/Firma"
    )
    rechnungsnummer = models.CharField(
        max_length=100, blank=True, verbose_name="Rechnungsnummer"
    )
    status = models.CharField(
        max_length=20, choices=STATUS_CHOICES, default="geplant", verbose_name="Status"
    )

    # Zuständigkeit und Zahlung
    rentmeister = models.ForeignKey(
        Rentmeister,
        on_delete=models.SET_NULL,
        null=True,
        blank=True,
        verbose_name="Zuständiger Rentmeister",
    )
    zahlungskonto = models.ForeignKey(
        StiftungsKonto,
        on_delete=models.SET_NULL,
        null=True,
        blank=True,
        related_name="zahlungen",
        verbose_name="Zahlungskonto",
    )
    quellkonto = models.ForeignKey(
        StiftungsKonto,
        on_delete=models.SET_NULL,
        null=True,
        blank=True,
        related_name="ausgaben",
        verbose_name="Quellkonto",
    )

    # Legacy field für Rückwärtskompatibilität
    konto = models.ForeignKey(
        StiftungsKonto,
        on_delete=models.SET_NULL,
        null=True,
        blank=True,
        verbose_name="Konto (Legacy)",
        help_text="Veraltet - verwende Zahlungskonto und Quellkonto",
    )

    # Fahrtkosten spezifisch
    km_anzahl = models.DecimalField(
        max_digits=8, decimal_places=1, null=True, blank=True, verbose_name="Kilometer"
    )
    km_satz = models.DecimalField(
        max_digits=4, decimal_places=2, null=True, blank=True, verbose_name="€/km"
    )
    von_ort = models.CharField(max_length=100, blank=True, verbose_name="Von (Ort)")
    nach_ort = models.CharField(max_length=100, blank=True, verbose_name="Nach (Ort)")
    zweck = models.CharField(max_length=200, blank=True, verbose_name="Zweck der Fahrt")

    beschreibung = models.TextField(blank=True, verbose_name="Beschreibung")
    notizen = models.TextField(blank=True, verbose_name="Notizen")

    erstellt_am = models.DateTimeField(auto_now_add=True)
    aktualisiert_am = models.DateTimeField(auto_now=True)

    class Meta:
        verbose_name = "Verwaltungskosten"
        verbose_name_plural = "Verwaltungskosten"
        ordering = ["-datum", "-erstellt_am"]

    def __str__(self):
        return f"{self.bezeichnung} - €{self.betrag} ({self.datum})"

    def get_status_color(self):
        colors = {
            "geplant": "secondary",
            "bestellt": "warning",
            "erhalten": "info",
            "in_bearbeitung": "primary",
            "bezahlt": "success",
            "storniert": "danger",
        }
        return colors.get(self.status, "secondary")

    def get_effective_zahlungskonto(self):
        """Gibt das Zahlungskonto zurück, fallback auf Legacy-Konto"""
        return self.zahlungskonto or self.konto

    def get_effective_quellkonto(self):
        """Gibt das Quellkonto zurück, fallback auf Zahlungskonto oder Legacy-Konto"""
        return self.quellkonto or self.zahlungskonto or self.konto

    def is_fahrtkosten(self):
        """Prüft ob es sich um Fahrtkosten handelt"""
        return self.kategorie == "fahrtkosten"

    def calculate_fahrtkosten(self):
        """Berechnet Fahrtkosten automatisch wenn km_anzahl und km_satz gesetzt sind"""
        if self.km_anzahl and self.km_satz:
            return self.km_anzahl * self.km_satz
        return None
