from django.contrib import admin
from django.contrib.auth.admin import UserAdmin
from django.utils.translation import gettext_lazy as _
from django.utils.html import format_html
from django.urls import reverse
from django.db.models import Count, Q
from django import forms
from .models import CustomUser, OTPVerification, PortfolioAssignment, Branch
from utils.datetime_utils import get_current_datetime


class ClientAssignmentForm(forms.ModelForm):
    """Enhanced form for client assignment in admin"""
    
    class Meta:
        model = CustomUser
        fields = ['portfolio_manager', 'branch']
    
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        # Only show active loan officers and team leaders as portfolio managers
        self.fields['portfolio_manager'].queryset = CustomUser.objects.filter(
            role__in=['loan_officer', 'team_leader'],
            status='active'
        )
        self.fields['portfolio_manager'].empty_label = "No Portfolio Manager"
        
        # Set up branch field
        try:
            from .models import Branch
            self.fields['branch'].queryset = Branch.objects.filter(is_active=True)
            self.fields['branch'].empty_label = "No Branch Assigned"
        except:
            # If Branch model doesn't exist, remove the field
            if 'branch' in self.fields:
                del self.fields['branch']


@admin.register(CustomUser)
class CustomUserAdmin(UserAdmin):
    form = ClientAssignmentForm
    list_display = (
        'user_image_display', 'phone_number', 'email', 'first_name', 'last_name', 
        'role', 'status', 'branch_display', 'portfolio_manager_link', 
        'assignment_date', 'is_active'
    )
    list_filter = (
        'role', 'status', 'is_active', 'is_staff', 'is_superuser',
        'branch', 'portfolio_manager', 'assigned_date'
    )
    search_fields = ('phone_number', 'email', 'first_name', 'last_name', 'id_number')
    ordering = ('-date_joined',)
    
    fieldsets = (
        (None, {'fields': ('phone_number', 'email', 'password')}),
        (_('Personal info'), {'fields': ('first_name', 'last_name', 'username')}),
        (_('Profile Image'), {'fields': ('selfie',)}),
        (_('Branch & Portfolio Management'), {
            'fields': ('branch', 'portfolio_manager', 'assigned_date'),
            'description': 'Assign this user to a branch and portfolio manager'
        }),
        (_('KYC Data'), {
            'fields': (
                'id_number', 'kra_pin', 'date_of_birth', 'gender', 'nationality',
                'marital_status', 'address', 'city', 'county', 'postal_code'
            ),
            'classes': ('collapse',)
        }),
        (_('Business Info'), {
            'fields': (
                'employer', 'business_name', 'business_type', 'monthly_income'
            ),
            'classes': ('collapse',)
        }),
        (_('Emergency Contact'), {
            'fields': (
                'emergency_contact_name', 'emergency_contact_phone',
                'emergency_contact_relationship'
            ),
            'classes': ('collapse',)
        }),
        (_('Documents'), {
            'fields': (
                'id_document', 'utility_bill', 'crb_report',
                'bank_statement'
            ),
            'classes': ('collapse',)
        }),
        (_('Permissions'), {
            'fields': (
                'role', 'status', 'is_active', 'is_staff', 'is_superuser',
                'groups', 'user_permissions'
            ),
        }),
        (_('Verification'), {
            'fields': ('is_phone_verified', 'is_email_verified'),
        }),
        (_('Important dates'), {
            'fields': ('last_login', 'date_joined'),
        }),
    )
    
    add_fieldsets = (
        (None, {
            'classes': ('wide',),
            'fields': ('phone_number', 'email', 'password1', 'password2'),
        }),
        (_('Personal info'), {
            'fields': ('first_name', 'last_name', 'username'),
        }),
        (_('Branch Assignment'), {
            'fields': ('branch',),
        }),
        (_('Role & Permissions'), {
            'fields': ('role', 'is_active', 'is_staff', 'is_superuser'),
        }),
    )
    
    readonly_fields = ['assigned_date', 'date_joined', 'last_login']
    
    actions = ['assign_to_portfolio_manager', 'unassign_from_portfolio_manager']
    
    def user_image_display(self, obj):
        """Display user profile image or default icon"""
        if obj.selfie:
            return format_html(
                '<img src="{}" width="40" height="40" style="border-radius: 50%; object-fit: cover;" />',
                obj.selfie.url
            )
        else:
            # Default user icon
            return format_html(
                '<div style="width: 40px; height: 40px; border-radius: 50%; background-color: #e0e0e0; '
                'display: flex; align-items: center; justify-content: center; color: #666; font-size: 16px;">'
                '👤</div>'
            )
    user_image_display.short_description = 'Photo'
    
    def branch_display(self, obj):
        """Display branch information with styling"""
        if hasattr(obj, 'branch') and obj.branch:
            return format_html(
                '<span style="background-color: #e3f2fd; color: #1976d2; padding: 2px 8px; '
                'border-radius: 12px; font-size: 11px; font-weight: bold;">{}</span>',
                obj.branch.name
            )
        return format_html(
            '<span style="color: #999; font-style: italic;">No Branch</span>'
        )
    branch_display.short_description = 'Branch'
    
    def portfolio_manager_link(self, obj):
        """Display portfolio manager with link to their profile"""
        if obj.portfolio_manager:
            url = reverse('admin:users_customuser_change', args=[obj.portfolio_manager.pk])
            return format_html(
                '<a href="{}">{}</a>',
                url,
                obj.portfolio_manager.get_full_name()
            )
        return format_html('<span style="color: #999;">Unassigned</span>')
    portfolio_manager_link.short_description = 'Portfolio Manager'
    
    def assignment_date(self, obj):
        """Display assignment date in a readable format"""
        if obj.assigned_date:
            return obj.assigned_date.strftime('%Y-%m-%d %H:%M')
        return '-'
    assignment_date.short_description = 'Assigned Date'
    
    def assign_to_portfolio_manager(self, request, queryset):
        """Bulk action to assign clients to a portfolio manager"""
        # This would open a form to select the portfolio manager
        # For now, we'll just show a message
        unassigned_clients = queryset.filter(role='borrower', portfolio_manager__isnull=True)
        count = unassigned_clients.count()
        
        if count == 0:
            self.message_user(request, "No unassigned clients selected.")
        else:
            self.message_user(
                request, 
                f"{count} clients ready for assignment. Use the Portfolio Management section to assign them."
            )
    assign_to_portfolio_manager.short_description = "Prepare selected clients for portfolio assignment"
    
    def unassign_from_portfolio_manager(self, request, queryset):
        """Bulk action to unassign clients from their portfolio managers"""
        assigned_clients = queryset.filter(role='borrower', portfolio_manager__isnull=False)
        count = 0
        
        for client in assigned_clients:
            # Deactivate current assignment
            PortfolioAssignment.objects.filter(
                client=client,
                is_active=True
            ).update(is_active=False, unassigned_date=get_current_datetime())
            
            # Clear portfolio manager
            client.portfolio_manager = None
            client.assigned_date = None
            client.save()
            count += 1
        
        self.message_user(request, f"Successfully unassigned {count} clients from their portfolio managers.")
    unassign_from_portfolio_manager.short_description = "Unassign selected clients from portfolio managers"
    
    def save_model(self, request, obj, form, change):
        """Override save to handle portfolio manager assignment"""
        old_manager = None
        
        if change and obj.pk:
            try:
                old_obj = CustomUser.objects.get(pk=obj.pk)
                old_manager = old_obj.portfolio_manager
            except CustomUser.DoesNotExist:
                pass
        
        # Check if portfolio manager changed
        if obj.portfolio_manager != old_manager:
            if old_manager:
                # Deactivate old assignment
                PortfolioAssignment.objects.filter(
                    client=obj,
                    portfolio_manager=old_manager,
                    is_active=True
                ).update(is_active=False, unassigned_date=get_current_datetime())
            
            if obj.portfolio_manager:
                # Set assignment date
                obj.assigned_date = get_current_datetime()
                
                # Create new portfolio assignment record
                PortfolioAssignment.objects.create(
                    client=obj,
                    portfolio_manager=obj.portfolio_manager,
                    assigned_by=request.user,
                    reason=f"Assigned via admin interface by {request.user.get_full_name()}"
                )
            else:
                # Clear assignment date if no manager
                obj.assigned_date = None
        
        super().save_model(request, obj, form, change)
    
    def get_queryset(self, request):
        """Optimize queryset with select_related"""
        qs = super().get_queryset(request).select_related('portfolio_manager')
        
        # Try to include branch if the field exists
        try:
            qs = qs.select_related('branch')
        except:
            pass  # Branch field might not exist
            
        return qs


