"""Admin configuration for Reporting and Analytics app."""

from django.contrib import admin
from django.utils.html import format_html
from django.urls import reverse
from django.utils.safestring import mark_safe
from django.db.models import Count, Avg, Sum
from django.utils import timezone
from datetime import timedelta

from .models import (
    AnalyticsRegion,
    AnalyticsTarget,
    SfrAnalytics,
    MarketShare,
    VerificationRecord,
    PredictionModel,
    SfrPrediction,
    AdbreakPrediction,
    ActivityLog,
    RealTimeAdbreak,
)


@admin.register(AnalyticsRegion)
class AnalyticsRegionAdmin(admin.ModelAdmin):
    list_display = ['name', 'code', 'country', 'population', 'timezone_name', 'created_at']
    list_filter = ['country', 'created_at']
    search_fields = ['name', 'code', 'country']
    ordering = ['name']
    readonly_fields = ['created_at', 'updated_at']
    
    fieldsets = (
        ('Basic Information', {
            'fields': ('name', 'code', 'country')
        }),
        ('Demographics', {
            'fields': ('population', 'timezone_name')
        }),
        ('Timestamps', {
            'fields': ('created_at', 'updated_at'),
            'classes': ('collapse',)
        }),
    )


@admin.register(AnalyticsTarget)
class AnalyticsTargetAdmin(admin.ModelAdmin):
    list_display = ['name', 'code', 'age_range', 'gender', 'created_at']
    list_filter = ['gender', 'created_at']
    search_fields = ['name', 'code', 'description']
    ordering = ['name']
    readonly_fields = ['created_at', 'updated_at']
    
    def age_range(self, obj):
        if obj.age_min and obj.age_max:
            return f"{obj.age_min}-{obj.age_max}"
        elif obj.age_min:
            return f"{obj.age_min}+"
        elif obj.age_max:
            return f"<{obj.age_max}"
        return "All ages"
    age_range.short_description = 'Age Range'
    
    fieldsets = (
        ('Basic Information', {
            'fields': ('name', 'code', 'description')
        }),
        ('Demographics', {
            'fields': ('age_min', 'age_max', 'gender')
        }),
        ('Timestamps', {
            'fields': ('created_at', 'updated_at'),
            'classes': ('collapse',)
        }),
    )


@admin.register(SfrAnalytics)
class SfrAnalyticsAdmin(admin.ModelAdmin):
    list_display = [
        'channel', 'sfr_channel_name', 'measurement_date', 'measurement_time',
        'region', 'target', 'indicator', 'value', 'percentage', 'quality_score'
    ]
    list_filter = [
        'measurement_date', 'indicator', 'region', 'target',
        'channel', 'data_source', 'created_at'
    ]
    search_fields = [
        'channel__name', 'sfr_channel_name', 'region__name',
        'target__name', 'indicator'
    ]
    ordering = ['-measurement_date', '-measurement_time']
    readonly_fields = ['created_at', 'updated_at']
    date_hierarchy = 'measurement_date'
    
    fieldsets = (
        ('Measurement Details', {
            'fields': (
                'channel', 'sfr_channel_name', 'measurement_date',
                'measurement_time', 'region', 'target'
            )
        }),
        ('Analytics Data', {
            'fields': ('indicator', 'value', 'percentage', 'quality_score')
        }),
        ('Metadata', {
            'fields': ('data_source', 'raw_data'),
            'classes': ('collapse',)
        }),
        ('Timestamps', {
            'fields': ('created_at', 'updated_at'),
            'classes': ('collapse',)
        }),
    )
    
    def get_queryset(self, request):
        return super().get_queryset(request).select_related(
            'channel', 'region', 'target'
        )


