# -*- coding: utf-8 -*-

from django.contrib import admin
from django.utils.html import format_html
from django.urls import reverse
from django.utils import timezone
from django.db.models import Sum, Avg, Count
from django.utils.safestring import mark_safe
from .models import (
    CampaignObjective,
    Campaign,
    TargetingRule,
    Creative,
    CampaignSchedule,
    CampaignPerformance
)


@admin.register(CampaignObjective)
class CampaignObjectiveAdmin(admin.ModelAdmin):
    """
    Django admin configuration for CampaignObjective model.
    
    Provides interface for managing campaign objectives including
    filtering, searching, and bulk operations.
    """
    
    list_display = [
        'name',
        'objective_type',
        'kpi_metric',
        'target_value',
        'campaign_count',
        'is_active',
        'created_at'
    ]
    list_filter = [
        'objective_type',
        'is_active',
        'created_at',
        'updated_at'
    ]
    search_fields = [
        'name',
        'description',
        'kpi_metric'
    ]
    ordering = ['name']
    readonly_fields = ['created_at', 'updated_at']
    
    fieldsets = [
        ('Basic Information', {
            'fields': ('name', 'objective_type', 'description')
        }),
        ('KPI Settings', {
            'fields': ('kpi_metric', 'target_value')
        }),
        ('Status', {
            'fields': ('is_active',)
        }),
        ('Timestamps', {
            'fields': ('created_at', 'updated_at'),
            'classes': ('collapse',)
        })
    ]
    
    def campaign_count(self, obj):
        """Display number of campaigns using this objective."""
        count = obj.campaigns.count()
        if count > 0:
            url = reverse('admin:campaigns_campaign_changelist')
            return format_html(
                '<a href="{}?objective__id__exact={}">{} campaigns</a>',
                url, obj.id, count
            )
        return '0 campaigns'
    campaign_count.short_description = 'Campaigns'
    campaign_count.admin_order_field = 'campaigns__count'
    
    def get_queryset(self, request):
        """Optimize queryset with annotations."""
        queryset = super().get_queryset(request)
        return queryset.annotate(
            campaigns_count=Count('campaigns')
        )


class TargetingRuleInline(admin.TabularInline):
    """
    Inline admin for TargetingRule model.
    
    Allows managing targeting rules directly from the Campaign admin page.
    """
    
    model = TargetingRule
    extra = 1
    fields = [
        'name',
        'targeting_type',
        'field_name',
        'operator',
        'value',
        'is_include',
        'priority',
        'is_active'
    ]
    ordering = ['-priority', 'name']


class CreativeInline(admin.TabularInline):
    """
    Inline admin for Creative model.
    
    Allows managing creatives directly from the Campaign admin page.
    """
    
    model = Creative
    extra = 1
    fields = [
        'name',
        'creative_type',
        'title',
        'call_to_action',
        'is_active',
        'is_approved'
    ]
    readonly_fields = ['impressions', 'clicks', 'conversions']


class CampaignScheduleInline(admin.TabularInline):
    """
    Inline admin for CampaignSchedule model.
    
    Allows managing campaign schedules directly from the Campaign admin page.
    """
    
    model = CampaignSchedule
    extra = 1
    fields = [
        'name',
        'schedule_type',
        'start_time',
        'end_time',
        'budget_percentage',
        'is_active'
    ]


