"""Django Admin Configuration for Channels App

This module configures the Django admin interface for all channel-related models.
Provides comprehensive admin interfaces with advanced filtering, search capabilities,
inline editing, and custom actions for efficient channel management.

Author: Senior Django Developer
Version: 1.0.0
"""

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.utils import timezone
from django.db.models import Count, Q

from apps.channels.models import (
    Channel, ChannelZone, ChannelCodec, ChannelZoneRelation,
    Jingle, JingleDetection, Adbreak, EPGProgram, ChannelSchedule,
    StandaloneVPNConfiguration, StandaloneFTPConfiguration,
    ZoneVPNConfiguration, ZoneFTPConfiguration
)


class ChannelZoneRelationInline(admin.TabularInline):
    """Inline admin for Channel-Zone relationships."""
    model = ChannelZoneRelation
    extra = 1
    fields = (
        'zone', 'codec', 'stream_url', 'backup_stream_url',
        'standalone_vpn_config', 'standalone_ftp_config', 
        'is_active', 'priority'
    )
    readonly_fields = ('created_at', 'updated_at')
    
    def get_queryset(self, request):
        return super().get_queryset(request).select_related(
            'zone', 'codec', 'standalone_vpn_config', 'standalone_ftp_config'
        )


class JingleInline(admin.TabularInline):
    """Inline admin for Channel Jingles."""
    model = Jingle
    extra = 0
    fields = ('name', 'jingle_type', 'placement_type', 'duration', 'is_active', 'priority')
    readonly_fields = ('duration', 'play_count', 'last_played')
    show_change_link = True


class EPGProgramInline(admin.TabularInline):
    """Inline admin for EPG Programs."""
    model = EPGProgram
    extra = 0
    fields = ('title', 'program_type', 'start_time', 'end_time', 'duration')
    readonly_fields = ('duration',)
    show_change_link = True
    
    def get_queryset(self, request):
        return super().get_queryset(request).filter(
            start_time__gte=timezone.now() - timezone.timedelta(days=7)
        ).order_by('start_time')


class ChannelScheduleInline(admin.TabularInline):
    """Inline admin for Channel Schedules."""
    model = ChannelSchedule
    extra = 0
    fields = ('title', 'schedule_type', 'start_time', 'end_time', 'is_active')
    show_change_link = True
    
    def get_queryset(self, request):
        return super().get_queryset(request).filter(
            start_time__gte=timezone.now() - timezone.timedelta(days=1)
        ).order_by('start_time')


@admin.register(ChannelZone)
class ChannelZoneAdmin(admin.ModelAdmin):
    """Admin interface for Channel Zones."""
    list_display = ('name', 'code', 'timezone', 'channel_count', 'is_active', 'created_at')
    list_filter = ('is_active', 'timezone', 'created_at')
    search_fields = ('name', 'code', 'description')
    ordering = ('name',)
    readonly_fields = ('id', 'created_at', 'updated_at')
    
    fieldsets = (
        (_('Basic Information'), {
            'fields': ('name', 'code', 'description')
        }),
        (_('Configuration'), {
            'fields': ('timezone', 'is_active')
        }),
        (_('Metadata'), {
            'fields': ('id', 'created_at', 'updated_at'),
            'classes': ('collapse',)
        })
    )
    
    def channel_count(self, obj):
        """Display number of channels in this zone."""
        count = obj.channels.count()
        if count > 0:
            url = reverse('admin:channels_channel_changelist') + f'?zones__id__exact={obj.id}'
            return format_html('<a href="{}">{} channels</a>', url, count)
        return '0 channels'
    channel_count.short_description = _('Channels')
    channel_count.admin_order_field = 'channels__count'
    
    def get_queryset(self, request):
        return super().get_queryset(request).annotate(
            channels_count=Count('channels')
        )


