from django.db import models
from django.utils import timezone
from django.contrib.auth import get_user_model
from django.utils.translation import gettext_lazy as _

from apps.common.models import BaseModel

class ChannelZone(BaseModel):
    """Geographic zones for channel broadcasting."""
    name = models.CharField(max_length=255)
    code = models.CharField(max_length=10, unique=True)
    description = models.TextField(blank=True)
    timezone = models.CharField(max_length=50, default="UTC")
    is_active = models.BooleanField(default=True)
    
    class Meta:
        db_table = "channel_zones"
        ordering = ["name"]
    
    def __str__(self):
        return f"{self.name} ({self.code})"


class ChannelCodec(BaseModel):
    """Video/Audio codec configurations for channels."""
    name = models.CharField(max_length=100)
    video_codec = models.CharField(max_length=50)
    audio_codec = models.CharField(max_length=50)
    resolution = models.CharField(max_length=20, blank=True)  # e.g., 1920x1080
    bitrate = models.PositiveIntegerField(help_text="Bitrate in kbps")
    frame_rate = models.DecimalField(max_digits=5, decimal_places=2, null=True, blank=True)
    
    class Meta:
        db_table = "channel_codecs"
        ordering = ["name"]
    
    def __str__(self):
        return f"{self.name} ({self.video_codec}/{self.audio_codec})"


class Channel(BaseModel):
    """
    Television channels with comprehensive metadata and relationships.
    
    Represents individual TV channels with their broadcasting details,
    network affiliations, geographic coverage, and advertising inventory.
    """
    CHANNEL_TYPES = [
        ('terrestrial', _('Terrestrial/Over-the-Air')),
        ('cable', _('Cable Channel')),
        ('satellite', _('Satellite Channel')),
        ('iptv', _('IPTV Channel')),
        ('streaming', _('Streaming Channel')),
        ('radio', _('Radio Station')),
    ] 
    
    STATUS_CHOICES = [
        ("active", "Active"),
        ("inactive", "Inactive"),
        ("maintenance", "Maintenance"),
        ("testing", "Testing"),
    ]
    
    # Channel Metadata
    name = models.CharField(
        max_length=200,
        verbose_name=_('Channel Name'),
        help_text=_('Full name of the TV channel')
    ) 
    display_name = models.CharField(
        max_length=20,
        unique=True,
        verbose_name=_('Call Sign'),
        help_text=_('Official call sign or identifier (e.g., "WABC-TV", "ESPN")')
    )
    channel_number = models.CharField(
        max_length=20,
        verbose_name=_('Channel Number'),
        help_text=_('Channel number on cable/satellite systems (e.g., "7.1", "ESPN")')
    ) 
    channel_type = models.CharField(
        max_length=20,
        choices=CHANNEL_TYPES, 
        default="satellite",
        verbose_name=_('Channel Type'),
        help_text=_('Type of broadcasting technology')
    ) 
    status = models.CharField(
        max_length=20,
        choices=STATUS_CHOICES,
        default="active",
        verbose_name=_('Channel Status'),
        help_text=_('Current status of the channel (e.g., Active, Inactive, Maintenance)')
    )
    
    # Technical details
    stream_url = models.URLField(
        verbose_name=_('Stream URL'),
        help_text=_('URL for live streaming of the channel'),
        blank=True
    )
    backup_stream_url = models.URLField(
        verbose_name=_('Backup Stream URL'),
        help_text=_('URL for backup live streaming in case of issues'),
        blank=True
    )
    codec = models.ForeignKey(
        ChannelCodec,
        on_delete=models.SET_NULL,
        null=True,
        blank=True,
        verbose_name=_('Video/Audio Codec'),
        help_text=_('Codec configuration for video and audio')
    ) 
    zone = models.ForeignKey(
        ChannelZone,
        on_delete=models.SET_NULL,
        null=True,
        blank=True,
        verbose_name=_('Channel Zone'),
        help_text=_('Geographic zone where the channel is active')
    )
    
    # Branding
    logo = models.ImageField(
        verbose_name=_('Channel Logo'),
        help_text=_('Logo or image representing the channel'),
        upload_to="channels/logos/",
        blank=True,
        null=True
    )
    description = models.TextField(
        verbose_name=_('Channel Description'),
        help_text=_('Short description or tagline about the channel'),
        blank=True
    )
    website = models.URLField(
        verbose_name=_('Channel Website'),
        help_text=_('Official website of the channel'),
        blank=True
    )
    
    # Broadcasting details
    language = models.CharField(
        max_length=250,
        blank=True,
        verbose_name=_('Channel Language'),
        help_text=_('Language of the content broadcasted on the channel')
    )
    category = models.CharField(
        max_length=250,
        blank=True,
        verbose_name=_('Channel Category'),
        help_text=_('Category of content broadcasted on the channel (e.g., News, Sports, Entertainment)')
    )
    target_audience = models.CharField(
        max_length=100,
        blank=True,
        verbose_name=_('Target Audience'),
        help_text=_('Specific demographic or group the channel is targeting (e.g., Teens, Mature, Children)')
    )
    
    # Ad insertion settings
    supports_dai = models.BooleanField(
        verbose_name=_('Supports DAI'),
        default=True, 
        help_text="Dynamic Ad Insertion support"
    )
    max_ad_duration = models.PositiveIntegerField(
        verbose_name=_('Max Ad Duration'),
        default=180, 
        help_text="Maximum ad break duration in seconds"
    )
    min_ad_gap = models.PositiveIntegerField(
        verbose_name=_('Min Ad Gap'),
        default=300, 
        help_text="Minimum gap between ads in seconds"
    )
    
    # Monitoring
    last_health_check = models.DateTimeField(
        verbose_name=_('Last Health Check'),
        null=True, 
        blank=True
    )
    is_online = models.BooleanField(
        verbose_name=_('Is Online'),
        default=True
    )
    
    class Meta:
        db_table = "channels"
        ordering = ["channel_number", "name"]
        unique_together = ["channel_number", "zone"]
    
    def __str__(self):
        if self.channel_number:
            return f"{self.channel_number}. {self.display_name or self.name}"
        return self.display_name or self.name
    
    @property
    def is_active(self):
        return self.status == "active" and self.is_online
    
    def update_health_status(self, is_online=True):
        """Update channel health status."""
        self.is_online = is_online
        self.last_health_check = timezone.now()
        self.save(update_fields=["is_online", "last_health_check"])


