from django import forms
from django.utils import timezone

from ..models import (Destinataer, DestinataerNotiz, DestinataerUnterstuetzung,
                      UnterstuetzungWiederkehrend, VierteljahresNachweis)
from django.core.exceptions import ValidationError


class DestinataerForm(forms.ModelForm):
    """Form für das Erstellen und Bearbeiten von Destinatären"""

    class Meta:
        model = Destinataer
        fields = "__all__"
        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"}),
            "strasse": forms.TextInput(attrs={"class": "form-control"}),
            "plz": forms.TextInput(attrs={"class": "form-control"}),
            "ort": forms.TextInput(attrs={"class": "form-control"}),
            "telefon": forms.TextInput(attrs={"class": "form-control"}),
            "mobil": forms.TextInput(attrs={"class": "form-control"}),
            "email": forms.EmailInput(attrs={"class": "form-control"}),
            "aktiv": forms.CheckboxInput(attrs={"class": "form-check-input"}),
            "notizen": forms.Textarea(attrs={"class": "form-control", "rows": 3}),
            "ist_abkoemmling": forms.CheckboxInput(attrs={"class": "form-check-input"}),
            "haushaltsgroesse": forms.NumberInput(
                attrs={"class": "form-control", "min": 1}
            ),
            "vermoegen": forms.NumberInput(
                attrs={"class": "form-control", "step": "0.01"}
            ),
            "unterstuetzung_bestaetigt": forms.CheckboxInput(
                attrs={"class": "form-check-input"}
            ),
            "standard_konto": forms.Select(attrs={"class": "form-select"}, choices=[(None, "---")] + [(c.pk, str(c)) for c in getattr(Destinataer, 'konten_queryset', lambda: [])()]),
            "vierteljaehrlicher_betrag": forms.NumberInput(
                attrs={"class": "form-control", "step": "0.01"}
            ),
            "studiennachweis_erforderlich": forms.CheckboxInput(
                attrs={"class": "form-check-input"}
            ),
            "letzter_studiennachweis": forms.DateInput(
                attrs={"class": "form-control", "type": "date"}
            ),
            "familienzweig": forms.Select(attrs={"class": "form-select"}),
            "berufsgruppe": forms.Select(attrs={"class": "form-select"}),
        }

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        for field_name, field in self.fields.items():
            if field_name not in ["vorname", "nachname"]:
                field.required = False
        # Set choices for familienzweig, berufsgruppe and anrede to match model
        self.fields["familienzweig"].choices = [("", "Bitte wählen...")] + list(Destinataer.FAMILIENZWIG_CHOICES)
        self.fields["berufsgruppe"].choices = [("", "Bitte wählen...")] + list(Destinataer.BERUFSGRUPPE_CHOICES)
        if "anrede" in self.fields:
            self.fields["anrede"].choices = [("", "Bitte wählen...")] + list(Destinataer.ANREDE_CHOICES)
        # Set choices for standard_konto to allow blank
        self.fields["standard_konto"].empty_label = "---"


class DestinataerUnterstuetzungForm(forms.ModelForm):
    """Form für geplante/ausgeführte Destinatärunterstützungen"""

    class Meta:
        model = DestinataerUnterstuetzung
        fields = [
            "destinataer",
            "konto",
            "betrag",
            "faellig_am",
            "status",
            "beschreibung",
            "empfaenger_iban",
            "empfaenger_name",
            "verwendungszweck",
        ]
        widgets = {
            "destinataer": forms.Select(attrs={"class": "form-select"}),
            "konto": forms.Select(attrs={"class": "form-select"}),
            "betrag": forms.NumberInput(
                attrs={"class": "form-control", "step": "0.01"}
            ),
            "faellig_am": forms.DateInput(
                attrs={"class": "form-control", "type": "date"}
            ),
            "status": forms.Select(attrs={"class": "form-select"}),
            "beschreibung": forms.TextInput(attrs={"class": "form-control"}),
            "empfaenger_iban": forms.TextInput(
                attrs={"class": "form-control", "placeholder": "DE89 3704 0044 0532 0130 00"}
            ),
            "empfaenger_name": forms.TextInput(
                attrs={"class": "form-control", "placeholder": "Max Mustermann"}
            ),
            "verwendungszweck": forms.TextInput(
                attrs={"class": "form-control", "placeholder": "Vierteljährliche Unterstützung Q1/2025"}
            ),
        }

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)

        # Make faellig_am read-only for automatically generated quarterly payments
        self.is_auto_generated = False
        if self.instance and self.instance.pk and self.instance.beschreibung:
            if "Vierteljährliche Unterstützung" in self.instance.beschreibung and "(automatisch erstellt)" in self.instance.beschreibung:
                self.is_auto_generated = True

                # Use a TextInput widget with readonly attribute to display the date
                from django import forms
                current_date = self.instance.faellig_am
                if current_date:
                    self.fields['faellig_am'].widget = forms.TextInput(
                        attrs={
                            "class": "form-control",
                            "readonly": True,
                            "value": current_date.strftime('%d.%m.%Y'),  # German date format
                            "style": "background-color: #f8f9fa; cursor: not-allowed;"
                        }
                    )
                    self.fields['faellig_am'].initial = current_date

                self.fields['faellig_am'].help_text = "Fälligkeitsdatum wird automatisch basierend auf Quartal berechnet"

    def clean(self):
        cleaned_data = super().clean()

        # For auto-generated payments, preserve the original due date
        if self.is_auto_generated and self.instance and self.instance.pk:
            cleaned_data['faellig_am'] = self.instance.faellig_am

        return cleaned_data