@admin.register(MarketShare)
class MarketShareAdmin(admin.ModelAdmin):
    list_display = [
        'channel', 'measurement_date', 'region', 'target',
        'market_share_percentage', 'ranking', 'total_users', 'channel_users'
    ]
    list_filter = [
        'measurement_date', 'region', 'target', 'channel', 'tool_name'
    ]
    search_fields = ['channel__name', 'region__name', 'target__name']
    ordering = ['-measurement_date', '-market_share_percentage']
    readonly_fields = ['created_at', 'updated_at']
    date_hierarchy = 'measurement_date'
    
    fieldsets = (
        ('Measurement Details', {
            'fields': ('channel', 'measurement_date', 'region', 'target')
        }),
        ('Market Data', {
            'fields': (
                'total_users', 'channel_users', 'market_share_percentage', 'ranking'
            )
        }),
        ('Metadata', {
            'fields': ('tool_name',)
        }),
        ('Timestamps', {
            'fields': ('created_at', 'updated_at'),
            'classes': ('collapse',)
        }),
    )
    
    def get_queryset(self, request):
        return super().get_queryset(request).select_related(
            'channel', 'region', 'target'
        )


@admin.register(VerificationRecord)
class VerificationRecordAdmin(admin.ModelAdmin):
    list_display = [
        'spot_id', 'network_name', 'broadcast_date', 'broadcast_time',
        'status', 'verification_status', 'verified_by', 'created_at'
    ]
    list_filter = [
        'status', 'broadcast_date', 'network_name', 'zone_name',
        'verified_by', 'created_at'
    ]
    search_fields = [
        'spot_id', 'network_name', 'zone_name', 'traffic_id',
        'campaign__name', 'advertiser__name'
    ]
    ordering = ['-broadcast_date', '-created_at']
    readonly_fields = ['id', 'created_at', 'updated_at']
    date_hierarchy = 'broadcast_date'
    
    def verification_status(self, obj):
        if obj.status == 'verified':
            color = 'green'
        elif obj.status == 'failed':
            color = 'red'
        elif obj.status == 'pending':
            color = 'orange'
        else:
            color = 'gray'
        
        return format_html(
            '<span style="color: {}; font-weight: bold;">{}</span>',
            color,
            obj.get_status_display()
        )
    verification_status.short_description = 'Status'
    
    fieldsets = (
        ('Broadcast Information', {
            'fields': (
                'network_name', 'zone_name', 'broadcast_date', 'broadcast_time',
                'traffic_id', 'spot_id'
            )
        }),
        ('Air Details', {
            'fields': (
                'air_time', 'air_length', 'air_status_code', 'revision'
            )
        }),
        ('Verification', {
            'fields': (
                'status', 'verification_complete', 'verified_by', 'verified_at',
                'error_message'
            )
        }),
        ('Associations', {
            'fields': ('campaign', 'advertiser'),
            'classes': ('collapse',)
        }),
        ('Additional Data', {
            'fields': ('verification_data',),
            'classes': ('collapse',)
        }),
        ('Timestamps', {
            'fields': ('id', 'created_at', 'updated_at'),
            'classes': ('collapse',)
        }),
    )
    
    actions = ['mark_as_verified', 'mark_as_failed', 'reprocess_verification']
    
    def mark_as_verified(self, request, queryset):
        updated = queryset.update(
            status='verified',
            verified_by=request.user,
            verified_at=timezone.now()
        )
        self.message_user(
            request,
            f'{updated} verification records marked as verified.'
        )
    mark_as_verified.short_description = 'Mark selected records as verified'
    
    def mark_as_failed(self, request, queryset):
        updated = queryset.update(status='failed')
        self.message_user(
            request,
            f'{updated} verification records marked as failed.'
        )
    mark_as_failed.short_description = 'Mark selected records as failed'
    
    def reprocess_verification(self, request, queryset):
        updated = queryset.update(status='pending')
        self.message_user(
            request,
            f'{updated} verification records queued for reprocessing.'
        )
    reprocess_verification.short_description = 'Reprocess selected records'


