"""
Django Admin Configuration for Agency and Brand Management

This module provides comprehensive admin interface configurations for:
- Agency: Marketing/advertising agencies
- Brand: Brands managed by agencies  
- Advertisers: Users associated with brands

Author: Generated for Django Admin Interface
Created: 2025
"""

from django.contrib import admin
from django.utils.html import format_html
from django.utils.translation import gettext_lazy as _
from django.urls import reverse
from django.utils.safestring import mark_safe
from django.db.models import Count, Q
from django.contrib.admin import SimpleListFilter

from .models import Agency, Brand, Advertiser, BrandCategory, BrandStatus


# ============================================================================
# CUSTOM FILTERS FOR ENHANCED ADMIN FUNCTIONALITY
# ============================================================================

class BrandCountFilter(SimpleListFilter):
    """
    Custom filter to filter agencies by number of brands they manage.
    Provides quick filtering options for agencies with different brand volumes.
    """
    title = _('Brand Count')
    parameter_name = 'brand_count'

    def lookups(self, request, model_admin):
        """Define filter options for brand count ranges"""
        return (
            ('0', _('No Brands')),
            ('1-5', _('1-5 Brands')),
            ('6-10', _('6-10 Brands')),
            ('11+', _('11+ Brands')),
        )

    def queryset(self, request, queryset):
        """Apply filtering logic based on selected option"""
        queryset = queryset.annotate(brand_count=Count('brands'))
        
        if self.value() == '0':
            return queryset.filter(brand_count=0)
        elif self.value() == '1-5':
            return queryset.filter(brand_count__range=(1, 5))
        elif self.value() == '6-10':
            return queryset.filter(brand_count__range=(6, 10))
        elif self.value() == '11+':
            return queryset.filter(brand_count__gte=11)
        
        return queryset


class ActiveBrandsFilter(SimpleListFilter):
    """
    Filter to show agencies based on their active brand status.
    Helps identify agencies with active vs inactive brand portfolios.
    """
    title = _('Active Brands Status')
    parameter_name = 'active_brands'

    def lookups(self, request, model_admin):
        """Define filter options for active brand status"""
        return (
            ('has_active', _('Has Active Brands')),
            ('no_active', _('No Active Brands')),
            ('all_active', _('All Brands Active')),
        )

    def queryset(self, request, queryset):
        """Apply filtering logic for active brands"""
        if self.value() == 'has_active':
            return queryset.filter(brands__status=BrandStatus.ACTIVE).distinct()
        elif self.value() == 'no_active':
            return queryset.exclude(brands__status=BrandStatus.ACTIVE).distinct()
        elif self.value() == 'all_active':
            # Agencies where all brands are active (excluding agencies with no brands)
            return queryset.annotate(
                total_brands=Count('brands'),
                active_brands=Count('brands', filter=Q(brands__status=BrandStatus.ACTIVE))
            ).filter(
                total_brands__gt=0,
                total_brands=models.F('active_brands')
            )
        
        return queryset


# ============================================================================
# INLINE ADMIN CLASSES FOR RELATED OBJECTS
# ============================================================================

class BrandInline(admin.TabularInline):
    """
    Inline admin for Brand model within Agency admin.
    Allows management of brands directly from the agency detail page.
    """
    model = Brand
    extra = 1  # Number of empty forms to display
    min_num = 0  # Minimum number of forms required
    max_num = 10  # Maximum number of inline forms allowed
    
    # Fields to display in the inline form
    fields = ('name', 'category', 'status', 'is_featured', 'logo_preview')
    readonly_fields = ('logo_preview',)  # Make logo preview read-only
    
    # Customize inline form appearance
    classes = ('collapse',)  # Make inline collapsible
    verbose_name = _('Brand')
    verbose_name_plural = _('Brands')

    def logo_preview(self, obj):
        """
        Display a small preview of the brand logo in the inline form.
        Returns HTML for image display or placeholder text.
        """
        if obj.logo:
            return format_html(
                '<img src="{}" width="50" height="50" style="object-fit: cover; border-radius: 4px;" />',
                obj.logo.url
            )
        return _('No logo')
    
    logo_preview.short_description = _('Logo Preview')