@admin.register(Campaign)
class CampaignAdmin(admin.ModelAdmin):
    """
    Django admin configuration for Campaign model.
    
    Provides comprehensive interface for managing campaigns including
    performance metrics, budget tracking, and status management.
    """
    
    list_display = [
        'name',
        'code',
        'advertiser',
        'brand',
        'status_badge',
        'budget_display',
        'performance_summary',
        'date_range',
        'created_by',
        'created_at'
    ]
    list_filter = [
        'status',
        'budget_type',
        'bidding_strategy',
        'advertiser',
        'brand',
        'objective',
        'is_active',
        'auto_optimize',
        'created_at',
        'start_date',
        'end_date'
    ]
    search_fields = [
        'name',
        'code',
        'description',
        'advertiser__name',
        'brand__name'
    ]
    ordering = ['-created_at']
    readonly_fields = [
        'id',
        'spent_amount',
        'impressions',
        'clicks',
        'conversions',
        'remaining_budget',
        'budget_utilization',
        'ctr',
        'conversion_rate',
        'is_running',
        'created_at',
        'updated_at',
        'approved_at',
        'launched_at'
    ]
    
    fieldsets = [
        ('Basic Information', {
            'fields': (
                'id',
                'name',
                'code',
                'description',
                'advertiser',
                'brand',
                'objective',
                'created_by'
            )
        }),
        ('Status & Lifecycle', {
            'fields': (
                'status',
                'is_active',
                'auto_optimize'
            )
        }),
        ('Budget & Bidding', {
            'fields': (
                'budget_type',
                'budget_amount',
                'spent_amount',
                'remaining_budget',
                'budget_utilization',
                'bidding_strategy',
                'max_bid'
            )
        }),
        ('Scheduling', {
            'fields': (
                'start_date',
                'end_date',
                'timezone',
                'frequency_cap'
            )
        }),
        ('Performance Metrics', {
            'fields': (
                'impressions',
                'clicks',
                'conversions',
                'ctr',
                'conversion_rate',
                'is_running'
            ),
            'classes': ('collapse',)
        }),
        ('Timestamps', {
            'fields': (
                'created_at',
                'updated_at',
                'approved_at',
                'launched_at'
            ),
            'classes': ('collapse',)
        })
    ]
    
    inlines = [TargetingRuleInline, CreativeInline, CampaignScheduleInline]
    
    actions = [
        'activate_campaigns',
        'pause_campaigns',
        'approve_campaigns',
        'export_performance_data'
    ]
    
    def status_badge(self, obj):
        """Display campaign status with color-coded badge."""
        colors = {
            'draft': 'gray',
            'pending_approval': 'orange',
            'approved': 'blue',
            'active': 'green',
            'paused': 'yellow',
            'completed': 'purple',
            'cancelled': 'red',
            'rejected': 'red'
        }
        color = colors.get(obj.status, 'gray')
        return format_html(
            '<span style="background-color: {}; color: white; padding: 3px 8px; '
            'border-radius: 3px; font-size: 11px;">{}</span>',
            color,
            obj.get_status_display()
        )
    status_badge.short_description = 'Status'
    status_badge.admin_order_field = 'status'
    
    def budget_display(self, obj):
        """Display budget information with utilization."""
        utilization = obj.budget_utilization
        color = 'green' if utilization < 80 else 'orange' if utilization < 95 else 'red'
        
        return format_html(
            '${:,.2f} / ${:,.2f}<br/>'
            '<div style="background-color: #f0f0f0; border-radius: 3px; overflow: hidden;">' 
            '<div style="background-color: {}; height: 4px; width: {}%;"></div></div>'
            '<small>{:.1f}% used</small>',
            obj.spent_amount,
            obj.budget_amount,
            color,
            min(utilization, 100),
            utilization
        )
    budget_display.short_description = 'Budget (Spent/Total)'
    budget_display.admin_order_field = 'budget_amount'
    
    def performance_summary(self, obj):
        """Display key performance metrics."""
        return format_html(
            '<strong>Impressions:</strong> {:,}<br/>'
            '<strong>Clicks:</strong> {:,}<br/>'
            '<strong>CTR:</strong> {:.2f}%<br/>'
            '<strong>Conversions:</strong> {:,}',
            obj.impressions,
            obj.clicks,
            obj.ctr,
            obj.conversions
        )
    performance_summary.short_description = 'Performance'
    
    def date_range(self, obj):
        """Display campaign date range."""
        start = obj.start_date.strftime('%Y-%m-%d %H:%M')
        if obj.end_date:
            end = obj.end_date.strftime('%Y-%m-%d %H:%M')
            return f"{start}<br/>to {end}"
        return f"{start}<br/>to Ongoing"
    date_range.short_description = 'Date Range'
    date_range.admin_order_field = 'start_date'
    
    def activate_campaigns(self, request, queryset):
        """Bulk action to activate selected campaigns."""
        activated = 0
        for campaign in queryset:
            if campaign.can_be_activated():
                campaign.activate()
                activated += 1
        
        self.message_user(
            request,
            f"Successfully activated {activated} campaigns."
        )
    activate_campaigns.short_description = "Activate selected campaigns"
    
    def pause_campaigns(self, request, queryset):
        """Bulk action to pause selected campaigns."""
        paused = 0
        for campaign in queryset.filter(status='active'):
            campaign.pause()
            paused += 1
        
        self.message_user(
            request,
            f"Successfully paused {paused} campaigns."
        )
    pause_campaigns.short_description = "Pause selected campaigns"
    
    def approve_campaigns(self, request, queryset):
        """Bulk action to approve selected campaigns."""
        approved = queryset.filter(status='pending_approval').update(
            status='approved',
            approved_at=timezone.now()
        )
        
        self.message_user(
            request,
            f"Successfully approved {approved} campaigns."
        )
    approve_campaigns.short_description = "Approve selected campaigns"
    
    def export_performance_data(self, request, queryset):
        """Export performance data for selected campaigns."""
        # This would typically generate a CSV or Excel file
        self.message_user(
            request,
            f"Performance data export initiated for {queryset.count()} campaigns."
        )
    export_performance_data.short_description = "Export performance data"
    
    def get_queryset(self, request):
        """Optimize queryset with select_related."""
        queryset = super().get_queryset(request)
        return queryset.select_related(
            'advertiser',
            'brand',
            'objective',
            'created_by'
        )


