from django.contrib import admin
from django.utils import timezone
from unfold.admin import ModelAdmin, TabularInline
from unfold.contrib.filters.admin import RangeDateFilter, RangeDateTimeFilter
from unfold.decorators import display

from core.admin_ui import PortalAdminMixin
from core.status_palette import TICKET_STATUS_LABELS
from .models import SupportMessage, SupportTicket
from .notifications import prepare_ticket_resolved_notification


class SupportMessageInline(TabularInline):
    model = SupportMessage
    can_delete = False
    extra = 0
    fields = ("author_type", "staff_user", "author_name", "message", "attachment", "is_internal", "read_by_client_at", "created_at")
    readonly_fields = ("read_by_client_at", "created_at")
    tab = True


@admin.action(description="Marcar como em tratamento")
def mark_in_progress(modeladmin, request, queryset):
    queryset.update(status=SupportTicket.Status.IN_PROGRESS, closed_at=None, last_activity_at=timezone.now())


@admin.action(description="Marcar como resolvido e preparar confirmação")
def mark_resolved(modeladmin, request, queryset):
    for ticket in queryset:
        ticket.last_activity_at = timezone.now()
        ticket.mark_resolved(user=request.user, note="Marcado como resolvido no backoffice.")
        prepare_ticket_resolved_notification(ticket)


@admin.register(SupportTicket)
class SupportTicketAdmin(PortalAdminMixin, ModelAdmin):
    portal_icon = "support_agent"
    portal_kicker = "RELAÇÃO COM CLIENTES"
    portal_description = "Registe pedidos, acompanhe conversas, defina prioridades e acompanhe o portal do cliente e mantenha todo o histórico de suporte centralizado."
    portal_tone = "violet"
    portal_stats = (
        {"label": "Pedidos", "icon": "support_agent", "tone": "primary", "caption": "Histórico total"},
        {"label": "Abertos", "icon": "mark_unread_chat_alt", "tone": "warning", "filters": {"status": SupportTicket.Status.OPEN}, "caption": "A iniciar"},
        {"label": "Em tratamento", "icon": "handyman", "tone": "primary", "filters": {"status": SupportTicket.Status.IN_PROGRESS}, "caption": "Em acompanhamento"},
        {"label": "Urgentes / atrasados", "icon": "crisis_alert", "tone": "danger", "method": "count_critical", "caption": "Prioridade máxima"},
    )
    portal_related_links = (
        {"label": "Mensagens", "icon": "forum", "url_name": "admin:support_supportmessage_changelist"},
        {"label": "Clientes", "icon": "groups", "url_name": "admin:clients_client_changelist"},
        {"label": "Tarefas", "icon": "task_alt", "url_name": "admin:operations_internaltask_changelist"},
    )

    list_display = (
        "ticket_identity",
        "client",
        "service",
        "category",
        "priority_label",
        "status_label",
        "unread_staff",
        "last_activity_at",
        "due_date",
        "overdue_label",
        "assigned_to",
    )
    list_filter = (
        "category",
        "priority",
        "status",
        "channel",
        "assigned_to",
        "client_visible",
        ("due_date", RangeDateFilter),
        ("last_activity_at", RangeDateTimeFilter),
    )
    search_fields = ("subject", "description", "client__name", "client__email", "service__name", "messages__message")
    autocomplete_fields = ("client", "service", "assigned_to")
    readonly_fields = ("public_id", "last_activity_at", "client_last_read_at", "staff_last_read_at", "closed_at", "resolved_by_client", "resolved_by", "created_at", "updated_at")
    inlines = (SupportMessageInline,)
    actions = (mark_in_progress, mark_resolved)
    list_filter_submit = True
    list_fullwidth = True

    fieldsets = (
        ("Pedido", {"fields": ("client", "service", "subject", "description", "category", "channel"), "description": "Origem, contexto e descrição completa do pedido."}),
        ("Tratamento", {"fields": ("priority", "status", "assigned_to", "due_date", "client_visible"), "description": "Prioridade, responsável e estado do acompanhamento."}),
        ("Atividade", {"fields": ("last_activity_at", "client_last_read_at", "staff_last_read_at", "closed_at", "resolved_by_client", "resolved_by", "resolution_note"), "description": "Cronologia, leitura e resolução do ticket."}),
        ("Sistema", {"fields": ("public_id", "created_at", "updated_at"), "classes": ("collapse",)}),
    )

    def count_critical(self, request, queryset):
        open_statuses = (SupportTicket.Status.OPEN, SupportTicket.Status.IN_PROGRESS, SupportTicket.Status.WAITING_CLIENT, SupportTicket.Status.WAITING_INTERNAL, SupportTicket.Status.REOPENED)
        urgent = queryset.filter(priority=SupportTicket.Priority.URGENT, status__in=open_statuses)
        overdue = queryset.filter(due_date__lt=timezone.localdate(), status__in=open_statuses)
        return (urgent | overdue).distinct().count()

    @display(description="Pedido", header=True)
    def ticket_identity(self, obj):
        return obj.subject, f"{obj.reference} · {obj.get_channel_display()}"

    @display(description="Prioridade", label={
        SupportTicket.Priority.LOW: "info",
        SupportTicket.Priority.NORMAL: "primary",
        SupportTicket.Priority.HIGH: "warning",
        SupportTicket.Priority.URGENT: "danger",
    }, ordering="priority")
    def priority_label(self, obj):
        return obj.get_priority_display()

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

    @display(description="Atrasado", boolean=True)
    def overdue_label(self, obj):
        return obj.is_overdue

    @display(description="Novas mensagens")
    def unread_staff(self, obj):
        count = obj.unread_for_staff
        return f"{count} por ler" if count else "—"

    def change_view(self, request, object_id, form_url="", extra_context=None):
        SupportMessage.objects.filter(
            ticket_id=object_id,
            author_type=SupportMessage.AuthorType.CLIENT,
            read_by_staff_at__isnull=True,
        ).update(read_by_staff_at=timezone.now())
        SupportTicket.objects.filter(pk=object_id).update(staff_last_read_at=timezone.now())
        return super().change_view(request, object_id, form_url, extra_context)

    def save_formset(self, request, form, formset, change):
        instances = formset.save(commit=False)
        for instance in instances:
            if isinstance(instance, SupportMessage) and instance.author_type == SupportMessage.AuthorType.STAFF:
                if not instance.staff_user_id:
                    instance.staff_user = request.user
                if not instance.author_name:
                    instance.author_name = request.user.get_full_name() or request.user.get_username()
            instance.save()
        formset.save_m2m()