@admin.register(ChannelCodec)
class ChannelCodecAdmin(admin.ModelAdmin):
    """Admin interface for Channel Codecs."""
    list_display = ('name', 'video_codec', 'audio_codec', 'resolution', 'bitrate', 'frame_rate', 'usage_count')
    list_filter = ('video_codec', 'audio_codec', 'resolution')
    search_fields = ('name', 'video_codec', 'audio_codec')
    ordering = ('name',)
    readonly_fields = ('id', 'created_at', 'updated_at')
    
    fieldsets = (
        (_('Basic Information'), {
            'fields': ('name',)
        }),
        (_('Video Settings'), {
            'fields': ('video_codec', 'resolution', 'frame_rate')
        }),
        (_('Audio Settings'), {
            'fields': ('audio_codec', 'bitrate')
        }),
        (_('Advanced Options'), {
            'fields': ('ffmpeg_options',),
            'classes': ('collapse',)
        }),
        (_('Metadata'), {
            'fields': ('id', 'created_at', 'updated_at'),
            'classes': ('collapse',)
        })
    )
    
    def usage_count(self, obj):
        """Display how many channels use this codec."""
        count = obj.channels.count() + obj.zone_relations.count()
        return f'{count} usage(s)'
    usage_count.short_description = _('Usage')


@admin.register(Channel)
class ChannelAdmin(admin.ModelAdmin):
    """Admin interface for Channels with comprehensive management features."""
    list_display = (
        'display_name', 'name', 'channel_number', 'channel_type', 
        'status_badge', 'online_status', 'zone_count', 'last_health_check'
    )
    list_filter = (
        'channel_type', 'status', 'is_online', 'supports_dai',
        'language', 'category', 'created_at'
    )
    search_fields = ('name', 'display_name', 'channel_number', 'description')
    ordering = ('channel_number', 'name')
    readonly_fields = ('id', 'created_at', 'updated_at', 'last_health_check')
    filter_horizontal = ()
    
    fieldsets = (
        (_('Channel Identity'), {
            'fields': ('name', 'display_name', 'channel_number', 'logo')
        }),
        (_('Classification'), {
            'fields': ('channel_type', 'status', 'category', 'language', 'target_audience')
        }),
        (_('Content & Branding'), {
            'fields': ('description', 'website')
        }),
        (_('Advertising Configuration'), {
            'fields': ('supports_dai',),
            'classes': ('collapse',)
        }),
        (_('Health Monitoring'), {
            'fields': ('is_online', 'last_health_check'),
            'classes': ('collapse',)
        }),
        (_('Metadata'), {
            'fields': ('id', 'created_at', 'updated_at'),
            'classes': ('collapse',)
        })
    )
    
    inlines = [ChannelZoneRelationInline, JingleInline, EPGProgramInline, ChannelScheduleInline]
    
    actions = ['activate_channels', 'deactivate_channels', 'mark_online', 'mark_offline']
    
    def status_badge(self, obj):
        """Display status with color-coded badge."""
        colors = {
            'active': 'green',
            'inactive': 'red',
            'maintenance': 'orange',
            'testing': 'blue'
        }
        color = colors.get(obj.status, 'gray')
        return format_html(
            '<span style="color: {}; font-weight: bold;">{}</span>',
            color, obj.get_status_display()
        )
    status_badge.short_description = _('Status')
    status_badge.admin_order_field = 'status'
    
    def online_status(self, obj):
        """Display online status with icon."""
        if obj.is_online:
            return format_html('<span style="color: green;">● Online</span>')
        return format_html('<span style="color: red;">● Offline</span>')
    online_status.short_description = _('Online')
    online_status.admin_order_field = 'is_online'
    
    def zone_count(self, obj):
        """Display number of zones this channel broadcasts to."""
        count = obj.zones.count()
        if count > 0:
            return f'{count} zone(s)'
        return 'No zones'
    zone_count.short_description = _('Zones')
    
    def activate_channels(self, request, queryset):
        """Bulk action to activate selected channels."""
        updated = queryset.update(status='active')
        self.message_user(request, f'{updated} channels activated successfully.')
    activate_channels.short_description = _('Activate selected channels')
    
    def deactivate_channels(self, request, queryset):
        """Bulk action to deactivate selected channels."""
        updated = queryset.update(status='inactive')
        self.message_user(request, f'{updated} channels deactivated successfully.')
    deactivate_channels.short_description = _('Deactivate selected channels')
    
    def mark_online(self, request, queryset):
        """Bulk action to mark channels as online."""
        updated = queryset.update(is_online=True)
        self.message_user(request, f'{updated} channels marked as online.')
    mark_online.short_description = _('Mark selected channels as online')
    
    def mark_offline(self, request, queryset):
        """Bulk action to mark channels as offline."""
        updated = queryset.update(is_online=False)
        self.message_user(request, f'{updated} channels marked as offline.')
    mark_offline.short_description = _('Mark selected channels as offline')
    
    def get_queryset(self, request):
        return super().get_queryset(request).select_related().prefetch_related('zones')