@admin.register(TargetingRule)
class TargetingRuleAdmin(admin.ModelAdmin):
    """
    Django admin configuration for TargetingRule model.
    
    Provides interface for managing campaign targeting rules.
    """
    
    list_display = [
        'name',
        'campaign',
        'targeting_type',
        'field_name',
        'operator',
        'value_preview',
        'is_include',
        'priority',
        'is_active'
    ]
    list_filter = [
        'targeting_type',
        'operator',
        'is_include',
        'is_active',
        'campaign__advertiser',
        'created_at'
    ]
    search_fields = [
        'name',
        'field_name',
        'value',
        'campaign__name'
    ]
    ordering = ['-priority', 'name']
    readonly_fields = ['created_at', 'updated_at']
    
    fieldsets = [
        ('Basic Information', {
            'fields': ('campaign', 'name', 'targeting_type')
        }),
        ('Targeting Criteria', {
            'fields': ('field_name', 'operator', 'value', 'is_include')
        }),
        ('Settings', {
            'fields': ('priority', 'is_active')
        }),
        ('Timestamps', {
            'fields': ('created_at', 'updated_at'),
            'classes': ('collapse',)
        })
    ]
    
    def value_preview(self, obj):
        """Display truncated value for list view."""
        if len(obj.value) > 50:
            return f"{obj.value[:50]}..."
        return obj.value
    value_preview.short_description = 'Value'
    value_preview.admin_order_field = 'value'
    
    def get_queryset(self, request):
        """Optimize queryset with select_related."""
        queryset = super().get_queryset(request)
        return queryset.select_related('campaign', 'campaign__advertiser')