class DestinataerNotizForm(forms.ModelForm):
    class Meta:
        model = DestinataerNotiz
        fields = ["titel", "text", "datei"]
        widgets = {
            "titel": forms.TextInput(
                attrs={
                    "class": "form-control",
                    "placeholder": "z.B. Telefonat vom 29.08.2025",
                }
            ),
            "text": forms.Textarea(
                attrs={
                    "class": "form-control",
                    "rows": 5,
                    "placeholder": "Notiztext...",
                }
            ),
            "datei": forms.ClearableFileInput(attrs={"class": "form-control"}),
        }

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        # Make all fields optional
        self.fields["datei"].required = False
        self.fields["titel"].required = False
        self.fields["text"].required = False

    def clean(self):
        cleaned = super().clean()
        titel = cleaned.get("titel", "").strip()
        text = cleaned.get("text", "").strip()
        if not (titel or text):
            raise forms.ValidationError(
                "Bitte geben Sie einen Titel oder einen Text ein."
            )
        return cleaned


class UnterstuetzungForm(forms.ModelForm):
    """Form für das Erstellen und Bearbeiten von Unterstützungen"""

    # Special field for creating recurring payments
    ist_wiederkehrend = forms.BooleanField(
        required=False,
        label="Wiederkehrende Zahlung",
        help_text="Aktivieren Sie diese Option um automatisch wiederkehrende Zahlungen zu erstellen",
    )
    intervall = forms.ChoiceField(
        choices=[("", "--- Wählen Sie ein Intervall ---")]
        + UnterstuetzungWiederkehrend.INTERVALL_CHOICES,
        required=False,
        widget=forms.Select(attrs={"class": "form-select"}),
        label="Zahlungsintervall",
    )
    letzte_zahlung_am = forms.DateField(
        required=False,
        widget=forms.DateInput(attrs={"class": "form-control", "type": "date"}),
        label="Letzte Zahlung am (optional)",
        help_text="Leer lassen für unbegrenzte Wiederholung",
    )

    class Meta:
        model = DestinataerUnterstuetzung
        fields = [
            "destinataer",
            "konto",
            "faellig_am",
            "betrag",
            "status",
            "beschreibung",
            "empfaenger_iban",
            "empfaenger_name",
            "verwendungszweck",
        ]

        widgets = {
            "destinataer": forms.Select(attrs={"class": "form-select"}),
            "konto": forms.Select(attrs={"class": "form-select"}),
            "faellig_am": forms.DateInput(
                attrs={"class": "form-control", "type": "date"}
            ),
            "betrag": forms.NumberInput(
                attrs={"class": "form-control", "step": "0.01"}
            ),
            "status": forms.Select(attrs={"class": "form-select"}),
            "beschreibung": forms.TextInput(attrs={"class": "form-control"}),
            "empfaenger_iban": forms.TextInput(
                attrs={
                    "class": "form-control",
                    "placeholder": "DE89 3704 0044 0532 0130 00",
                }
            ),
            "empfaenger_name": forms.TextInput(attrs={"class": "form-control"}),
            "verwendungszweck": forms.TextInput(
                attrs={"class": "form-control", "maxlength": "140"}
            ),
        }

        labels = {
            "destinataer": "Destinatär",
            "konto": "Zahlungskonto",
            "faellig_am": "Fällig am",
            "betrag": "Betrag (€)",
            "status": "Status",
            "beschreibung": "Beschreibung",
            "empfaenger_iban": "Empfänger IBAN",
            "empfaenger_name": "Empfänger Name",
            "verwendungszweck": "Verwendungszweck",
        }

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        # Add onchange event to destinataer field for AJAX IBAN fetching
        self.fields["destinataer"].widget.attrs["onchange"] = "updateDestinataerInfo()"

    def clean(self):
        cleaned_data = super().clean()
        ist_wiederkehrend = cleaned_data.get("ist_wiederkehrend")
        intervall = cleaned_data.get("intervall")

        if ist_wiederkehrend and not intervall:
            raise forms.ValidationError(
                "Bitte wählen Sie ein Zahlungsintervall für wiederkehrende Zahlungen."
            )

        return cleaned_data


