from django.contrib import admin, messages
from django.core.exceptions import ValidationError

from .assignment_services import deactivate_assignment, reactivate_assignment, set_primary_assignment
from .assignments import UserOrganizationAssignment


@admin.register(UserOrganizationAssignment)
class UserOrganizationAssignmentAdmin(admin.ModelAdmin):
    list_display = ("user", "company", "region", "service_center", "department", "is_primary", "is_active")
    list_select_related = ("user", "company", "region", "service_center", "department")
    search_fields = ("user__username", "user__email", "company__code", "region__code", "service_center__code", "department__code")
    list_filter = ("is_active", "is_primary", "company", "region", "service_center", "department")
    ordering = ("user__username", "-is_primary", "company__code", "-created_at")
    autocomplete_fields = ("user", "company", "region", "service_center", "department")
    readonly_fields = ("id", "created_at", "updated_at")
    actions = ("deactivate_selected", "reactivate_selected", "make_primary")

    def get_readonly_fields(self, request, obj=None):
        fields = super().get_readonly_fields(request, obj)
        return (*fields, "user") if obj else fields

    def has_delete_permission(self, request, obj=None):
        # Ending an assignment is the normal operation; retain its history in admin.
        return False

    @admin.action(description="Deactivate selected assignments and clear primary", permissions=["change"])
    def deactivate_selected(self, request, queryset):
        for assignment in queryset.order_by("user_id", "pk"):
            deactivate_assignment(assignment=assignment)
        self.message_user(request, "Selected assignments deactivated.")

    @admin.action(description="Reactivate selected assignments only", permissions=["change"])
    def reactivate_selected(self, request, queryset):
        completed = 0
        for assignment in queryset.order_by("user_id", "pk"):
            try:
                reactivate_assignment(assignment=assignment)
            except ValidationError as error:
                self.message_user(request, "; ".join(error.messages), level=messages.ERROR)
            else:
                completed += 1
        self.message_user(request, f"Reactivated {completed} assignment(s); primary and role assignments unchanged.")

    @admin.action(description="Make the selected assignment primary (select one)", permissions=["change"])
    def make_primary(self, request, queryset):
        if queryset.count() != 1:
            self.message_user(request, "Select exactly one assignment.", level=messages.ERROR)
            return
        try:
            set_primary_assignment(assignment=queryset.get())
        except ValidationError as error:
            self.message_user(request, "; ".join(error.messages), level=messages.ERROR)
        else:
            self.message_user(request, "Primary assignment updated.")