class EPGProgram(BaseModel):
    """Electronic Program Guide entries."""
    PROGRAM_TYPES = [
        ("movie", "Movie"),
        ("series", "TV Series"),
        ("news", "News"),
        ("sports", "Sports"),
        ("documentary", "Documentary"),
        ("entertainment", "Entertainment"),
        ("kids", "Kids"),
        ("music", "Music"),
        ("other", "Other"),
    ]
    
    channel = models.ForeignKey(Channel, on_delete=models.CASCADE, related_name="programs")
    
    title = models.CharField(max_length=255)
    description = models.TextField(blank=True)
    program_type = models.CharField(max_length=20, choices=PROGRAM_TYPES, default="other")
    
    start_time = models.DateTimeField()
    end_time = models.DateTimeField()
    duration = models.PositiveIntegerField(help_text="Duration in minutes")
    
    # Content details
    season_number = models.PositiveIntegerField(null=True, blank=True)
    episode_number = models.PositiveIntegerField(null=True, blank=True)
    original_air_date = models.DateField(null=True, blank=True)
    
    # Ratings and content
    content_rating = models.CharField(max_length=10, blank=True)  # G, PG, PG-13, etc.
    language = models.CharField(max_length=50, blank=True)
    subtitles_available = models.BooleanField(default=False)
    
    # Ad insertion opportunities
    has_ad_breaks = models.BooleanField(default=True)
    ad_break_positions = models.JSONField(default=list, blank=True)  # List of seconds where ads can be inserted
    
    class Meta:
        db_table = "epg_programs"
        ordering = ["channel", "start_time"]
        indexes = [
            models.Index(fields=["channel", "start_time"]),
            models.Index(fields=["start_time", "end_time"]),
        ]
    
    def __str__(self):
        return f"{self.title} on {self.channel.name} at {self.start_time}"
    
    @property
    def is_currently_airing(self):
        now = timezone.now()
        return self.start_time <= now <= self.end_time
    
    def get_ad_opportunities(self):
        """Get available ad insertion opportunities."""
        if not self.has_ad_breaks:
            return []
        
        # Default ad breaks at beginning, middle, and end
        if not self.ad_break_positions:
            duration_seconds = self.duration * 60
            return [0, duration_seconds // 2, duration_seconds - 30]
        
        return self.ad_break_positions


class Jingle(BaseModel):
    """Channel jingles and station IDs."""
    JINGLE_TYPES = [
        ("station_id", "Station ID"),
        ("bumper", "Bumper"),
        ("promo", "Promo"),
        ("transition", "Transition"),
        ("commercial_break", "Commercial Break"),
    ]
    
    channel = models.ForeignKey(Channel, on_delete=models.CASCADE, related_name="jingles")
    
    name = models.CharField(max_length=255)
    jingle_type = models.CharField(max_length=20, choices=JINGLE_TYPES)
    file = models.FileField(upload_to="jingles/")
    duration = models.PositiveIntegerField(help_text="Duration in seconds")
    
    # Usage settings
    is_active = models.BooleanField(default=True)
    priority = models.PositiveIntegerField(default=1, help_text="Higher number = higher priority")
    
    # Scheduling
    start_date = models.DateField(null=True, blank=True)
    end_date = models.DateField(null=True, blank=True)
    time_slots = models.JSONField(default=list, blank=True)  # List of time ranges when this jingle can play
    
    # Usage tracking
    play_count = models.PositiveIntegerField(default=0)
    last_played = models.DateTimeField(null=True, blank=True)
    
    class Meta:
        db_table = "jingles"
        ordering = ["channel", "-priority", "name"]
    
    def __str__(self):
        return f"{self.name} ({self.channel.name})"
    
    def can_play_now(self):
        """Check if jingle can be played at current time."""
        if not self.is_active:
            return False
        
        now = timezone.now()
        
        # Check date range
        if self.start_date and now.date() < self.start_date:
            return False
        if self.end_date and now.date() > self.end_date:
            return False
        
        # Check time slots
        if self.time_slots:
            current_time = now.time()
            for slot in self.time_slots:
                start_time = timezone.datetime.strptime(slot["start"], "%H:%M").time()
                end_time = timezone.datetime.strptime(slot["end"], "%H:%M").time()
                if start_time <= current_time <= end_time:
                    return True
            return False
        
        return True
    
    def mark_played(self):
        """Mark jingle as played."""
        self.play_count += 1
        self.last_played = timezone.now()
        self.save(update_fields=["play_count", "last_played"])


class ChannelSchedule(BaseModel):
    """Channel broadcasting schedule."""
    SCHEDULE_TYPES = [
        ("regular", "Regular Programming"),
        ("special", "Special Event"),
        ("maintenance", "Maintenance"),
        ("test", "Test Broadcast"),
    ]
    
    channel = models.ForeignKey(Channel, on_delete=models.CASCADE, related_name="schedules")
    
    title = models.CharField(max_length=255)
    schedule_type = models.CharField(max_length=20, choices=SCHEDULE_TYPES, default="regular")
    
    start_time = models.DateTimeField()
    end_time = models.DateTimeField()
    
    # Content details
    description = models.TextField(blank=True)
    content_url = models.URLField(blank=True)
    backup_content_url = models.URLField(blank=True)
    
    # Ad settings
    allow_ads = models.BooleanField(default=True)
    ad_break_duration = models.PositiveIntegerField(default=120, help_text="Ad break duration in seconds")
    
    # Status
    is_active = models.BooleanField(default=True)
    
    class Meta:
        db_table = "channel_schedules"
        ordering = ["channel", "start_time"]
    
    def __str__(self):
        return f"{self.title} on {self.channel.name}"
    
    @property
    def is_currently_active(self):
        now = timezone.now()
        return self.is_active and self.start_time <= now <= self.end_time