class AdvertisersInline(admin.TabularInline):
    """
    Inline admin for Advertisers model within Brand admin.
    Shows users associated with each brand for quick management.
    """
    model = Advertiser
    extra = 1  # Number of empty forms to display
    min_num = 0  # Minimum number of forms required
    
    # Fields to display in the inline form
    fields = ('id_user', 'status')
    
    # Customize appearance
    verbose_name = _('Advertiser')
    verbose_name_plural = _('Advertisers')


# ============================================================================
# MAIN ADMIN CLASSES
# ============================================================================

@admin.register(Agency)
class AgencyAdmin(admin.ModelAdmin):
    """
    Comprehensive admin interface for Agency model.
    Provides full CRUD operations with enhanced filtering and display options.
    """
    
    # ===== LIST VIEW CONFIGURATION =====
    list_display = (
        'name',                    # Agency name
        'owner_link',             # Clickable link to owner profile
        'brand_count',            # Number of brands managed
        'active_brand_count',     # Number of active brands
        'description_short',      # Truncated description
        'created_at',           # Creation date
        'status_indicator',       # Visual status indicator
    )
    
    # Fields that can be clicked to view/edit the object
    list_display_links = ('name',)
    
    # Fields available for filtering in the right sidebar
    list_filter = (
        BrandCountFilter,         # Custom filter for brand count
        ActiveBrandsFilter,       # Custom filter for active brands 
        'is_deleted',             # Filter by deletion status
        'owner',                  # Filter by owner
    )
    
    # Fields available for search functionality
    search_fields = (
        'name',                   # Search by agency name
        'description',            # Search by description
        'owner__username',        # Search by owner username
        'owner__email',           # Search by owner email
    )
    
    # Default ordering of the list view
    ordering = ('name',)
    
    # Number of items per page
    list_per_page = 25
    
    # Enable select all checkbox
    list_select_related = ('owner',)  # Optimize database queries
    
    # ===== DETAIL VIEW CONFIGURATION =====
    fieldsets = (
        (_('Basic Information'), {
            'fields': ('name', 'owner', 'description'),
            'description': _('Core agency information and ownership details.'),
        }),
        (_('Metadata'), {
            'fields': ( 'is_deleted', 'created_at'),
            'classes': ('collapse',),  # Collapsible section
            'description': _('Administrative metadata and status information.'),
        }),
    )
    
    # Related object inlines
    inlines = [BrandInline]
    
    # ===== CUSTOM ADMIN METHODS =====
    
    def owner_link(self, obj):
        """
        Create a clickable link to the owner's user profile.
        Provides easy navigation to related user information.
        """
        if obj.owner:
            url = reverse('admin:accounts_user_change', args=[obj.owner.pk])
            return format_html('<a href="{}">{}</a>', url, obj.owner.username)
        return _('No Owner')
    
    owner_link.short_description = _('Owner')
    owner_link.admin_order_field = 'owner__username'  # Enable sorting
    
    def brand_count(self, obj):
        """
        Display the total number of brands managed by this agency.
        Includes a link to filter brands by this agency.
        """
        count = obj.brands.count()
        if count > 0:
            url = reverse('admin:agencies_brand_changelist')
            return format_html(
                '<a href="{}?agency__id__exact={}">{} brands</a>',
                url, obj.pk, count
            )
        return '0 brands'
    
    brand_count.short_description = _('Total Brands')
    
    def active_brand_count(self, obj):
        """
        Display the number of active brands managed by this agency.
        Provides quick insight into agency activity level.
        """
        count = obj.brands.filter(status=BrandStatus.ACTIVE).count()
        return f'{count} active'
    
    active_brand_count.short_description = _('Active Brands')
    
    def description_short(self, obj):
        """
        Display truncated description for better list view readability.
        Shows first 50 characters with ellipsis if longer.
        """
        if obj.description:
            return (obj.description[:50] + '...') if len(obj.description) > 50 else obj.description
        return _('No description')
    
    description_short.short_description = _('Description')
    
    def status_indicator(self, obj):
        """
        Visual indicator for agency status based on deletion flag.
        Uses color-coded badges for quick status recognition.
        """
        if obj.is_deleted:
            return format_html(
                '<span style="color: red; font-weight: bold;">●</span> {}',
                _('Deleted')
            )
        else:
            return format_html(
                '<span style="color: green; font-weight: bold;">●</span> {}',
                _('Active')
            )
    
    status_indicator.short_description = _('Status')
    
    # ===== ADMIN ACTIONS =====
    
    def mark_as_deleted(self, request, queryset):
        """
        Bulk action to mark selected agencies as deleted.
        Soft delete functionality for data preservation.
        """
        updated = queryset.update(is_deleted=1)
        self.message_user(
            request,
            f'{updated} agencies were marked as deleted.',
        )
    
    mark_as_deleted.short_description = _('Mark selected agencies as deleted')
    
    def restore_agencies(self, request, queryset):
        """
        Bulk action to restore deleted agencies.
        Allows recovery of soft-deleted records.
        """
        updated = queryset.update(is_deleted=0)
        self.message_user(
            request,
            f'{updated} agencies were restored.',
        )
    
    restore_agencies.short_description = _('Restore selected agencies')
    
    # Register custom actions
    actions = ['mark_as_deleted', 'restore_agencies']


