# Adtlas TV Advertising Platform - Channels Admin Interface
# Comprehensive Django admin configuration for TV channels management

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, Sum
from .models import (
    GeographicZone,
    BroadcastNetwork,
    TVChannel,
    ChannelCoverage,
    ContentSchedule,
    AudienceDemographics
)


@admin.register(GeographicZone)
class GeographicZoneAdmin(admin.ModelAdmin):
    """
    Admin interface for Geographic Zones.
    
    Provides comprehensive management of geographic zones with hierarchical
    display, population statistics, and coverage analytics.
    """
    
    list_display = [
        'name',
        'code',
        'zone_type',
        'parent_zone_link',
        'population_formatted',
        'tv_households_formatted',
        'child_zones_count',
        'is_active',
        'created_at'
    ]
    
    list_filter = [
        'zone_type',
        'is_active',
        'created_at',
        'parent_zone__zone_type'
    ]
    
    search_fields = [
        'name',
        'code',
        'parent_zone__name'
    ]
    
    ordering = ['zone_type', 'name']
    
    fieldsets = (
        (_('Basic Information'), {
            'fields': ('name', 'code', 'zone_type', 'parent_zone')
        }),
        (_('Demographics'), {
            'fields': ('population', 'tv_households'),
            'classes': ('collapse',)
        }),
        (_('Geographic Data'), {
            'fields': ('latitude', 'longitude', 'timezone'),
            'classes': ('collapse',)
        }),
        (_('Status'), {
            'fields': ('is_active',)
        })
    )
    
    readonly_fields = ['created_at', 'updated_at']
    
    def parent_zone_link(self, obj):
        """Display parent zone as a clickable link."""
        if obj.parent_zone:
            url = reverse('admin:channels_geographiczone_change', args=[obj.parent_zone.pk])
            return format_html('<a href="{}">{}</a>', url, obj.parent_zone.name)
        return '-'
    parent_zone_link.short_description = _('Parent Zone')
    
    def population_formatted(self, obj):
        """Format population with thousands separators."""
        if obj.population:
            return f"{obj.population:,}"
        return '-'
    population_formatted.short_description = _('Population')
    
    def tv_households_formatted(self, obj):
        """Format TV households with thousands separators."""
        if obj.tv_households:
            return f"{obj.tv_households:,}"
        return '-'
    tv_households_formatted.short_description = _('TV Households')
    
    def child_zones_count(self, obj):
        """Display count of child zones."""
        count = obj.get_child_zones_count()
        if count > 0:
            return format_html(
                '<span style="color: #0066cc;">{} zones</span>',
                count
            )
        return '0'
    child_zones_count.short_description = _('Child Zones')
    
    def get_queryset(self, request):
        """Optimize queryset with select_related."""
        return super().get_queryset(request).select_related('parent_zone')


@admin.register(BroadcastNetwork)
class BroadcastNetworkAdmin(admin.ModelAdmin):
    """
    Admin interface for Broadcast Networks.
    
    Manages TV networks with hierarchical relationships, channel counts,
    and network-specific metadata.
    """
    
    list_display = [
        'name',
        'short_name',
        'network_type',
        'parent_network_link',
        'channels_count',
        'subsidiaries_count',
        'founded_date',
        'is_active'
    ]
    
    list_filter = [
        'network_type',
        'is_active',
        'founded_date',
        'created_at'
    ]
    
    search_fields = [
        'name',
        'short_name',
        'headquarters_location'
    ]
    
    ordering = ['network_type', 'name']
    
    fieldsets = (
        (_('Basic Information'), {
            'fields': ('name', 'short_name', 'network_type', 'parent_network')
        }),
        (_('Company Details'), {
            'fields': ('founded_date', 'headquarters_location', 'description'),
            'classes': ('collapse',)
        }),
        (_('Online Presence'), {
            'fields': ('website_url', 'logo_url'),
            'classes': ('collapse',)
        }),
        (_('Audience Data'), {
            'fields': ('target_demographics',),
            'classes': ('collapse',)
        }),
        (_('Status'), {
            'fields': ('is_active',)
        })
    )
    
    readonly_fields = ['created_at', 'updated_at']
    
    def parent_network_link(self, obj):
        """Display parent network as a clickable link."""
        if obj.parent_network:
            url = reverse('admin:channels_broadcastnetwork_change', args=[obj.parent_network.pk])
            return format_html('<a href="{}">{}</a>', url, obj.parent_network.name)
        return '-'
    parent_network_link.short_description = _('Parent Network')
    
    def channels_count(self, obj):
        """Display count of channels for this network."""
        count = obj.channel_count
        if count > 0:
            return format_html(
                '<span style="color: #0066cc;">{} channels</span>',
                count
            )
        return '0'
    channels_count.short_description = _('Channels')
    
    def subsidiaries_count(self, obj):
        """Display count of subsidiary networks."""
        count = obj.subsidiary_networks.filter(is_active=True).count()
        if count > 0:
            return format_html(
                '<span style="color: #009900;">{} subsidiaries</span>',
                count
            )
        return '0'
    subsidiaries_count.short_description = _('Subsidiaries')
    
    def get_queryset(self, request):
        """Optimize queryset with select_related and annotations."""
        return super().get_queryset(request).select_related(
            'parent_network'
        ).annotate(
            channels_count=Count('channels', filter=models.Q(channels__is_active=True))
        )


