from datetime import timedelta

from django.contrib import admin
from django.db.models import Q
from django.utils import timezone
from unfold.admin import ModelAdmin
from unfold.contrib.filters.admin import RangeDateFilter
from unfold.decorators import display

from core.admin_ui import PortalAdminMixin
from core.status_palette import DOMAIN_STATUS_LABELS
from .models import Domain


@admin.register(Domain)
class DomainAdmin(PortalAdminMixin, ModelAdmin):
    portal_icon = "language"
    portal_kicker = "SERVIÇOS RECORRENTES"
    portal_description = "Controle expirações, registadores, DNS, transferência e relação de cada domínio com o respetivo serviço."
    portal_tone = "cyan"
    portal_stats = (
        {"label": "Domínios", "icon": "language", "tone": "primary", "caption": "Total registado"},
        {"label": "Ativos", "icon": "verified", "tone": "success", "filters": {"status": Domain.DomainStatus.ACTIVE}, "caption": "Em utilização"},
        {"label": "Expiram em 30 dias", "icon": "event_busy", "tone": "warning", "method": "count_expiring", "caption": "A renovar"},
        {"label": "Dados incompletos", "icon": "dns_off", "tone": "danger", "method": "count_incomplete", "caption": "Sem data ou registador"},
    )
    portal_related_links = (
        {"label": "Serviços", "icon": "inventory_2", "url_name": "admin:services_service_changelist"},
        {"label": "Alojamentos", "icon": "cloud", "url_name": "admin:hosting_hostingaccount_changelist"},
        {"label": "Fornecedores", "icon": "business", "url_name": "admin:core_provider_changelist"},
    )

    list_display = ("domain_identity", "client_name", "registrar", "show_status", "expiry", "days_remaining", "dns_management")
    list_filter = ("status", "registrar", "dns_management", "auto_renew_at_registrar", "transfer_lock", ("service__next_renewal_date", RangeDateFilter))
    search_fields = ("domain_name", "service__name", "service__client__name", "service__client__email", "nameservers")
    autocomplete_fields = ("service", "registrar")
    readonly_fields = ("public_id", "expiry", "days_remaining", "created_at", "updated_at")
    list_filter_submit = True
    list_fullwidth = True

    fieldsets = (
        ("Domínio", {"fields": ("service", "domain_name", "registrar", "registered_on", "status"), "description": "Identificação do domínio e respetivo serviço comercial."}),
        ("DNS e transferência", {"fields": ("dns_management", "nameservers", "auto_renew_at_registrar", "transfer_lock", "auth_code_reference"), "description": "Configuração operacional sem guardar credenciais sensíveis."}),
        ("Renovação", {"fields": ("expiry", "days_remaining"), "description": "A data é herdada do serviço associado."}),
        ("Notas", {"fields": ("notes",)}),
        ("Sistema", {"fields": ("public_id", "created_at", "updated_at"), "classes": ("collapse",)}),
    )

    def count_expiring(self, request, queryset):
        today = timezone.localdate()
        return queryset.filter(service__next_renewal_date__range=(today, today + timedelta(days=30))).count()

    def count_incomplete(self, request, queryset):
        return queryset.filter(Q(registrar__isnull=True) | Q(service__next_renewal_date__isnull=True)).distinct().count()

    @display(description="Domínio", header=True)
    def domain_identity(self, obj):
        return obj.domain_name, obj.service.name

    @display(description="Cliente", ordering="service__client__name")
    def client_name(self, obj):
        return obj.service.client

    @display(description="Estado", label=DOMAIN_STATUS_LABELS, ordering="status")
    def show_status(self, obj):
        return obj.get_status_display()

    @display(description="Expira em", ordering="service__next_renewal_date")
    def expiry(self, obj):
        return obj.expires_on if obj and obj.service_id else None

    @display(description="Dias")
    def days_remaining(self, obj):
        if not obj or not obj.service_id:
            return "—"
        value = obj.service.days_until_renewal
        return "—" if value is None else value