@admin.register(Brand)
class BrandAdmin(admin.ModelAdmin):
    """
    Comprehensive admin interface for Brand model.
    Provides advanced brand management with visual elements and filtering.
    """
    
    # ===== LIST VIEW CONFIGURATION =====
    list_display = (
        'logo_thumbnail',         # Small logo preview
        'name',                   # Brand name
        'agency_link',            # Link to parent agency
        'category',               # Brand category
        'status_badge',           # Visual status indicator
        'is_featured',            # Featured status
        'advertiser_count',       # Number of associated advertisers
        'created_info',           # Creation information
    )
    
    # Clickable fields in list view
    list_display_links = ('name', 'logo_thumbnail')
    
    # # Editable fields directly in list view
    # list_editable = ('status', 'is_featured')
    list_editable = ('is_featured',)
    
    # Filtering options in right sidebar
    list_filter = (
        'status',                 # Filter by brand status
        'category',               # Filter by category
        'is_featured',            # Filter by featured status
        'agency',                 # Filter by agency
        'created_at',             # Filter by creation date (assuming BaseModel has this)
    )
    
    # Search functionality
    search_fields = (
        'name',                   # Search by brand name
        'description',            # Search by description
        'agency__name',           # Search by agency name
    )
    
    # Default ordering
    ordering = ('name',)
    
    # Pagination settings
    list_per_page = 30
    
    # Optimize database queries
    list_select_related = ('agency',)
    
    # ===== DETAIL VIEW CONFIGURATION =====
    fieldsets = (
        (_('Brand Identity'), {
            'fields': ('name', 'logo', 'logo_preview', 'description'),
            'description': _('Core brand identity elements including name, logo, and description.'),
        }),
        (_('Classification'), {
            'fields': ('agency', 'category', 'status', 'is_featured'),
            'description': _('Brand categorization and status information.'),
        }),
    )
    
    # Read-only fields
    readonly_fields = ('logo_preview',)
    
    # Form widget customization
    filter_horizontal = ()  # For ManyToMany fields if any
    
    # Related object inlines
    inlines = [AdvertisersInline]
    
    # ===== CUSTOM ADMIN METHODS =====
    
    def logo_thumbnail(self, obj):
        """
        Display small logo thumbnail in list view.
        Provides visual brand identification at a glance.
        """
        if obj.logo:
            return format_html(
                '<img src="{}" width="40" height="40" '
                'style="object-fit: cover; border-radius: 4px; border: 1px solid #ddd;" />',
                obj.logo.url
            )
        return format_html(
            '<div style="width: 40px; height: 40px; background: #f0f0f0; '
            'border-radius: 4px; display: flex; align-items: center; '
            'justify-content: center; font-size: 12px; color: #666;">No Logo</div>'
        )
    
    logo_thumbnail.short_description = _('Logo')
    
    def logo_preview(self, obj):
        """
        Display larger logo preview in detail view.
        Shows full-size logo for detailed inspection.
        """
        if obj.logo:
            return format_html(
                '<img src="{}" style="max-width: 200px; max-height: 200px; '
                'object-fit: contain; border: 1px solid #ddd; border-radius: 4px;" />',
                obj.logo.url
            )
        return _('No logo uploaded')
    
    logo_preview.short_description = _('Logo Preview')
    
    def agency_link(self, obj):
        """
        Create clickable link to the parent agency.
        Enables easy navigation to agency details.
        """
        if obj.agency:
            url = reverse('admin:agencies_agency_change', args=[obj.agency.pk])
            return format_html('<a href="{}">{}</a>', url, obj.agency.name)
        return _('No Agency')
    
    agency_link.short_description = _('Agency')
    agency_link.admin_order_field = 'agency__name'  # Enable sorting
    
    def status_badge(self, obj):
        """
        Display color-coded status badge for visual status identification.
        Uses different colors for different status types.
        """
        status_colors = {
            BrandStatus.ACTIVE: '#28a745',      # Green
            BrandStatus.INACTIVE: '#6c757d',    # Gray
            BrandStatus.PENDING: '#ffc107',     # Yellow
            BrandStatus.SUSPENDED: '#dc3545',   # Red
            BrandStatus.ARCHIVED: '#17a2b8',    # Blue
        }
        
        color = status_colors.get(obj.status, '#6c757d')
        return format_html(
            '<span style="background-color: {}; color: white; padding: 3px 8px; '
            'border-radius: 12px; font-size: 11px; font-weight: bold;">{}</span>',
            color,
            obj.get_status_display()
        )
    
    status_badge.short_description = _('Status')
    status_badge.admin_order_field = 'status'  # Enable sorting
    
    def advertiser_count(self, obj):
        """
        Display count of advertisers associated with this brand.
        Provides insight into brand team size.
        """
        count = obj.advertisers_set.count()
        if count > 0:
            url = reverse('admin:agencies_advertisers_changelist')
            return format_html(
                '<a href="{}?brand__id__exact={}">{} advertisers</a>',
                url, obj.pk, count
            )
        return '0 advertisers'
    
    advertiser_count.short_description = _('Advertisers')
    
    def created_info(self, obj):
        """
        Display creation date information.
        Shows when the brand was added to the system.
        """
        if hasattr(obj, 'created_at') and obj.created_at:
            return obj.created_at.strftime('%Y-%m-%d')
        return _('Unknown')
    
    created_info.short_description = _('Created')
    
    # ===== BULK ACTIONS =====
    
    def activate_brands(self, request, queryset):
        """
        Bulk action to activate selected brands.
        Sets status to active for multiple brands at once.
        """
        updated = queryset.update(status=BrandStatus.ACTIVE)
        self.message_user(
            request,
            f'{updated} brands were activated.',
        )
    
    activate_brands.short_description = _('Activate selected brands')
    
    def feature_brands(self, request, queryset):
        """
        Bulk action to mark selected brands as featured.
        Highlights important brands across the platform.
        """
        updated = queryset.update(is_featured=True)
        self.message_user(
            request,
            f'{updated} brands were marked as featured.',
        )
    
    feature_brands.short_description = _('Mark selected brands as featured')
    
    def unfeature_brands(self, request, queryset):
        """
        Bulk action to remove featured status from selected brands.
        Removes highlighting from brands.
        """
        updated = queryset.update(is_featured=False)
        self.message_user(
            request,
            f'{updated} brands were unmarked as featured.',
        )
    
    unfeature_brands.short_description = _('Remove featured status from selected brands')
    
    # Register custom actions
    actions = ['activate_brands', 'feature_brands', 'unfeature_brands']