class ChannelCoverageInline(admin.TabularInline):
    """
    Inline admin for Channel Coverage within TV Channel admin.
    
    Allows managing channel coverage zones directly from the channel edit page.
    """
    
    model = ChannelCoverage
    extra = 1
    fields = [
        'zone',
        'signal_strength',
        'coverage_percentage',
        'subscriber_count',
        'penetration_rate',
        'is_active'
    ]
    
    def get_queryset(self, request):
        """Optimize inline queryset."""
        return super().get_queryset(request).select_related('zone')


class ContentScheduleInline(admin.TabularInline):
    """
    Inline admin for Content Schedule within TV Channel admin.
    
    Shows recent and upcoming scheduled content for the channel.
    """
    
    model = ContentSchedule
    extra = 0
    fields = [
        'title',
        'content_type',
        'start_time',
        'duration_minutes',
        'is_live'
    ]
    
    def get_queryset(self, request):
        """Show only recent and upcoming schedule entries."""
        from django.utils import timezone
        from datetime import timedelta
        
        cutoff_date = timezone.now() - timedelta(days=7)
        return super().get_queryset(request).filter(
            start_time__gte=cutoff_date
        ).order_by('start_time')[:10]


@admin.register(TVChannel)
class TVChannelAdmin(admin.ModelAdmin):
    """
    Admin interface for TV Channels.
    
    Comprehensive channel management with coverage zones, scheduling,
    and audience analytics integration.
    """
    
    list_display = [
        'name',
        'call_sign',
        'channel_number',
        'channel_type',
        'network_link',
        'content_category',
        'coverage_zones_count',
        'total_population',
        'hd_uhd_status',
        'advertising_enabled',
        'is_active'
    ]
    
    list_filter = [
        'channel_type',
        'content_category',
        'network__network_type',
        'is_active',
        'is_premium',
        'advertising_enabled',
        'hd_available',
        'created_at'
    ]
    
    search_fields = [
        'name',
        'call_sign',
        'channel_number',
        'network__name',
        'network__short_name'
    ]
    
    ordering = ['channel_number', 'name']
    
    fieldsets = (
        (_('Basic Information'), {
            'fields': ('name', 'call_sign', 'channel_number', 'channel_type', 'network')
        }),
        (_('Content & Programming'), {
            'fields': (
                'content_category',
                'primary_language',
                'secondary_languages',
                'target_demographics',
                'description'
            ),
            'classes': ('collapse',)
        }),
        (_('Technical Specifications'), {
            'fields': ('hd_available',),
            'classes': ('collapse',)
        }),
        (_('Online Presence'), {
            'fields': ('website_url', 'logo_url'),
            'classes': ('collapse',)
        }),
        (_('Business Settings'), {
            'fields': (
                'is_premium',
                'advertising_enabled',
                'launch_date'
            ),
            'classes': ('collapse',)
        }),
        (_('Status'), {
            'fields': ('is_active',)
        })
    )
    
    readonly_fields = ['created_at', 'updated_at']
    
    inlines = [ChannelCoverageInline, ContentScheduleInline]
    
    def network_link(self, obj):
        """Display network as a clickable link."""
        url = reverse('admin:channels_broadcastnetwork_change', args=[obj.network.pk])
        return format_html(
            '<a href="{}">{}</a>',
            url,
            obj.network.short_name or obj.network.name
        )
    network_link.short_description = _('Network')
    
    def coverage_zones_count(self, obj):
        """Display count of coverage zones."""
        count = obj.coverage_zones.filter(is_active=True).count()
        if count > 0:
            return format_html(
                '<span style="color: #0066cc;">{} zones</span>',
                count
            )
        return '0'
    coverage_zones_count.short_description = _('Coverage Zones')
    
    def total_population(self, obj):
        """Display total population covered."""
        population = obj.total_coverage_population
        if population > 0:
            return f"{population:,}"
        return '-'
    total_population.short_description = _('Total Population')
    
    def hd_uhd_status(self, obj):
        """Display HD availability status."""
        if obj.hd_available:
            return format_html('<span style="color: #009900;">HD</span>')
        return format_html('<span style="color: #999;">SD</span>')
    hd_uhd_status.short_description = _('Quality')
    
    def get_queryset(self, request):
        """Optimize queryset with select_related."""
        return super().get_queryset(request).select_related('network')