@admin.register(Creative)
class CreativeAdmin(admin.ModelAdmin):
    """
    Django admin configuration for Creative model.
    
    Provides interface for managing campaign creative assets.
    """
    
    list_display = [
        'name',
        'campaign',
        'creative_type',
        'format',
        'dimensions',
        'performance_summary',
        'approval_status',
        'is_active',
        'created_at'
    ]
    list_filter = [
        'creative_type',
        'format',
        'is_active',
        'is_approved',
        'campaign__advertiser',
        'created_at'
    ]
    search_fields = [
        'name',
        'title',
        'description',
        'campaign__name'
    ]
    ordering = ['-created_at']
    readonly_fields = [
        'file_size',
        'impressions',
        'clicks',
        'conversions',
        'ctr',
        'conversion_rate',
        'created_at',
        'updated_at',
        'approved_at'
    ]
    
    fieldsets = [
        ('Basic Information', {
            'fields': (
                'campaign',
                'name',
                'creative_type',
                'format'
            )
        }),
        ('Content', {
            'fields': (
                'title',
                'description',
                'call_to_action'
            )
        }),
        ('Media Files', {
            'fields': (
                'image_file',
                'video_file',
                'html_content'
            )
        }),
        ('URLs', {
            'fields': (
                'landing_url',
                'tracking_url'
            )
        }),
        ('Specifications', {
            'fields': (
                'width',
                'height',
                'file_size',
                'duration'
            )
        }),
        ('Performance', {
            'fields': (
                'impressions',
                'clicks',
                'conversions',
                'ctr',
                'conversion_rate'
            ),
            'classes': ('collapse',)
        }),
        ('Status', {
            'fields': (
                'is_active',
                'is_approved'
            )
        }),
        ('Timestamps', {
            'fields': (
                'created_at',
                'updated_at',
                'approved_at'
            ),
            'classes': ('collapse',)
        })
    ]
    
    def dimensions(self, obj):
        """Display creative dimensions."""
        if obj.width and obj.height:
            return f"{obj.width} x {obj.height}px"
        return "-"
    dimensions.short_description = 'Dimensions'
    
    def performance_summary(self, obj):
        """Display creative performance metrics."""
        return format_html(
            '<strong>Impressions:</strong> {:,}<br/>'
            '<strong>Clicks:</strong> {:,}<br/>'
            '<strong>CTR:</strong> {:.2f}%',
            obj.impressions,
            obj.clicks,
            obj.ctr
        )
    performance_summary.short_description = 'Performance'
    
    def approval_status(self, obj):
        """Display approval status with badge."""
        if obj.is_approved:
            return format_html(
                '<span style="background-color: green; color: white; padding: 2px 6px; '
                'border-radius: 3px; font-size: 10px;">APPROVED</span>'
            )
        return format_html(
            '<span style="background-color: orange; color: white; padding: 2px 6px; '
            'border-radius: 3px; font-size: 10px;">PENDING</span>'
        )
    approval_status.short_description = 'Approval'
    approval_status.admin_order_field = 'is_approved'
    
    def get_queryset(self, request):
        """Optimize queryset with select_related."""
        queryset = super().get_queryset(request)
        return queryset.select_related('campaign', 'campaign__advertiser')


@admin.register(CampaignSchedule)
class CampaignScheduleAdmin(admin.ModelAdmin):
    """
    Django admin configuration for CampaignSchedule model.
    
    Provides interface for managing campaign scheduling rules.
    """
    
    list_display = [
        'name',
        'campaign',
        'schedule_type',
        'time_range',
        'budget_percentage',
        'active_status',
        'is_active'
    ]
    list_filter = [
        'schedule_type',
        'is_active',
        'campaign__advertiser',
        'created_at'
    ]
    search_fields = [
        'name',
        'campaign__name'
    ]
    ordering = ['campaign', 'name']
    readonly_fields = ['created_at', 'updated_at']
    
    fieldsets = [
        ('Basic Information', {
            'fields': ('campaign', 'name', 'schedule_type')
        }),
        ('Time Settings', {
            'fields': (
                'days_of_week',
                'start_time',
                'end_time'
            )
        }),
        ('Date Settings', {
            'fields': (
                'specific_dates',
                'exclude_dates'
            )
        }),
        ('Budget Allocation', {
            'fields': ('budget_percentage',)
        }),
        ('Status', {
            'fields': ('is_active',)
        }),
        ('Timestamps', {
            'fields': ('created_at', 'updated_at'),
            'classes': ('collapse',)
        })
    ]
    
    def time_range(self, obj):
        """Display time range for the schedule."""
        if obj.start_time and obj.end_time:
            return f"{obj.start_time.strftime('%H:%M')} - {obj.end_time.strftime('%H:%M')}"
        return "All day"
    time_range.short_description = 'Time Range'
    
    def active_status(self, obj):
        """Display whether schedule is currently active."""
        if obj.is_active_now():
            return format_html(
                '<span style="color: green;">● Active Now</span>'
            )
        return format_html(
            '<span style="color: gray;">○ Inactive</span>'
        )
    active_status.short_description = 'Current Status'
    
    def get_queryset(self, request):
        """Optimize queryset with select_related."""
        queryset = super().get_queryset(request)
        return queryset.select_related('campaign', 'campaign__advertiser')


