import re

from django import forms
from django.core.exceptions import ValidationError

from ..models import BankTransaction, Rentmeister, StiftungsKonto, Verwaltungskosten


class RentmeisterForm(forms.ModelForm):
    """Form für das Erstellen und Bearbeiten von Rentmeistern"""

    class Meta:
        model = Rentmeister
        fields = [
            "anrede",
            "vorname",
            "nachname",
            "titel",
            "email",
            "telefon",
            "mobil",
            "strasse",
            "plz",
            "ort",
            "iban",
            "bic",
            "bank_name",
            "seit_datum",
            "bis_datum",
            "aktiv",
            "monatliche_verguetung",
            "km_pauschale",
            "notizen",
        ]

        widgets = {
            "anrede": forms.Select(attrs={"class": "form-select"}),
            "vorname": forms.TextInput(attrs={"class": "form-control"}),
            "nachname": forms.TextInput(attrs={"class": "form-control"}),
            "titel": forms.TextInput(attrs={"class": "form-control"}),
            "email": forms.EmailInput(attrs={"class": "form-control"}),
            "telefon": forms.TextInput(attrs={"class": "form-control"}),
            "mobil": forms.TextInput(attrs={"class": "form-control"}),
            "strasse": forms.TextInput(attrs={"class": "form-control"}),
            "plz": forms.TextInput(attrs={"class": "form-control"}),
            "ort": forms.TextInput(attrs={"class": "form-control"}),
            "iban": forms.TextInput(
                attrs={"class": "form-control", "placeholder": "DE89370400440532013000"}
            ),
            "bic": forms.TextInput(
                attrs={"class": "form-control", "placeholder": "COBADEFFXXX"}
            ),
            "bank_name": forms.TextInput(attrs={"class": "form-control"}),
            "seit_datum": forms.DateInput(
                attrs={"class": "form-control", "type": "date"}
            ),
            "bis_datum": forms.DateInput(
                attrs={"class": "form-control", "type": "date"}
            ),
            "aktiv": forms.CheckboxInput(attrs={"class": "form-check-input"}),
            "monatliche_verguetung": forms.NumberInput(
                attrs={"class": "form-control", "step": "0.01"}
            ),
            "km_pauschale": forms.NumberInput(
                attrs={"class": "form-control", "step": "0.01", "value": "0.30"}
            ),
            "notizen": forms.Textarea(attrs={"class": "form-control", "rows": 4}),
        }

        labels = {
            "anrede": "Anrede",
            "vorname": "Vorname *",
            "nachname": "Nachname *",
            "titel": "Titel",
            "email": "E-Mail",
            "telefon": "Telefon",
            "mobil": "Mobil",
            "strasse": "Straße",
            "plz": "PLZ",
            "ort": "Ort",
            "iban": "IBAN",
            "bic": "BIC",
            "bank_name": "Bank",
            "seit_datum": "Rentmeister seit *",
            "bis_datum": "Rentmeister bis",
            "aktiv": "Aktiv",
            "monatliche_verguetung": "Monatliche Vergütung (€)",
            "km_pauschale": "Kilometerpauschale (€/km)",
            "notizen": "Notizen",
        }

        help_texts = {
            "iban": "Internationale Bankkontonummer für Abrechnungen",
            "km_pauschale": "Standard: 0,30 € pro Kilometer",
            "seit_datum": "Datum des Amtsantritts als Rentmeister",
            "bis_datum": "Leer lassen für aktive Rentmeister",
        }

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        # Markiere Pflichtfelder
        self.fields["vorname"].required = True
        self.fields["nachname"].required = True
        self.fields["seit_datum"].required = True

    def clean_iban(self):
        """Validierung der IBAN"""
        iban = self.cleaned_data.get("iban")
        if iban:
            # Entferne Leerzeichen und konvertiere zu Großbuchstaben
            iban = re.sub(r"\s+", "", iban.upper())

            # Einfache IBAN-Längenvalidierung für deutsche IBANs
            if iban.startswith("DE") and len(iban) != 22:
                raise ValidationError("Deutsche IBANs müssen 22 Zeichen lang sein.")

            # Speichere die bereinigte IBAN
            return iban
        return iban

    def clean_plz(self):
        """Validierung der PLZ"""
        plz = self.cleaned_data.get("plz")
        if plz and not re.match(r"^\d{5}$", plz):
            raise ValidationError("PLZ muss aus 5 Ziffern bestehen.")
        return plz

    def clean(self):
        """Übergreifende Validierung"""
        from django.utils.dateparse import parse_date

        cleaned_data = super().clean()
        seit_datum = cleaned_data.get("seit_datum")
        bis_datum = cleaned_data.get("bis_datum")

        # Helper function to ensure we have date objects
        def ensure_date(date_value):
            if not date_value:
                return None
            if isinstance(date_value, str):
                return parse_date(date_value)
            return date_value

        # Convert to date objects if they're strings
        seit_datum = ensure_date(seit_datum)
        bis_datum = ensure_date(bis_datum)

        # Prüfe Datum-Logik
        if seit_datum and bis_datum and bis_datum <= seit_datum:
            raise ValidationError("Das End-Datum muss nach dem Start-Datum liegen.")

        return cleaned_data