@admin.register(Advertiser)
class AdvertisersAdmin(admin.ModelAdmin):
    """
    Admin interface for Advertisers model.
    Manages the relationship between users and brands.
    """
    
    # ===== LIST VIEW CONFIGURATION =====
    list_display = (
        'user_info',              # User information with link
        'brand_link',             # Brand information with link
        'status_display',         # Status with formatting
        'relationship_info',      # Additional relationship context
    )
    
    # Clickable fields
    list_display_links = ('user_info',)
    
    # # Editable fields in list view
    # list_editable = ('status',)
    
    # Filtering options
    list_filter = (
        'status',                 # Filter by status
        'brand__agency',          # Filter by brand's agency
        'brand__category',        # Filter by brand category
        'brand__status',          # Filter by brand status
    )
    
    # Search functionality
    search_fields = (
        'id_user__username',      # Search by username
        'id_user__email',         # Search by email
        'id_user__first_name',    # Search by first name
        'id_user__last_name',     # Search by last name
        'brand__name',            # Search by brand name
    )
    
    # Default ordering
    ordering = ('id_user__username', 'brand__name')
    
    # Optimize queries
    list_select_related = ('id_user', 'brand', 'brand__agency')
    
    # Pagination
    list_per_page = 25
    
    # ===== DETAIL VIEW CONFIGURATION =====
    fieldsets = (
        (_('Relationship'), {
            'fields': ('id_user', 'brand', 'status'),
            'description': _('Define the relationship between user and brand.'),
        }),
    )
    
    # ===== CUSTOM ADMIN METHODS =====
    
    def user_info(self, obj):
        """
        Display comprehensive user information with link.
        Shows name, username, and email for easy identification.
        """
        if obj.id_user:
            url = reverse('admin:accounts_user_change', args=[obj.id_user.pk])
            display_name = f"{obj.id_user.get_full_name()}" if obj.id_user.get_full_name() else obj.id_user.username
            return format_html(
                '<a href="{}">{}</a><br><small style="color: #666;">{}</small>',
                url, display_name, obj.id_user.email or obj.id_user.username
            )
        return _('No User')
    
    user_info.short_description = _('User')
    user_info.admin_order_field = 'id_user__username'
    
    def brand_link(self, obj):
        """
        Display brand information with link to brand admin.
        Shows brand name and parent agency for context.
        """
        if obj.brand:
            url = reverse('admin:agencies_brand_change', args=[obj.brand.pk])
            agency_name = obj.brand.agency.name if obj.brand.agency else _('No Agency')
            return format_html(
                '<a href="{}">{}</a><br><small style="color: #666;">{}</small>',
                url, obj.brand.name, agency_name
            )
        return _('No Brand')
    
    brand_link.short_description = _('Brand')
    brand_link.admin_order_field = 'brand__name'
    
    def status_display(self, obj):
        """
        Display formatted status information.
        Provides visual styling for different status types.
        """
        if obj.status:
            # Define status colors (you can customize these)
            status_colors = {
                'active': '#28a745',
                'inactive': '#6c757d',
                'pending': '#ffc107',
                'suspended': '#dc3545',
            }
            
            # Get color based on status (default to gray if not found)
            color = status_colors.get(obj.status.lower(), '#6c757d')
            
            return format_html(
                '<span style="color: {}; font-weight: bold;">{}</span>',
                color, obj.status.title()
            )
        return _('No Status')
    
    status_display.short_description = _('Status')
    status_display.admin_order_field = 'status'
    
    def relationship_info(self, obj):
        """
        Display additional context about the user-brand relationship.
        Shows helpful metadata for relationship management.
        """
        info_parts = []
        
        # Add brand category information
        if obj.brand and obj.brand.category:
            info_parts.append(f"Category: {obj.brand.get_category_display()}")
        
        # Add brand status
        if obj.brand and obj.brand.status:
            info_parts.append(f"Brand: {obj.brand.get_status_display()}")
        
        # Add user status if available
        if obj.id_user and hasattr(obj.id_user, 'is_active'):
            user_status = "Active User" if obj.id_user.is_active else "Inactive User"
            info_parts.append(user_status)
        
        return format_html('<br>'.join(info_parts)) if info_parts else _('No additional info')
    
    relationship_info.short_description = _('Additional Info')
    
    # ===== BULK ACTIONS =====
    
    def activate_relationships(self, request, queryset):
        """
        Bulk action to activate selected advertiser relationships.
        """
        updated = queryset.update(status='active')
        self.message_user(
            request,
            f'{updated} advertiser relationships were activated.',
        )
    
    activate_relationships.short_description = _('Activate selected relationships')
    
    def deactivate_relationships(self, request, queryset):
        """
        Bulk action to deactivate selected advertiser relationships.
        """
        updated = queryset.update(status='inactive')
        self.message_user(
            request,
            f'{updated} advertiser relationships were deactivated.',
        )
    
    deactivate_relationships.short_description = _('Deactivate selected relationships')
    
    # Register actions
    actions = ['activate_relationships', 'deactivate_relationships']


# ============================================================================
# ADMIN SITE CUSTOMIZATION
# ============================================================================

# Customize admin site headers and titles
admin.site.site_header = _('Agency & Brand Management System')
admin.site.site_title = _('Agency Admin')
admin.site.index_title = _('Welcome to Agency & Brand Management')

# Optional: Register models individually if needed
# admin.site.register(Agency, AgencyAdmin)
# admin.site.register(Brand, BrandAdmin)
# admin.site.register(Advertisers, AdvertisersAdmin)