@admin.register(CampaignPerformance)
class CampaignPerformanceAdmin(admin.ModelAdmin):
    """
    Django admin configuration for CampaignPerformance model.
    
    Provides interface for viewing and analyzing campaign performance data.
    """
    
    list_display = [
        'campaign',
        'date',
        'impressions',
        'clicks',
        'conversions',
        'cost',
        'ctr_display',
        'cpc_display',
        'cpa_display',
        'roas_display'
    ]
    list_filter = [
        'date',
        'campaign__advertiser',
        'campaign__brand',
        'campaign__status'
    ]
    search_fields = [
        'campaign__name',
        'campaign__code'
    ]
    ordering = ['-date', 'campaign']
    readonly_fields = [
        'ctr',
        'cpc',
        'cpm',
        'cpa',
        'roas',
        'created_at',
        'updated_at'
    ]
    date_hierarchy = 'date'
    
    fieldsets = [
        ('Basic Information', {
            'fields': ('campaign', 'date')
        }),
        ('Traffic Metrics', {
            'fields': (
                'impressions',
                'clicks',
                'unique_clicks'
            )
        }),
        ('Conversion Metrics', {
            'fields': (
                'conversions',
                'conversion_value'
            )
        }),
        ('Cost Metrics', {
            'fields': ('cost',)
        }),
        ('Calculated Metrics', {
            'fields': (
                'ctr',
                'cpc',
                'cpm',
                'cpa',
                'roas'
            ),
            'classes': ('collapse',)
        }),
        ('Timestamps', {
            'fields': ('created_at', 'updated_at'),
            'classes': ('collapse',)
        })
    ]
    
    def ctr_display(self, obj):
        """Display CTR with formatting."""
        return f"{obj.ctr:.2f}%"
    ctr_display.short_description = 'CTR'
    ctr_display.admin_order_field = 'ctr'
    
    def cpc_display(self, obj):
        """Display CPC with formatting."""
        return f"${obj.cpc:.2f}"
    cpc_display.short_description = 'CPC'
    cpc_display.admin_order_field = 'cpc'
    
    def cpa_display(self, obj):
        """Display CPA with formatting."""
        return f"${obj.cpa:.2f}"
    cpa_display.short_description = 'CPA'
    cpa_display.admin_order_field = 'cpa'
    
    def roas_display(self, obj):
        """Display ROAS with formatting."""
        return f"{obj.roas:.2f}x"
    roas_display.short_description = 'ROAS'
    roas_display.admin_order_field = 'roas'
    
    def get_queryset(self, request):
        """Optimize queryset with select_related."""
        queryset = super().get_queryset(request)
        return queryset.select_related('campaign', 'campaign__advertiser')
    
    def has_add_permission(self, request):
        """Restrict manual addition of performance data."""
        return False
    
    def has_delete_permission(self, request, obj=None):
        """Restrict deletion of performance data."""
        return request.user.is_superuser