from django import forms
from django.utils import timezone

from .models import ConsultationRequest, ConsultationSlot


class AvailableSlotChoiceField(forms.ModelChoiceField):
    def label_from_instance(self, slot):
        local_start = timezone.localtime(slot.start_at)
        return (
            f"{local_start:%d.%m.%Y} в {local_start:%H:%M} "
            f"· {slot.duration_minutes} минут · {slot.get_format_display()}"
        )


class ConsultationRequestForm(forms.ModelForm):
    slot = AvailableSlotChoiceField(
        queryset=ConsultationSlot.objects.none(),
        empty_label="Выберите свободное время",
        label="Удобное время",
    )

    class Meta:
        model = ConsultationRequest
        fields = (
            "name",
            "phone",
            "contact",
            "student_grade",
            "subject",
            "exam",
            "format",
            "slot",
            "comment",
            "consent_given",
        )
        widgets = {
            "name": forms.TextInput(attrs={"placeholder": "Как к вам обращаться"}),
            "phone": forms.TelInput(attrs={"placeholder": "+7 (999) 123-45-67"}),
            "contact": forms.TextInput(attrs={"placeholder": "@username, WhatsApp и т. п."}),
            "comment": forms.Textarea(
                attrs={
                    "placeholder": "Класс, темы и вопросы, которые хотите разобрать",
                    "rows": 4,
                }
            ),
        }

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.fields["slot"].queryset = ConsultationSlot.objects.available()
        for name, field in self.fields.items():
            if name != "consent_given":
                field.widget.attrs["class"] = "form-control"
        self.fields["consent_given"].widget.attrs["class"] = "consent-control"
        self.fields["contact"].required = False
        self.fields["student_grade"].required = False
        self.fields["comment"].required = False

    def clean_slot(self):
        slot = self.cleaned_data["slot"]
        if not slot.is_available:
            raise forms.ValidationError("Это время уже занято. Выберите другой свободный слот.")
        return slot

    def clean(self):
        cleaned_data = super().clean()
        slot = cleaned_data.get("slot")
        subject = cleaned_data.get("subject")
        requested_format = cleaned_data.get("format")
        if slot and subject and slot.subject not in (ConsultationSlot.Subject.ANY, subject):
            self.add_error("slot", "Это время доступно только для другого предмета.")
        if slot and requested_format not in (ConsultationRequest.Format.ANY, slot.format):
            self.add_error("format", f"Для выбранного времени доступен формат: {slot.get_format_display()}.")
        return cleaned_data