@admin.register(PredictionModel)
class PredictionModelAdmin(admin.ModelAdmin):
    list_display = [
        'name', 'model_type', 'version', 'accuracy_score',
        'is_active', 'created_at'
    ]
    list_filter = ['model_type', 'is_active', 'algorithm', 'created_at']
    search_fields = ['name', 'description', 'algorithm']
    ordering = ['-created_at']
    readonly_fields = ['id', 'created_at', 'updated_at']
    
    fieldsets = (
        ('Model Information', {
            'fields': ('name', 'model_type', 'description', 'version')
        }),
        ('Configuration', {
            'fields': ('algorithm', 'is_active', 'parameters')
        }),
        ('Performance', {
            'fields': ('accuracy_score', 'training_data_start', 'training_data_end')
        }),
        ('Timestamps', {
            'fields': ('id', 'created_at', 'updated_at'),
            'classes': ('collapse',)
        }),
    )
    
    actions = ['activate_models', 'deactivate_models']
    
    def activate_models(self, request, queryset):
        updated = queryset.update(is_active=True)
        self.message_user(request, f'{updated} models activated.')
    activate_models.short_description = 'Activate selected models'
    
    def deactivate_models(self, request, queryset):
        updated = queryset.update(is_active=False)
        self.message_user(request, f'{updated} models deactivated.')
    deactivate_models.short_description = 'Deactivate selected models'


@admin.register(SfrPrediction)
class SfrPredictionAdmin(admin.ModelAdmin):
    list_display = [
        'channel', 'prediction_date', 'prediction_time', 'indicator',
        'predicted_value', 'actual_value', 'accuracy_display', 'confidence_score'
    ]
    list_filter = [
        'prediction_date', 'indicator', 'channel', 'region', 'target', 'model'
    ]
    search_fields = [
        'channel__name', 'sfr_channel_name', 'region__name', 'target__name'
    ]
    ordering = ['-prediction_date', '-prediction_time']
    readonly_fields = ['created_at', 'updated_at', 'accuracy_display']
    date_hierarchy = 'prediction_date'
    
    def accuracy_display(self, obj):
        accuracy = obj.accuracy
        if accuracy is not None:
            percentage = accuracy * 100
            if percentage >= 90:
                color = 'green'
            elif percentage >= 70:
                color = 'orange'
            else:
                color = 'red'
            return format_html(
                '<span style="color: {}; font-weight: bold;">{:.1f}%</span>',
                color, percentage
            )
        return '-'
    accuracy_display.short_description = 'Accuracy'
    
    fieldsets = (
        ('Prediction Details', {
            'fields': (
                'model', 'channel', 'sfr_channel_name', 'prediction_date',
                'prediction_time', 'region', 'target'
            )
        }),
        ('Prediction Data', {
            'fields': (
                'indicator', 'predicted_value', 'predicted_percentage',
                'confidence_score'
            )
        }),
        ('Actual Results', {
            'fields': ('actual_value', 'accuracy_display')
        }),
        ('Timestamps', {
            'fields': ('created_at', 'updated_at'),
            'classes': ('collapse',)
        }),
    )


