"""
Django admin configuration for User models.
"""

from django.contrib import admin
from django.contrib.auth.admin import UserAdmin as BaseUserAdmin
from django.utils.html import format_html
from django.urls import reverse
from django.utils.safestring import mark_safe
from unfold.admin import ModelAdmin
from unfold.decorators import display
from import_export import resources
from import_export.admin import ImportExportModelAdmin

from .models import User, UserRole, UserProfile


class UserResource(resources.ModelResource):
    """Resource for importing/exporting users."""
    
    class Meta:
        model = User
        fields = (
            'id', 'email', 'username', 'first_name', 'last_name',
            'date_joined', 'last_login', 'is_active', 'is_staff',
            'banned', 'reputation_score', 'mfa_enabled'
        )
        export_order = fields


class UserRoleInline(admin.StackedInline):
    """Inline for user role."""
    model = UserRole
    can_delete = False
    verbose_name_plural = 'Role'
    fk_name = 'user'
    fields = ('role', 'granted_by', 'granted_at')
    readonly_fields = ('granted_at',)


class UserProfileInline(admin.StackedInline):
    """Inline for user profile."""
    model = UserProfile
    can_delete = False
    verbose_name_plural = 'Profile & Preferences'
    fk_name = 'user'
    fields = (
        ('email_notifications', 'email_on_submission_approved', 'email_on_submission_rejected'),
        ('profile_public', 'show_email'),
        ('total_submissions', 'approved_submissions'),
    )
    readonly_fields = ('total_submissions', 'approved_submissions')


@admin.register(User)
class UserAdmin(BaseUserAdmin, ModelAdmin, ImportExportModelAdmin):
    """Admin interface for User model."""
    
    resource_class = UserResource
    
    list_display = [
        'email',
        'username',
        'display_name_admin',
        'role_badge',
        'reputation_badge',
        'status_badge',
        'mfa_badge',
        'date_joined',
        'last_login',
    ]
    
    list_filter = [
        'is_active',
        'is_staff',
        'is_superuser',
        'banned',
        'mfa_enabled',
        'oauth_provider',
        'date_joined',
        'last_login',
    ]
    
    search_fields = [
        'email',
        'username',
        'first_name',
        'last_name',
    ]
    
    ordering = ['-date_joined']
    
    fieldsets = (
        ('Account Information', {
            'fields': ('email', 'username', 'password')
        }),
        ('Personal Information', {
            'fields': ('first_name', 'last_name', 'avatar_url', 'bio')
        }),
        ('Permissions', {
            'fields': (
                'is_active',
                'is_staff',
                'is_superuser',
                'groups',
                'user_permissions',
            )
        }),
        ('Moderation', {
            'fields': (
                'banned',
                'ban_reason',
                'banned_at',
                'banned_by',
            )
        }),
        ('OAuth', {
            'fields': ('oauth_provider', 'oauth_sub'),
            'classes': ('collapse',)
        }),
        ('Security', {
            'fields': ('mfa_enabled', 'reputation_score'),
        }),
        ('Timestamps', {
            'fields': ('date_joined', 'last_login'),
            'classes': ('collapse',)
        }),
    )
    
    add_fieldsets = (
        ('Create New User', {
            'classes': ('wide',),
            'fields': ('email', 'username', 'password1', 'password2'),
        }),
    )
    
    readonly_fields = [
        'date_joined',
        'last_login',
        'banned_at',
        'oauth_provider',
        'oauth_sub',
    ]
    
    inlines = [UserRoleInline, UserProfileInline]
    
    @display(description="Name", label=True)
    def display_name_admin(self, obj):
        """Display user's display name."""
        return obj.display_name or '-'
    
    @display(description="Role", label=True)
    def role_badge(self, obj):
        """Display user role with badge."""
        try:
            role = obj.role.role
            colors = {
                'admin': 'red',
                'moderator': 'blue',
                'user': 'green',
            }
            return format_html(
                '<span style="background-color: {}; color: white; padding: 3px 8px; border-radius: 3px; font-size: 11px;">{}</span>',
                colors.get(role, 'gray'),
                role.upper()
            )
        except UserRole.DoesNotExist:
            return format_html('<span style="color: gray;">No Role</span>')
    
    @display(description="Reputation", label=True)
    def reputation_badge(self, obj):
        """Display reputation score."""
        score = obj.reputation_score
        if score >= 100:
            color = 'green'
        elif score >= 50:
            color = 'blue'
        elif score >= 0:
            color = 'gray'
        else:
            color = 'red'
        
        return format_html(
            '<span style="color: {}; font-weight: bold;">{}</span>',
            color,
            score
        )
    
    @display(description="Status", label=True)
    def status_badge(self, obj):
        """Display user status."""
        if obj.banned:
            return format_html(
                '<span style="background-color: red; color: white; padding: 3px 8px; border-radius: 3px; font-size: 11px;">BANNED</span>'
            )
        elif not obj.is_active:
            return format_html(
                '<span style="background-color: orange; color: white; padding: 3px 8px; border-radius: 3px; font-size: 11px;">INACTIVE</span>'
            )
        else:
            return format_html(
                '<span style="background-color: green; color: white; padding: 3px 8px; border-radius: 3px; font-size: 11px;">ACTIVE</span>'
            )
    
    @display(description="MFA", label=True)
    def mfa_badge(self, obj):
        """Display MFA status."""
        if obj.mfa_enabled:
            return format_html(
                '<span style="color: green;">✓ Enabled</span>'
            )
        else:
            return format_html(
                '<span style="color: gray;">✗ Disabled</span>'
            )
    
    def get_queryset(self, request):
        """Optimize queryset with select_related."""
        qs = super().get_queryset(request)
        return qs.select_related('role', 'banned_by')
    
    actions = ['ban_users', 'unban_users', 'make_moderator', 'make_user']
    
    @admin.action(description="Ban selected users")
    def ban_users(self, request, queryset):
        """Ban selected users."""
        count = 0
        for user in queryset:
            if not user.banned:
                user.ban(reason="Banned by admin", banned_by=request.user)
                count += 1
        
        self.message_user(
            request,
            f"{count} user(s) have been banned."
        )
    
    @admin.action(description="Unban selected users")
    def unban_users(self, request, queryset):
        """Unban selected users."""
        count = 0
        for user in queryset:
            if user.banned:
                user.unban()
                count += 1
        
        self.message_user(
            request,
            f"{count} user(s) have been unbanned."
        )
    
    @admin.action(description="Set role to Moderator")
    def make_moderator(self, request, queryset):
        """Set users' role to moderator."""
        from .services import RoleService
        
        count = 0
        for user in queryset:
            RoleService.assign_role(user, 'moderator', request.user)
            count += 1
        
        self.message_user(
            request,
            f"{count} user(s) have been set to Moderator role."
        )
    
    @admin.action(description="Set role to User")
    def make_user(self, request, queryset):
        """Set users' role to user."""
        from .services import RoleService
        
        count = 0
        for user in queryset:
            RoleService.assign_role(user, 'user', request.user)
            count += 1
        
        self.message_user(
            request,
            f"{count} user(s) have been set to User role."
        )