class UnterstuetzungWiederkehrendForm(forms.ModelForm):
    """Form für das Bearbeiten von wiederkehrenden Unterstützungsvorlagen"""

    class Meta:
        model = UnterstuetzungWiederkehrend
        fields = [
            "destinataer",
            "konto",
            "betrag",
            "intervall",
            "beschreibung",
            "empfaenger_iban",
            "empfaenger_name",
            "verwendungszweck",
            "erste_zahlung_am",
            "letzte_zahlung_am",
            "aktiv",
        ]

        widgets = {
            "destinataer": forms.Select(attrs={"class": "form-select"}),
            "konto": forms.Select(attrs={"class": "form-select"}),
            "betrag": forms.NumberInput(
                attrs={"class": "form-control", "step": "0.01"}
            ),
            "intervall": forms.Select(attrs={"class": "form-select"}),
            "beschreibung": forms.TextInput(attrs={"class": "form-control"}),
            "empfaenger_iban": forms.TextInput(
                attrs={
                    "class": "form-control",
                    "placeholder": "DE89 3704 0044 0532 0130 00",
                }
            ),
            "empfaenger_name": forms.TextInput(attrs={"class": "form-control"}),
            "verwendungszweck": forms.TextInput(
                attrs={"class": "form-control", "maxlength": "140"}
            ),
            "erste_zahlung_am": forms.DateInput(
                attrs={"class": "form-control", "type": "date"}
            ),
            "letzte_zahlung_am": forms.DateInput(
                attrs={"class": "form-control", "type": "date"}
            ),
            "aktiv": forms.CheckboxInput(attrs={"class": "form-check-input"}),
        }


class UnterstuetzungMarkAsPaidForm(forms.Form):
    """Simple form to mark an Unterstützung as paid"""

    ausgezahlt_am = forms.DateField(
        widget=forms.DateInput(attrs={"class": "form-control", "type": "date"}),
        label="Ausgezahlt am",
        initial=timezone.now().date(),
    )

    bemerkung = forms.CharField(
        widget=forms.Textarea(attrs={"class": "form-control", "rows": 3}),
        label="Bemerkung (optional)",
        required=False,
        help_text="Optionale Notiz zur Zahlung",
    )