@admin.register(AdbreakPrediction)
class AdbreakPredictionAdmin(admin.ModelAdmin):
    list_display = [
        'channel', 'prediction_datetime', 'predicted_duration',
        'actual_datetime', 'timing_accuracy_display', 'confidence_score'
    ]
    list_filter = ['prediction_date', 'channel', 'model']
    search_fields = ['channel__name']
    ordering = ['-prediction_datetime']
    readonly_fields = ['created_at', 'updated_at', 'timing_accuracy_display']
    date_hierarchy = 'prediction_date'
    
    def timing_accuracy_display(self, obj):
        accuracy = obj.timing_accuracy_minutes
        if accuracy is not None:
            if accuracy <= 1:
                color = 'green'
                status = 'Excellent'
            elif accuracy <= 5:
                color = 'orange'
                status = 'Good'
            else:
                color = 'red'
                status = 'Poor'
            return format_html(
                '<span style="color: {}; font-weight: bold;">{:.1f} min ({})</span>',
                color, accuracy, status
            )
        return '-'
    timing_accuracy_display.short_description = 'Timing Accuracy'
    
    fieldsets = (
        ('Prediction Details', {
            'fields': (
                'model', 'channel', 'prediction_datetime', 'prediction_date',
                'prediction_time'
            )
        }),
        ('Duration Prediction', {
            'fields': ('predicted_duration', 'predicted_duration_seconds', 'confidence_score')
        }),
        ('Actual Results', {
            'fields': (
                'actual_datetime', 'actual_duration_seconds', 'timing_accuracy_display'
            )
        }),
        ('Timestamps', {
            'fields': ('created_at', 'updated_at'),
            'classes': ('collapse',)
        }),
    )


@admin.register(ActivityLog)
class ActivityLogAdmin(admin.ModelAdmin):
    list_display = [
        'activity_type', 'description', 'user', 'activity_date',
        'ip_address', 'created_at'
    ]
    list_filter = ['activity_type', 'activity_date', 'user', 'created_at']
    search_fields = ['description', 'user__username', 'ip_address']
    ordering = ['-created_at']
    readonly_fields = ['created_at', 'updated_at']
    date_hierarchy = 'activity_date'
    
    fieldsets = (
        ('Activity Information', {
            'fields': ('activity_type', 'activity_date', 'description')
        }),
        ('User Information', {
            'fields': ('user', 'ip_address', 'user_agent')
        }),
        ('Additional Data', {
            'fields': ('additional_data',),
            'classes': ('collapse',)
        }),
        ('Timestamps', {
            'fields': ('created_at', 'updated_at'),
            'classes': ('collapse',)
        }),
    )
    
    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 request.user.is_superuser


@admin.register(RealTimeAdbreak)
class RealTimeAdbreakAdmin(admin.ModelAdmin):
    list_display = [
        'channel', 'start_time', 'end_time', 'duration_display',
        'status', 'ad_count', 'viewer_count', 'total_revenue'
    ]
    list_filter = ['status', 'channel', 'start_time']
    search_fields = ['channel__name']
    ordering = ['-start_time']
    readonly_fields = ['created_at', 'updated_at', 'duration_display']
    date_hierarchy = 'start_time'
    
    def duration_display(self, obj):
        duration = obj.actual_duration_seconds
        if duration:
            minutes = duration // 60
            seconds = duration % 60
            return f"{minutes}:{seconds:02d}"
        return '-'
    duration_display.short_description = 'Duration'
    
    fieldsets = (
        ('Ad Break Information', {
            'fields': ('channel', 'start_time', 'end_time', 'duration_seconds', 'status')
        }),
        ('Performance Metrics', {
            'fields': ('ad_count', 'viewer_count', 'total_revenue')
        }),
        ('Tracking Data', {
            'fields': ('tracking_data',),
            'classes': ('collapse',)
        }),
        ('Timestamps', {
            'fields': ('created_at', 'updated_at'),
            'classes': ('collapse',)
        }),
    )
    
    actions = ['mark_as_completed', 'mark_as_cancelled']
    
    def mark_as_completed(self, request, queryset):
        updated = queryset.filter(status__in=['scheduled', 'started', 'in_progress']).update(
            status='completed',
            end_time=timezone.now()
        )
        self.message_user(request, f'{updated} ad breaks marked as completed.')
    mark_as_completed.short_description = 'Mark selected ad breaks as completed'
    
    def mark_as_cancelled(self, request, queryset):
        updated = queryset.filter(status__in=['scheduled', 'started']).update(
            status='cancelled'
        )
        self.message_user(request, f'{updated} ad breaks marked as cancelled.')
    mark_as_cancelled.short_description = 'Mark selected ad breaks as cancelled'