from datetime import datetime, time, timedelta

from django import forms
from django.core.exceptions import ValidationError
from django.utils import timezone

from apps.service.models import ServiceCase


class ReportFilters(forms.Form):
    date_from = forms.DateField(required=False, widget=forms.DateInput(attrs={"type": "date"}))
    date_to = forms.DateField(required=False, widget=forms.DateInput(attrs={"type": "date"}))
    company = forms.UUIDField(required=False)
    region = forms.UUIDField(required=False)
    service_center = forms.UUIDField(required=False)
    brand = forms.UUIDField(required=False)
    product_category = forms.UUIDField(required=False, label="Product Category")
    model = forms.UUIDField(required=False)
    variant = forms.UUIDField(required=False)
    engineer = forms.UUIDField(required=False)
    case = forms.UUIDField(required=False)
    complaint = forms.UUIDField(required=False, label="ComplaintSymptom")
    fault_diagnosis = forms.UUIDField(required=False)
    root_cause = forms.UUIDField(required=False)
    unknown_root_cause = forms.ChoiceField(required=False, choices=[("", "All root causes"), ("yes", "Unknown / Unconfirmed only")])
    repair_action = forms.UUIDField(required=False, label="Repair action taxonomy")
    event_outcome = forms.ChoiceField(required=False, choices=[("", "All outcomes"), *[(v, v) for v in ("REPAIRED", "NOT_REPAIRED", "PASSED", "FAILED")]])
    status = forms.ChoiceField(required=False, choices=[("", "All statuses"), *ServiceCase.Status.choices])
    intake_channel = forms.ChoiceField(required=False, choices=[("", "All channels"), *ServiceCase.Channel.choices])
    warranty = forms.ChoiceField(required=False, choices=[("", "All intake warranty snapshots"), ("covered", "Recorded coverage"), ("uncovered", "No recorded coverage")])
    responsibility = forms.ChoiceField(required=False, choices=[("", "All explicit commercial responsibility"), ("CUSTOMER", "Customer"), ("WARRANTY", "Warranty"), ("COMPANY", "Company")])

    def clean(self):
        values = super().clean()
        if values.get("date_from") and values.get("date_to") and values["date_from"] > values["date_to"]:
            raise ValidationError("Start date must not follow end date.")
        if values.get("date_to") and values["date_to"].year == 9999:
            raise ValidationError("End date must allow a next-day boundary.")
        if values.get("root_cause") and values.get("unknown_root_cause"):
            raise ValidationError("Choose a RootCause or unknown causes, not both.")
        return values


def period(rows, field, filters):
    """Complete local dates, half-open boundaries; no received-date substitution."""
    tz = timezone.get_current_timezone()
    if filters.get("date_from"):
        rows = rows.filter(**{field + "__gte": timezone.make_aware(datetime.combine(filters["date_from"], time.min), tz)})
    if filters.get("date_to"):
        end = filters["date_to"] + timedelta(days=1)
        rows = rows.filter(**{field + "__lt": timezone.make_aware(datetime.combine(end, time.min), tz)})
    return rows