@admin.register(PortfolioAssignment)
class PortfolioAssignmentAdmin(admin.ModelAdmin):
    list_display = [
        'client', 'portfolio_manager', 'assigned_by', 'assigned_date',
        'is_active', 'unassigned_date'
    ]
    list_filter = ['is_active', 'assigned_date', 'unassigned_date', 'portfolio_manager']
    search_fields = [
        'client__first_name', 'client__last_name', 'client__phone_number',
        'portfolio_manager__first_name', 'portfolio_manager__last_name'
    ]
    ordering = ['-assigned_date']
    
    fieldsets = (
        ('Assignment Details', {
            'fields': ('client', 'portfolio_manager', 'assigned_by', 'reason')
        }),
        ('Status', {
            'fields': ('is_active', 'assigned_date', 'unassigned_date')
        }),
    )
    
    readonly_fields = ['assigned_date', 'unassigned_date']


@admin.register(OTPVerification)
class OTPVerificationAdmin(admin.ModelAdmin):
    list_display = ('user', 'otp_code', 'is_used', 'created_at', 'expires_at')
    list_filter = ('is_used', 'created_at')
    search_fields = ('user__phone_number', 'user__email', 'otp_code')


@admin.register(Branch)
class BranchAdmin(admin.ModelAdmin):
    list_display = (
        'name', 'code', 'mpesa_shortcode_display', 'mpesa_config_status', 
        'is_main_branch', 'is_active', 'user_count', 'created_at'
    )
    list_filter = ('is_main_branch', 'is_active', 'created_at')
    search_fields = ('name', 'code', 'mpesa_shortcode')
    ordering = ('name',)
    
    class Media:
        css = {
            'all': ('admin/css/custom_branch_admin.css',)
        }
    
    fieldsets = (
        ('Basic Information', {
            'fields': ('name', 'code', 'address', 'phone_number', 'email')
        }),
        ('Status', {
            'fields': ('is_main_branch', 'is_active')
        }),
        ('M-Pesa Configuration', {
            'fields': (
                'mpesa_shortcode', 'mpesa_consumer_key', 'mpesa_consumer_secret', 'mpesa_passkey'
            ),
            'description': (
                '<div style="background-color: #ffebee; padding: 10px; border-left: 4px solid #d32f2f; margin-bottom: 10px;">'
                '<strong>🔴 REQUIRED:</strong> ALL branches <strong>MUST</strong> have M-Pesa settings configured to accept payments.<br>'
                'Enter your PayBill number, Consumer Key, Consumer Secret, and Passkey (for STK Push).<br>'
                '<strong>NO DEFAULT CREDENTIALS</strong> - Every branch requires manual configuration.'
                '</div>'
            )
        }),
    )
    
    def mpesa_shortcode_display(self, obj):
        """Display M-Pesa shortcode with styling"""
        shortcode = obj.get_mpesa_shortcode()
        if shortcode:
            return format_html(
                '<span style="background-color: #e8f5e8; color: #2e7d32; padding: 2px 8px; '
                'border-radius: 12px; font-size: 11px; font-weight: bold;">{}</span>',
                shortcode
            )
        else:
            return format_html(
                '<span style="background-color: #ffebee; color: #c62828; padding: 2px 8px; '
                'border-radius: 12px; font-size: 11px;">Not Set</span>'
            )
    mpesa_shortcode_display.short_description = 'M-Pesa Shortcode'
    
    def mpesa_config_status(self, obj):
        """Display M-Pesa configuration status with clear warnings"""
        if obj.has_mpesa_config():
            return format_html(
                '<span style="color: #2e7d32; font-weight: bold;">✓ Configured</span>'
            )
        else:
            return format_html(
                '<span style="background-color: #ffebee; color: #c62828; padding: 3px 8px; '
                'border-radius: 12px; font-size: 11px; font-weight: bold;">🔴 NOT CONFIGURED</span>'
            )
    mpesa_config_status.short_description = 'M-Pesa Status'
    
    def user_count(self, obj):
        """Display number of users in this branch"""
        count = obj.users.count()
        if count > 0:
            return format_html(
                '<span style="color: #1976d2; font-weight: bold;">{}</span>',
                count
            )
        return format_html('<span style="color: #999;">0</span>')
    user_count.short_description = 'Users'
    
    def save_model(self, request, obj, form, change):
        """Override save to handle main branch logic and show warnings"""
        # Ensure only one main branch exists
        if obj.is_main_branch:
            Branch.objects.filter(is_main_branch=True).exclude(pk=obj.pk).update(is_main_branch=False)
        
        super().save_model(request, obj, form, change)
        
        # Show warning if M-Pesa configuration is incomplete for ANY branch
        if not obj.has_mpesa_config():
            self.message_user(
                request,
                f"🔴 CRITICAL: Branch '{obj.name}' does not have M-Pesa configuration. "
                f"This branch CANNOT process payments until M-Pesa settings are configured.",
                level='ERROR'
            )
    
    def changelist_view(self, request, extra_context=None):
        """Add warning banner for branches without M-Pesa config"""
        extra_context = extra_context or {}
        
        # Get ALL branches without M-Pesa config (including main branch)
        unconfigured_branches = Branch.objects.filter(
            is_active=True
        ).exclude(
            mpesa_shortcode__isnull=False,
            mpesa_consumer_key__isnull=False,
            mpesa_consumer_secret__isnull=False
        )
        
        extra_context['unconfigured_branches'] = unconfigured_branches
        extra_context['unconfigured_count'] = unconfigured_branches.count()

        return super().changelist_view(request, extra_context=extra_context)
