from django import forms
from django.contrib import admin

from apps.core.audit.models import AuditLog
from apps.core.authentication.models import CustomUser, Institution, MFADevice, UserProfile
from apps.core.notifications.models import Notification, NotificationPreference, NotificationTemplate


class CustomUserAdminForm(forms.ModelForm):
    password = forms.CharField(widget=forms.PasswordInput, required=False)

    class Meta:
        model = CustomUser
        exclude = ("password",)

    def clean(self):
        data = super().clean()
        if not self.instance.pk and not data.get("password"):
            raise forms.ValidationError({"password": "Password is required for new users."})
        return data

    def save(self, commit=True):
        user = super().save(commit=False)
        raw = self.cleaned_data.get("password")
        if raw:
            user.set_password(raw)
        if commit:
            user.save()
            self.save_m2m()
        return user


@admin.register(Institution)
class InstitutionAdmin(admin.ModelAdmin):
    list_display = ("name", "country", "institution_type", "is_member", "is_active", "created_at")
    list_filter = ("is_member", "is_active", "institution_type", "country")
    search_fields = ("name", "region")


@admin.register(CustomUser)
class CustomUserAdmin(admin.ModelAdmin):
    form = CustomUserAdminForm
    ordering = ("email",)
    list_display = ("email", "first_name", "last_name", "role", "is_staff", "is_active")
    list_filter = ("is_staff", "is_superuser", "is_active", "role")
    search_fields = ("email", "first_name", "last_name")
    readonly_fields = ("date_joined", "last_login")
    fieldsets = (
        (None, {"fields": ("email", "password")}),
        (
            "Personal",
            {"fields": ("first_name", "last_name", "phone", "institution", "role", "email_verified")},
        ),
        ("Permissions", {"fields": ("is_active", "is_staff", "is_superuser", "groups", "user_permissions")}),
        ("Important dates", {"fields": ("last_login", "date_joined")}),
    )
    filter_horizontal = ("groups", "user_permissions")


@admin.register(UserProfile)
class UserProfileAdmin(admin.ModelAdmin):
    list_display = ("user", "country", "timezone", "preferred_language")
    raw_id_fields = ("user",)


@admin.register(MFADevice)
class MFADeviceAdmin(admin.ModelAdmin):
    list_display = ("user", "device_type", "name", "is_verified", "created_at")
    raw_id_fields = ("user",)
    readonly_fields = ("created_at",)


@admin.register(AuditLog)
class AuditLogAdmin(admin.ModelAdmin):
    list_display = ("timestamp", "actor", "action", "target_model", "object_id", "path", "method")
    list_filter = ("action", "target_model")
    search_fields = ("object_repr", "path", "actor__email")
    readonly_fields = [f.name for f in AuditLog._meta.fields]
    date_hierarchy = "timestamp"

    def has_add_permission(self, request):
        return False

    def has_change_permission(self, request, obj=None):
        return False

    def has_delete_permission(self, request, obj=None):
        return False


@admin.register(Notification)
class NotificationAdmin(admin.ModelAdmin):
    list_display = ("recipient", "verb", "is_read", "created_at", "email_sent")
    list_filter = ("verb", "is_read", "email_sent")
    search_fields = ("message", "recipient__email")
    raw_id_fields = ("recipient",)


@admin.register(NotificationPreference)
class NotificationPreferenceAdmin(admin.ModelAdmin):
    list_display = ("user", "channel", "verb", "enabled")
    list_filter = ("channel", "enabled")
    raw_id_fields = ("user",)


@admin.register(NotificationTemplate)
class NotificationTemplateAdmin(admin.ModelAdmin):
    list_display = ("verb", "name", "is_active", "updated_at")
    list_filter = ("is_active",)
    search_fields = ("verb", "name", "subject", "body_text", "body_html")
    readonly_fields = ("updated_at", "updated_by")

    def save_model(self, request, obj, form, change):
        obj.updated_by = request.user
        super().save_model(request, obj, form, change)