@admin.register(UserRole)
class UserRoleAdmin(ModelAdmin):
    """Admin interface for UserRole model."""
    
    list_display = ['user', 'role', 'is_moderator', 'is_admin', 'granted_at', 'granted_by']
    list_filter = ['role', 'granted_at']
    search_fields = ['user__email', 'user__username']
    ordering = ['-granted_at']
    
    readonly_fields = ['granted_at']
    
    def get_queryset(self, request):
        """Optimize queryset."""
        qs = super().get_queryset(request)
        return qs.select_related('user', 'granted_by')


@admin.register(UserProfile)
class UserProfileAdmin(ModelAdmin):
    """Admin interface for UserProfile model."""
    
    list_display = [
        'user',
        'total_submissions',
        'approved_submissions',
        'approval_rate',
        'email_notifications',
        'profile_public',
    ]
    
    list_filter = [
        'email_notifications',
        'profile_public',
        'show_email',
    ]
    
    search_fields = ['user__email', 'user__username']
    
    readonly_fields = ['created', 'modified', 'total_submissions', 'approved_submissions']
    
    fieldsets = (
        ('User', {
            'fields': ('user',)
        }),
        ('Statistics', {
            'fields': ('total_submissions', 'approved_submissions'),
        }),
        ('Notification Preferences', {
            'fields': (
                'email_notifications',
                'email_on_submission_approved',
                'email_on_submission_rejected',
            )
        }),
        ('Privacy Settings', {
            'fields': ('profile_public', 'show_email'),
        }),
        ('Timestamps', {
            'fields': ('created', 'modified'),
            'classes': ('collapse',)
        }),
    )
    
    @display(description="Approval Rate")
    def approval_rate(self, obj):
        """Display approval rate percentage."""
        if obj.total_submissions == 0:
            return '-'
        
        rate = (obj.approved_submissions / obj.total_submissions) * 100
        
        if rate >= 80:
            color = 'green'
        elif rate >= 60:
            color = 'blue'
        elif rate >= 40:
            color = 'orange'
        else:
            color = 'red'
        
        return format_html(
            '<span style="color: {}; font-weight: bold;">{:.1f}%</span>',
            color,
            rate
        )
    
    def get_queryset(self, request):
        """Optimize queryset."""
        qs = super().get_queryset(request)
        return qs.select_related('user')