@admin.register(ChannelZoneRelation)
class ChannelZoneRelationAdmin(admin.ModelAdmin):
    """Admin interface for Channel-Zone relationships."""
    list_display = ('channel', 'zone', 'codec', 'is_active', 'priority', 'stream_url_short')
    list_filter = ('is_active', 'zone', 'codec', 'vpn_type')
    search_fields = ('channel__name', 'zone__name', 'stream_url')
    ordering = ('channel', 'zone', '-priority')
    readonly_fields = ('id', 'created_at', 'updated_at')
    
    fieldsets = (
        (_('Relationship'), {
            'fields': ('channel', 'zone', 'codec')
        }),
        (_('Configuration'), {
            'fields': ('stream_url', 'is_active', 'priority')
        }),
        (_('VPN Configuration'), {
            'fields': ('vpn_type', 'vpn_server_address', 'vpn_username', 'vpn_password'),
            'classes': ('collapse',)
        }),
        (_('FTP Configuration'), {
            'fields': ('ftp_platform_name', 'ftp_server_address', 'ftp_username', 'ftp_password'),
            'classes': ('collapse',)
        }),
        (_('Metadata'), {
            'fields': ('id', 'created_at', 'updated_at'),
            'classes': ('collapse',)
        })
    )
    
    def stream_url_short(self, obj):
        """Display shortened stream URL."""
        if obj.stream_url:
            return obj.stream_url[:50] + '...' if len(obj.stream_url) > 50 else obj.stream_url
        return '-'
    stream_url_short.short_description = _('Stream URL')
    
    def get_queryset(self, request):
        return super().get_queryset(request).select_related('channel', 'zone', 'codec')


@admin.register(Jingle)
class JingleAdmin(admin.ModelAdmin):
    """Admin interface for Channel Jingles."""
    list_display = (
        'name', 'channel', 'jingle_type', 'placement_type', 
        'duration_display', 'is_active', 'priority', 'play_count', 'last_played'
    )
    list_filter = ('jingle_type', 'placement_type', 'is_active', 'channel', 'created_at')
    search_fields = ('name', 'channel__name', 'description')
    ordering = ('channel', 'jingle_type', '-priority')
    readonly_fields = ('id', 'duration', 'play_count', 'last_played', 'created_at', 'updated_at')
    
    fieldsets = (
        (_('Basic Information'), {
            'fields': ('channel', 'name')
        }),
        (_('Classification'), {
            'fields': ('jingle_type', 'placement_type', 'priority')
        }),
        (_('Media'), {
            'fields': ('file', 'duration')
        }),
        (_('Scheduling'), {
            'fields': ('is_active', 'start_date', 'end_date', 'time_slots'),
            'classes': ('collapse',)
        }),
        (_('Fingerprinting'), {
            'fields': ('audio_fingerprint', 'frames_fingerprint'),
            'classes': ('collapse',)
        }),
        (_('Statistics'), {
            'fields': ('play_count', 'last_played'),
            'classes': ('collapse',)
        }),
        (_('Metadata'), {
            'fields': ('id', 'created_at', 'updated_at'),
            'classes': ('collapse',)
        })
    )
    
    def duration_display(self, obj):
        """Display duration in human-readable format."""
        if obj.duration:
            minutes, seconds = divmod(obj.duration, 60)
            return f'{minutes:02d}:{seconds:02d}'
        return '-'
    duration_display.short_description = _('Duration')
    duration_display.admin_order_field = 'duration'
    
    def get_queryset(self, request):
        return super().get_queryset(request).select_related('channel')


@admin.register(Adbreak)
class AdbreakAdmin(admin.ModelAdmin):
    """Admin interface for Ad Breaks."""
    list_display = (
        'channel', 'date', 'start_at', 'end_at', 'duration_display',
        'adbreak_type', 'adbreak_category', 'show_before', 'show_after'
    )
    list_filter = ('adbreak_type', 'adbreak_category', 'date', 'channel')
    search_fields = ('channel__name', 'show_before', 'show_after')
    ordering = ('-date', '-start_at')
    readonly_fields = ('id', 'created_at', 'updated_at')
    date_hierarchy = 'date'
    
    fieldsets = (
        (_('Basic Information'), {
            'fields': ('channel', 'date')
        }),
        (_('Timing'), {
            'fields': ('start_at', 'end_at', 'duration')
        }),
        (_('Classification'), {
            'fields': ('adbreak_type', 'adbreak_category')
        }),
        (_('Context'), {
            'fields': ('show_before', 'show_after')
        }),
        (_('Metadata'), {
            'fields': ('id', 'created_at', 'updated_at'),
            'classes': ('collapse',)
        })
    )
    
    def duration_display(self, obj):
        """Display duration in human-readable format."""
        if obj.duration:
            total_seconds = int(obj.duration.total_seconds())
            minutes, seconds = divmod(total_seconds, 60)
            return f'{minutes:02d}:{seconds:02d}'
        return '-'
    duration_display.short_description = _('Duration')
    duration_display.admin_order_field = 'duration'
    
    def get_queryset(self, request):
        return super().get_queryset(request).select_related('channel')