@admin.register(ChannelCoverage)
class ChannelCoverageAdmin(admin.ModelAdmin):
    """
    Admin interface for Channel Coverage relationships.
    
    Manages the detailed coverage information between channels and zones.
    """
    
    list_display = [
        'channel_name',
        'zone_name',
        'signal_strength',
        'coverage_percentage',
        'subscriber_count_formatted',
        'penetration_rate',
        'estimated_viewers_formatted',
        'is_active'
    ]
    
    list_filter = [
        'signal_strength',
        'is_active',
        'channel__channel_type',
        'zone__zone_type',
        'launch_date_in_zone'
    ]
    
    search_fields = [
        'channel__name',
        'channel__call_sign',
        'zone__name',
        'zone__code'
    ]
    
    ordering = ['channel__name', 'zone__name']
    
    fieldsets = (
        (_('Relationship'), {
            'fields': ('channel', 'zone')
        }),
        (_('Coverage Details'), {
            'fields': (
                'signal_strength',
                'coverage_percentage',
                'subscriber_count',
                'penetration_rate'
            )
        }),
        (_('Timeline'), {
            'fields': ('launch_date_in_zone',),
            'classes': ('collapse',)
        }),
        (_('Additional Information'), {
            'fields': ('notes',),
            'classes': ('collapse',)
        }),
        (_('Status'), {
            'fields': ('is_active',)
        })
    )
    
    readonly_fields = ['created_at', 'updated_at']
    
    def channel_name(self, obj):
        """Display channel name with link."""
        url = reverse('admin:channels_tvchannel_change', args=[obj.channel.pk])
        return format_html('<a href="{}">{}</a>', url, obj.channel.name)
    channel_name.short_description = _('Channel')
    
    def zone_name(self, obj):
        """Display zone name with link."""
        url = reverse('admin:channels_geographiczone_change', args=[obj.zone.pk])
        return format_html('<a href="{}">{}</a>', url, obj.zone.name)
    zone_name.short_description = _('Zone')
    
    def subscriber_count_formatted(self, obj):
        """Format subscriber count with thousands separators."""
        if obj.subscriber_count:
            return f"{obj.subscriber_count:,}"
        return '-'
    subscriber_count_formatted.short_description = _('Subscribers')
    
    def estimated_viewers_formatted(self, obj):
        """Format estimated viewers with thousands separators."""
        viewers = obj.estimated_viewers
        if viewers:
            return f"{viewers:,}"
        return '-'
    estimated_viewers_formatted.short_description = _('Est. Viewers')
    
    def get_queryset(self, request):
        """Optimize queryset with select_related."""
        return super().get_queryset(request).select_related('channel', 'zone')


@admin.register(ContentSchedule)
class ContentScheduleAdmin(admin.ModelAdmin):
    """
    Admin interface for Content Schedule (EPG).
    
    Manages programming schedules with content metadata and advertising breaks.
    """
    
    list_display = [
        'title',
        'channel_link',
        'content_type',
        'start_time',
        'duration_formatted',
        'advertising_info',
        'is_live',
        'is_premiere',
        'currently_airing'
    ]
    
    list_filter = [
        'content_type',
        'is_live',
        'is_premiere',
        'channel__network',
        'start_time',
        'genre',
        'rating'
    ]
    
    search_fields = [
        'title',
        'description',
        'channel__name',
        'channel__call_sign',
        'genre'
    ]
    
    ordering = ['-start_time']
    
    date_hierarchy = 'start_time'
    
    fieldsets = (
        (_('Program Information'), {
            'fields': ('channel', 'title', 'description', 'content_type')
        }),
        (_('Schedule'), {
            'fields': ('start_time', 'end_time', 'duration_minutes')
        }),
        (_('Content Details'), {
            'fields': ('genre', 'rating', 'target_demographics'),
            'classes': ('collapse',)
        }),
        (_('Advertising'), {
            'fields': ('advertising_breaks', 'ad_break_duration'),
            'classes': ('collapse',)
        }),
        (_('Flags'), {
            'fields': ('is_live', 'is_premiere')
        }),
        (_('External Integration'), {
            'fields': ('external_id',),
            'classes': ('collapse',)
        })
    )
    
    readonly_fields = ['created_at', 'updated_at']
    
    def channel_link(self, obj):
        """Display channel as a clickable link."""
        url = reverse('admin:channels_tvchannel_change', args=[obj.channel.pk])
        return format_html('<a href="{}">{}</a>', url, obj.channel.name)
    channel_link.short_description = _('Channel')
    
    def duration_formatted(self, obj):
        """Format duration in hours and minutes."""
        hours, minutes = divmod(obj.duration_minutes, 60)
        if hours > 0:
            return f"{hours}h {minutes}m"
        return f"{minutes}m"
    duration_formatted.short_description = _('Duration')
    
    def advertising_info(self, obj):
        """Display advertising break information."""
        if obj.advertising_breaks > 0:
            total_minutes = obj.ad_break_duration // 60
            return format_html(
                '<span style="color: #009900;">{} breaks ({}m)</span>',
                obj.advertising_breaks,
                total_minutes
            )
        return format_html('<span style="color: #999;">No ads</span>')
    advertising_info.short_description = _('Advertising')
    
    def currently_airing(self, obj):
        """Show if the program is currently airing."""
        if obj.is_currently_airing:
            return format_html('<span style="color: #ff0000;">● LIVE</span>')
        return '-'
    currently_airing.short_description = _('Status')
    
    def get_queryset(self, request):
        """Optimize queryset with select_related."""
        return super().get_queryset(request).select_related('channel')