@admin.register(SupportMessage)
class SupportMessageAdmin(PortalAdminMixin, ModelAdmin):
    portal_icon = "forum"
    portal_kicker = "RELAÇÃO COM CLIENTES"
    portal_description = "Histórico detalhado de mensagens, respostas e notas internas associadas aos pedidos de suporte."
    portal_tone = "cyan"
    portal_stats = (
        {"label": "Mensagens", "icon": "forum", "tone": "primary", "caption": "Histórico total"},
        {"label": "Da equipa", "icon": "support_agent", "tone": "primary", "filters": {"author_type": SupportMessage.AuthorType.STAFF}, "caption": "Respostas internas"},
        {"label": "Dos clientes", "icon": "person", "tone": "success", "filters": {"author_type": SupportMessage.AuthorType.CLIENT}, "caption": "Comunicação recebida"},
        {"label": "Notas internas", "icon": "visibility_off", "tone": "warning", "filters": {"is_internal": True}, "caption": "Nunca visíveis ao cliente"},
    )
    portal_related_links = (
        {"label": "Pedidos", "icon": "support_agent", "url_name": "admin:support_supportticket_changelist"},
    )

    list_display = ("ticket", "author_type", "author_name", "is_internal", "created_at")
    list_filter = ("author_type", "is_internal", "created_at")
    search_fields = ("ticket__subject", "ticket__client__name", "author_name", "author_email", "message")
    autocomplete_fields = ("ticket", "staff_user")
    readonly_fields = ("read_by_client_at", "read_by_staff_at", "created_at", "updated_at")
    list_fullwidth = True

    def has_delete_permission(self, request, obj=None):
        # As mensagens são parte do histórico de auditoria da conversa.
        return False
    fieldsets = (
        ("Mensagem", {"fields": ("ticket", "author_type", "staff_user", "author_name", "author_email", "message", "attachment", "is_internal")}),
        ("Leitura", {"fields": ("read_by_client_at", "read_by_staff_at"), "description": "Registo de leitura no portal e no backoffice."}),
        ("Sistema", {"fields": ("created_at", "updated_at")}),
    )