class StiftungsKontoForm(forms.ModelForm):
    """Form für das Erstellen und Bearbeiten von Stiftungskonten"""

    class Meta:
        model = StiftungsKonto
        fields = [
            "kontoname",
            "bank_name",
            "iban",
            "bic",
            "konto_typ",
            "saldo",
            "saldo_datum",
            "zinssatz",
            "laufzeit_bis",
            "aktiv",
            "notizen",
        ]

        widgets = {
            "kontoname": forms.TextInput(attrs={"class": "form-control"}),
            "bank_name": forms.TextInput(attrs={"class": "form-control"}),
            "iban": forms.TextInput(
                attrs={"class": "form-control", "placeholder": "DE89370400440532013000"}
            ),
            "bic": forms.TextInput(
                attrs={"class": "form-control", "placeholder": "COBADEFFXXX"}
            ),
            "konto_typ": forms.Select(attrs={"class": "form-select"}),
            "saldo": forms.NumberInput(attrs={"class": "form-control", "step": "0.01"}),
            "saldo_datum": forms.DateInput(
                attrs={"class": "form-control", "type": "date"}
            ),
            "zinssatz": forms.NumberInput(
                attrs={"class": "form-control", "step": "0.01"}
            ),
            "laufzeit_bis": forms.DateInput(
                attrs={"class": "form-control", "type": "date"}
            ),
            "aktiv": forms.CheckboxInput(attrs={"class": "form-check-input"}),
            "notizen": forms.Textarea(attrs={"class": "form-control", "rows": 3}),
        }


class VerwaltungskostenForm(forms.ModelForm):
    """Form für das Erstellen und Bearbeiten von Verwaltungskosten"""

    class Meta:
        model = Verwaltungskosten
        fields = [
            "bezeichnung",
            "kategorie",
            "betrag",
            "datum",
            "status",
            "rentmeister",
            "zahlungskonto",
            "quellkonto",
            "lieferant_firma",
            "rechnungsnummer",
            "km_anzahl",
            "km_satz",
            "von_ort",
            "nach_ort",
            "zweck",
            "beschreibung",
            "notizen",
        ]

        widgets = {
            "bezeichnung": forms.TextInput(attrs={"class": "form-control"}),
            "kategorie": forms.Select(attrs={"class": "form-select"}),
            "betrag": forms.NumberInput(
                attrs={"class": "form-control", "step": "0.01"}
            ),
            "datum": forms.DateInput(attrs={"class": "form-control", "type": "date"}),
            "status": forms.Select(attrs={"class": "form-select"}),
            "rentmeister": forms.Select(attrs={"class": "form-select"}),
            "zahlungskonto": forms.Select(attrs={"class": "form-select"}),
            "quellkonto": forms.Select(attrs={"class": "form-select"}),
            "lieferant_firma": forms.TextInput(attrs={"class": "form-control"}),
            "rechnungsnummer": forms.TextInput(attrs={"class": "form-control"}),
            "km_anzahl": forms.NumberInput(
                attrs={"class": "form-control", "step": "0.1"}
            ),
            "km_satz": forms.NumberInput(
                attrs={"class": "form-control", "step": "0.01"}
            ),
            "von_ort": forms.TextInput(attrs={"class": "form-control"}),
            "nach_ort": forms.TextInput(attrs={"class": "form-control"}),
            "zweck": forms.TextInput(attrs={"class": "form-control"}),
            "beschreibung": forms.Textarea(attrs={"class": "form-control", "rows": 3}),
            "notizen": forms.Textarea(attrs={"class": "form-control", "rows": 2}),
        }

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        # Filtere nur aktive Rentmeister und Konten
        self.fields["rentmeister"].queryset = Rentmeister.objects.filter(aktiv=True)
        self.fields["zahlungskonto"].queryset = StiftungsKonto.objects.filter(
            aktiv=True
        )
        self.fields["quellkonto"].queryset = StiftungsKonto.objects.filter(aktiv=True)

        # Standardwerte setzen
        if not self.instance.pk:  # Nur bei neuen Objekten
            # Standard km_satz auf 0.30 Euro setzen
            self.fields["km_satz"].initial = 0.30