@admin.register(EPGProgram)
class EPGProgramAdmin(admin.ModelAdmin):
    """Admin interface for EPG Programs."""
    list_display = (
        'title', 'channel', 'program_type', 'start_time', 'end_time',
        'duration_display', 'season_episode', 'content_rating'
    )
    list_filter = ('program_type', 'content_rating', 'language', 'channel', 'start_time')
    search_fields = ('title', 'description', 'channel__name')
    ordering = ('-start_time',)
    readonly_fields = ('id', 'duration', 'created_at', 'updated_at')
    date_hierarchy = 'start_time'
    
    fieldsets = (
        (_('Basic Information'), {
            'fields': ('channel', 'title', 'description')
        }),
        (_('Classification'), {
            'fields': ('program_type', 'content_rating', 'language')
        }),
        (_('Scheduling'), {
            'fields': ('start_time', 'end_time', 'duration')
        }),
        (_('Series Information'), {
            'fields': ('season_number', 'episode_number', 'original_air_date'),
            'classes': ('collapse',)
        }),
        (_('Accessibility'), {
            'fields': ('subtitles_available',),
            'classes': ('collapse',)
        }),
        (_('Advertising'), {
            'fields': ('has_ad_breaks', 'ad_break_positions'),
            'classes': ('collapse',)
        }),
        (_('Metadata'), {
            'fields': ('id', 'created_at', 'updated_at'),
            'classes': ('collapse',)
        })
    )
    
    def duration_display(self, obj):
        """Display duration in human-readable format."""
        if obj.duration:
            hours, remainder = divmod(obj.duration, 60)
            return f'{hours}h {remainder}m' if hours > 0 else f'{remainder}m'
        return '-'
    duration_display.short_description = _('Duration')
    duration_display.admin_order_field = 'duration'
    
    def season_episode(self, obj):
        """Display season and episode information."""
        if obj.season_number and obj.episode_number:
            return f'S{obj.season_number:02d}E{obj.episode_number:02d}'
        elif obj.season_number:
            return f'Season {obj.season_number}'
        return '-'
    season_episode.short_description = _('S/E')
    
    def get_queryset(self, request):
        return super().get_queryset(request).select_related('channel')


@admin.register(ChannelSchedule)
class ChannelScheduleAdmin(admin.ModelAdmin):
    """Admin interface for Channel Schedules."""
    list_display = (
        'title', 'channel', 'schedule_type', 'start_time', 'end_time',
        'is_active', 'allow_ads'
    )
    list_filter = ('schedule_type', 'is_active', 'allow_ads', 'channel', 'start_time')
    search_fields = ('title', 'description', 'channel__name')
    ordering = ('-start_time',)
    readonly_fields = ('id', 'created_at', 'updated_at')
    date_hierarchy = 'start_time'
    
    fieldsets = (
        (_('Basic Information'), {
            'fields': ('channel', 'title', 'description')
        }),
        (_('Scheduling'), {
            'fields': ('schedule_type', 'start_time', 'end_time', 'is_active')
        }),
        (_('Content'), {
            'fields': ('content_url', 'backup_content_url')
        }),
        (_('Advertising'), {
            'fields': ('allow_ads', 'ad_break_duration'),
            'classes': ('collapse',)
        }),
        (_('Metadata'), {
            'fields': ('id', 'created_at', 'updated_at'),
            'classes': ('collapse',)
        })
    )
    
    def get_queryset(self, request):
        return super().get_queryset(request).select_related('channel')


# Admin site customization
admin.site.site_header = _('Adtlas Channels Administration')
admin.site.site_title = _('Adtlas Channels Admin')
admin.site.index_title = _('Welcome to Adtlas Channels Administration')