from django.contrib import admin, messages
from django.core.exceptions import ValidationError

from .models import Role, UserRoleAssignment
from . import services


@admin.register(Role)
class RoleAdmin(admin.ModelAdmin):
    list_display = ("code", "name", "is_active")
    search_fields = ("code", "name", "description")
    list_filter = ("is_active",)
    ordering = ("code",)
    readonly_fields = ("id", "created_at", "updated_at")
    filter_horizontal = ("permissions",)
    actions = ("deactivate_selected", "reactivate_selected")

    def save_related(self, request, form, formsets, change):
        # Role's only M2M is permissions. Use its supported replacement service,
        # inside Django's existing atomic change-form transaction.
        services.set_role_permissions(role=form.instance, permissions=form.cleaned_data["permissions"])
        for formset in formsets:
            self.save_formset(request, form, formset, change=change)

    @admin.action(description="Deactivate roles and their active assignments", permissions=["change"])
    def deactivate_selected(self, request, queryset):
        for role in queryset.order_by("pk"):
            services.deactivate_role(role=role)
        self.message_user(request, "Selected roles deactivated.")

    @admin.action(description="Reactivate roles only", permissions=["change"])
    def reactivate_selected(self, request, queryset):
        for role in queryset.order_by("pk"):
            services.reactivate_role(role=role)
        self.message_user(request, "Selected roles reactivated; assignments unchanged.")


@admin.register(UserRoleAssignment)
class UserRoleAssignmentAdmin(admin.ModelAdmin):
    list_display = ("user", "role", "organization_assignment", "is_active")
    list_select_related = ("user", "role", "organization_assignment")
    search_fields = ("user__username", "user__email", "role__code", "role__name", "organization_assignment__company__code")
    list_filter = ("is_active", "role", "organization_assignment__company")
    ordering = ("user__username", "role__code", "-created_at")
    autocomplete_fields = ("user", "role", "organization_assignment")
    readonly_fields = ("id", "created_at", "updated_at")
    actions = ("deactivate_selected", "reactivate_selected")

    def get_readonly_fields(self, request, obj=None):
        return (*self.readonly_fields, "user") if obj else self.readonly_fields

    def has_delete_permission(self, request, obj=None):
        return False

    @admin.action(description="Deactivate selected role assignments", permissions=["change"])
    def deactivate_selected(self, request, queryset):
        for assignment in queryset.order_by("user_id", "pk"):
            services.deactivate_role_assignment(assignment=assignment)
        self.message_user(request, "Selected role assignments deactivated.")

    @admin.action(description="Reactivate selected role assignments", permissions=["change"])
    def reactivate_selected(self, request, queryset):
        for assignment in queryset.order_by("user_id", "pk"):
            try:
                services.reactivate_role_assignment(assignment=assignment)
            except ValidationError as error:
                self.message_user(request, "; ".join(error.messages), level=messages.ERROR)
