from django.contrib.admin import filters
from django.db import models
from django.utils.http import urlencode
from django.utils.translation import gettext_lazy as _

__all__ = ("DateFieldFilter", "DateTimeFieldFilter")


class DateFieldFilter(filters.FieldListFilter):
    """Display date input."""

    template = "admin/aircox/filters/date_filter.html"
    input_type = "date"

    def __init__(self, field, request, params, model, model_admin, field_path):
        self.field_generic = f"{field_path}__"
        self.date_params = {k: v for k, v in params.items() if k.startswith(self.field_generic)}

        exact_lookup = "date" if isinstance(field, models.DateTimeField) else "exact"

        # links as: (label, param, input_type|None, value)
        self.links = [
            (_("Exact"), self.field_generic + exact_lookup, self.input_type),
            (_("Since"), self.field_generic + "gte", self.input_type),
            (_("Until"), self.field_generic + "lte", self.input_type),
        ]
        if field.null:
            self.links.insert(0, (_("None"), self.field_generic + "isnull", None, "1"))

        self.query_attrs = {k: v for k, v in request.GET.items() if k not in self.date_params}
        self.query_string = urlencode(self.query_attrs)
        super().__init__(field, request, params, model, model_admin, field_path)

    def expected_parameters(self):
        return [link[1] for link in self.links]

    def choices(self, changelist):
        yield {
            "label": _("Any"),
            "type": None,
            "query_string": self.query_string,
        }

        for link in self.links:
            value = len(link) > 3 and link[3] or self.date_params.get(link[1])
            yield {
                "label": link[0],
                "name": link[1],
                "value": value,
                "type": link[2],
                "query_attrs": self.query_attrs,
                "query_string": urlencode({link[1]: value}) + "&" + self.query_string if value else self.query_string,
            }


class DateTimeFieldFilter(DateFieldFilter):
    """Display datetime input."""

    input_type = "datetime-local"


filters.FieldListFilter.register(
    lambda f: isinstance(f, models.DateField),
    DateFieldFilter,
    take_priority=True,
)

filters.FieldListFilter.register(
    lambda f: isinstance(f, models.DateTimeField),
    DateTimeFieldFilter,
    take_priority=True,
)