class VierteljahresNachweisForm(forms.ModelForm):
    """Form for quarterly confirmations (Vierteljahresnachweise)"""

    class Meta:
        model = VierteljahresNachweis
        fields = [
            'studiennachweis_eingereicht',
            'studiennachweis_datei',
            'studiennachweis_bemerkung',
            'einkommenssituation_bestaetigt',
            'einkommenssituation_text',
            'einkommenssituation_datei',
            'vermogenssituation_bestaetigt',
            'vermogenssituation_text',
            'vermogenssituation_datei',
            'weitere_dokumente',
            'weitere_dokumente_beschreibung',
            'interne_notizen',
        ]

        widgets = {
            'studiennachweis_eingereicht': forms.CheckboxInput(attrs={'class': 'form-check-input'}),
            'studiennachweis_datei': forms.FileInput(attrs={'class': 'form-control', 'accept': '.pdf,.jpg,.jpeg,.png,.doc,.docx'}),
            'studiennachweis_bemerkung': forms.Textarea(attrs={'class': 'form-control', 'rows': 3}),
            'einkommenssituation_bestaetigt': forms.CheckboxInput(attrs={'class': 'form-check-input'}),
            'einkommenssituation_text': forms.Textarea(attrs={'class': 'form-control', 'rows': 3, 'placeholder': 'Z.B. "Keine Änderungen seit letzter Meldung"'}),
            'einkommenssituation_datei': forms.FileInput(attrs={'class': 'form-control', 'accept': '.pdf,.jpg,.jpeg,.png,.doc,.docx'}),
            'vermogenssituation_bestaetigt': forms.CheckboxInput(attrs={'class': 'form-check-input'}),
            'vermogenssituation_text': forms.Textarea(attrs={'class': 'form-control', 'rows': 3, 'placeholder': 'Z.B. "Keine Änderungen seit letzter Meldung"'}),
            'vermogenssituation_datei': forms.FileInput(attrs={'class': 'form-control', 'accept': '.pdf,.jpg,.jpeg,.png,.doc,.docx'}),
            'weitere_dokumente': forms.FileInput(attrs={'class': 'form-control', 'accept': '.pdf,.jpg,.jpeg,.png,.doc,.docx'}),
            'weitere_dokumente_beschreibung': forms.Textarea(attrs={'class': 'form-control', 'rows': 2}),
            'interne_notizen': forms.Textarea(attrs={'class': 'form-control', 'rows': 3}),
        }

        labels = {
            'studiennachweis_erforderlich': 'Studiennachweis erforderlich',
            'studiennachweis_eingereicht': 'Studiennachweis eingereicht',
            'studiennachweis_datei': 'Studiennachweis (Datei)',
            'studiennachweis_bemerkung': 'Bemerkung zum Studiennachweis',
            'einkommenssituation_bestaetigt': 'Einkommenssituation bestätigt',
            'einkommenssituation_text': 'Einkommenssituation (Text)',
            'einkommenssituation_datei': 'Einkommenssituation (Datei)',
            'vermogenssituation_bestaetigt': 'Vermögenssituation bestätigt',
            'vermogenssituation_text': 'Vermögenssituation (Text)',
            'vermogenssituation_datei': 'Vermögenssituation (Datei)',
            'weitere_dokumente': 'Weitere Dokumente',
            'weitere_dokumente_beschreibung': 'Beschreibung weitere Dokumente',
            'interne_notizen': 'Interne Notizen (nur für Verwaltung)',
        }

        help_texts = {
            'einkommenssituation_text': 'Z.B. "Keine Änderungen seit letzter Meldung" oder Details zu Änderungen',
            'vermogenssituation_text': 'Z.B. "Keine Änderungen seit letzter Meldung" oder Details zu Änderungen',
            'interne_notizen': 'Diese Notizen sind nur für die interne Verwaltung sichtbar',
        }

    def clean(self):
        cleaned_data = super().clean()

        # Validate that at least one form of confirmation is provided for income situation
        einkommenssituation_text = cleaned_data.get('einkommenssituation_text')
        einkommenssituation_datei = cleaned_data.get('einkommenssituation_datei')
        einkommenssituation_bestaetigt = cleaned_data.get('einkommenssituation_bestaetigt')

        # DMS-Dokumente aus POST-Daten beruecksichtigen (werden parallel zum Formular gesendet)
        has_einkommens_dms = (
            self.instance and self.instance.pk and
            bool(self.instance.einkommenssituation_dms_dokument_id)
        )
        if einkommenssituation_bestaetigt and not einkommenssituation_text and not einkommenssituation_datei and not has_einkommens_dms:
            raise ValidationError(
                'Wenn die Einkommenssituation bestätigt wird, muss entweder ein Text, eine Datei oder ein DMS-Dokument angegeben werden.'
            )

        # Validate that at least one form of confirmation is provided for asset situation
        vermogenssituation_text = cleaned_data.get('vermogenssituation_text')
        vermogenssituation_datei = cleaned_data.get('vermogenssituation_datei')
        vermogenssituation_bestaetigt = cleaned_data.get('vermogenssituation_bestaetigt')

        has_vermogens_dms = (
            self.instance and self.instance.pk and
            bool(self.instance.vermogenssituation_dms_dokument_id)
        )
        if vermogenssituation_bestaetigt and not vermogenssituation_text and not vermogenssituation_datei and not has_vermogens_dms:
            raise ValidationError(
                'Wenn die Vermögenssituation bestätigt wird, muss entweder ein Text, eine Datei oder ein DMS-Dokument angegeben werden.'
            )

        # Validate study proof if required and marked as submitted
        studiennachweis_erforderlich = cleaned_data.get('studiennachweis_erforderlich')
        studiennachweis_eingereicht = cleaned_data.get('studiennachweis_eingereicht')
        studiennachweis_datei = cleaned_data.get('studiennachweis_datei')
        studiennachweis_bemerkung = cleaned_data.get('studiennachweis_bemerkung')

        if studiennachweis_erforderlich and studiennachweis_eingereicht:
            has_dms_studiennachweis = (
                self.instance and self.instance.pk and (
                    bool(self.instance.studiennachweis_dms_dokument_id)
                    or self.instance.nachweis_dokumente.filter(kontext="studiennachweis").exists()
                )
            )
            if not studiennachweis_datei and not studiennachweis_bemerkung and not has_dms_studiennachweis:
                raise ValidationError(
                    'Wenn der Studiennachweis als eingereicht markiert wird, muss entweder eine Datei, eine Bemerkung oder ein DMS-Dokument angegeben werden.'
                )

        return cleaned_data