class BankTransactionForm(forms.ModelForm):
    """Form für das Bearbeiten von Banktransaktionen"""

    class Meta:
        model = BankTransaction
        fields = [
            "konto",
            "datum",
            "valuta",
            "betrag",
            "waehrung",
            "verwendungszweck",
            "empfaenger_zahlungspflichtiger",
            "iban_gegenpartei",
            "bic_gegenpartei",
            "transaction_type",
            "status",
            "kommentare",
            "verwaltungskosten",
        ]

        widgets = {
            "konto": forms.Select(attrs={"class": "form-select"}),
            "datum": forms.DateInput(attrs={"class": "form-control", "type": "date"}),
            "valuta": forms.DateInput(attrs={"class": "form-control", "type": "date"}),
            "betrag": forms.NumberInput(
                attrs={"class": "form-control", "step": "0.01"}
            ),
            "waehrung": forms.TextInput(attrs={"class": "form-control"}),
            "verwendungszweck": forms.Textarea(
                attrs={"class": "form-control", "rows": 3}
            ),
            "empfaenger_zahlungspflichtiger": forms.TextInput(
                attrs={"class": "form-control"}
            ),
            "iban_gegenpartei": forms.TextInput(attrs={"class": "form-control"}),
            "bic_gegenpartei": forms.TextInput(attrs={"class": "form-control"}),
            "transaction_type": forms.Select(attrs={"class": "form-select"}),
            "status": forms.Select(attrs={"class": "form-select"}),
            "kommentare": forms.Textarea(attrs={"class": "form-control", "rows": 4}),
            "verwaltungskosten": forms.Select(attrs={"class": "form-select"}),
        }


class BankImportForm(forms.Form):
    """Form für den Import von Bankdaten"""

    konto = forms.ModelChoiceField(
        queryset=StiftungsKonto.objects.filter(aktiv=True),
        widget=forms.Select(attrs={"class": "form-select"}),
        label="Zielkonto",
    )

    datei = forms.FileField(
        widget=forms.FileInput(attrs={"class": "form-control", "accept": ".csv,.txt"}),
        label="Bankdatei",
        help_text="Unterstützte Formate: CSV, TXT (Sparkasse, Volksbank, etc.)",
    )

    encoding = forms.ChoiceField(
        choices=[
            ("utf-8", "UTF-8"),
            ("latin1", "Latin-1 / ISO-8859-1"),
            ("cp1252", "Windows-1252"),
        ],
        initial="utf-8",
        widget=forms.Select(attrs={"class": "form-select"}),
        label="Zeichenkodierung",
    )

    delimiter = forms.ChoiceField(
        choices=[
            (";", "Semikolon (;)"),
            (",", "Komma (,)"),
            ("\t", "Tab"),
        ],
        initial=";",
        widget=forms.Select(attrs={"class": "form-select"}),
        label="Trennzeichen",
    )

    skip_header = forms.BooleanField(
        initial=True,
        required=False,
        widget=forms.CheckboxInput(attrs={"class": "form-check-input"}),
        label="Erste Zeile überspringen (Spaltenüberschriften)",
    )