@admin.register(AudienceDemographics)
class AudienceDemographicsAdmin(admin.ModelAdmin):
    """
    Admin interface for Audience Demographics.
    
    Manages viewership analytics and demographic data for channels and zones.
    """
    
    list_display = [
        'channel_link',
        'zone_link',
        'measurement_date',
        'total_viewers_formatted',
        'primary_age_group_display',
        'engagement_score',
        'viewing_hours_formatted'
    ]
    
    list_filter = [
        'measurement_date',
        'channel__network',
        'zone__zone_type',
        'channel__content_category'
    ]
    
    search_fields = [
        'channel__name',
        'zone__name',
        'channel__call_sign'
    ]
    
    ordering = ['-measurement_date', 'channel__name']
    
    date_hierarchy = 'measurement_date'
    
    fieldsets = (
        (_('Measurement Details'), {
            'fields': ('channel', 'zone', 'measurement_date', 'total_viewers')
        }),
        (_('Demographics Distribution'), {
            'fields': (
                'age_distribution',
                'gender_distribution',
                'income_distribution',
                'education_distribution'
            ),
            'classes': ('collapse',)
        }),
        (_('Viewing Behavior'), {
            'fields': ('viewing_hours_per_week', 'peak_viewing_times'),
            'classes': ('collapse',)
        })
    )
    
    readonly_fields = ['created_at', 'updated_at']
    
    def channel_link(self, obj):
        """Display channel as a clickable link."""
        url = reverse('admin:channels_tvchannel_change', args=[obj.channel.pk])
        return format_html('<a href="{}">{}</a>', url, obj.channel.name)
    channel_link.short_description = _('Channel')
    
    def zone_link(self, obj):
        """Display zone as a clickable link."""
        url = reverse('admin:channels_geographiczone_change', args=[obj.zone.pk])
        return format_html('<a href="{}">{}</a>', url, obj.zone.name)
    zone_link.short_description = _('Zone')
    
    def total_viewers_formatted(self, obj):
        """Format total viewers with thousands separators."""
        return f"{obj.total_viewers:,}"
    total_viewers_formatted.short_description = _('Total Viewers')
    
    def primary_age_group_display(self, obj):
        """Display the primary age group."""
        age_group = obj.primary_age_group
        if age_group:
            return format_html(
                '<span style="color: #0066cc;">{}</span>',
                age_group
            )
        return '-'
    primary_age_group_display.short_description = _('Primary Age Group')
    
    def engagement_score(self, obj):
        """Display viewer engagement score."""
        score = obj.viewer_engagement_score
        if score > 75:
            color = '#009900'  # Green for high engagement
        elif score > 50:
            color = '#ff9900'  # Orange for medium engagement
        else:
            color = '#cc0000'  # Red for low engagement
        
        return format_html(
            '<span style="color: {};">{:.1f}%</span>',
            color,
            score
        )
    engagement_score.short_description = _('Engagement')
    
    def viewing_hours_formatted(self, obj):
        """Format viewing hours per week."""
        if obj.viewing_hours_per_week:
            return f"{obj.viewing_hours_per_week:.1f}h/week"
        return '-'
    viewing_hours_formatted.short_description = _('Viewing Hours')
    
    def get_queryset(self, request):
        """Optimize queryset with select_related."""
        return super().get_queryset(request).select_related('channel', 'zone')


# Admin site customization
admin.site.site_header = _('Adtlas TV Advertising Platform')
admin.site.site_title = _('Adtlas Admin')
admin.site.index_title = _('TV Channels & Networks Management')