from django.db import models
from django.contrib.auth import get_user_model
from django.utils import timezone
from apps.common.models import BaseModel


class Brand(BaseModel):
    """Brand model for organizing campaigns."""
    name = models.CharField(max_length=255)
    description = models.TextField(blank=True)
    logo = models.ImageField(upload_to="brands/", blank=True, null=True)
    website = models.URLField(blank=True)
    is_active = models.BooleanField(default=True)
    
    class Meta:
        db_table = "brands"
        ordering = ["name"]
    
    def __str__(self):
        return self.name


class Agency(BaseModel):
    """Advertising agency model."""
    name = models.CharField(max_length=255)
    contact_person = models.CharField(max_length=255, blank=True)
    email = models.EmailField(blank=True)
    phone = models.CharField(max_length=20, blank=True)
    address = models.TextField(blank=True)
    is_active = models.BooleanField(default=True)
    
    class Meta:
        db_table = "agencies"
        ordering = ["name"]
        verbose_name_plural = "Agencies"
    
    def __str__(self):
        return self.name


class Campaign(BaseModel):
    """Main campaign model."""
    CAMPAIGN_TYPES = [
        ("standard", "Standard"),
        ("premium", "Premium"),
        ("sponsored", "Sponsored"),
    ]
    
    STATUS_CHOICES = [
        ("draft", "Draft"),
        ("pending", "Pending Approval"),
        ("approved", "Approved"),
        ("active", "Active"),
        ("paused", "Paused"),
        ("completed", "Completed"),
        ("cancelled", "Cancelled"),
    ]
    
    name = models.CharField(max_length=255)
    description = models.TextField(blank=True)
    brand = models.ForeignKey(Brand, on_delete=models.CASCADE, related_name="campaigns")
    agency = models.ForeignKey(Agency, on_delete=models.SET_NULL, null=True, blank=True, related_name="campaigns")
    
    campaign_type = models.CharField(max_length=20, choices=CAMPAIGN_TYPES, default="standard")
    status = models.CharField(max_length=20, choices=STATUS_CHOICES, default="draft")
    
    start_date = models.DateTimeField()
    end_date = models.DateTimeField()
    
    budget = models.DecimalField(max_digits=12, decimal_places=2, null=True, blank=True)
    target_impressions = models.PositiveIntegerField(null=True, blank=True)
    
    created_by = models.ForeignKey("accounts.User", on_delete=models.SET_NULL, null=True, related_name="created_campaigns")
    approved_by = models.ForeignKey("accounts.User", on_delete=models.SET_NULL, null=True, blank=True, related_name="approved_campaigns")
    approved_at = models.DateTimeField(null=True, blank=True)
    
    class Meta:
        db_table = "campaigns"
        ordering = ["-created_at"]
    
    def __str__(self):
        return f"{self.name} ({self.brand.name})"
    
    @property
    def is_active(self):
        now = timezone.now()
        return (self.status == "active" and 
                self.start_date <= now <= self.end_date)
    
    @property
    def total_impressions(self):
        return sum(adspot.impressions for adspot in self.adspots.all())
    
    def approve(self, user):
        """Approve the campaign."""
        self.status = "approved"
        self.approved_by = user
        self.approved_at = timezone.now()
        self.save()


class Creative(BaseModel):
    """Creative assets for campaigns."""
    CREATIVE_TYPES = [
        ("video", "Video"),
        ("audio", "Audio"),
        ("image", "Image"),
        ("text", "Text"),
    ]
    
    name = models.CharField(max_length=255)
    creative_type = models.CharField(max_length=20, choices=CREATIVE_TYPES)
    file = models.FileField(upload_to="creatives/")
    duration = models.PositiveIntegerField(null=True, blank=True, help_text="Duration in seconds")
    file_size = models.PositiveIntegerField(null=True, blank=True, help_text="File size in bytes")
    
    # Video/Image specific
    width = models.PositiveIntegerField(null=True, blank=True)
    height = models.PositiveIntegerField(null=True, blank=True)
    
    # Audio specific
    bitrate = models.PositiveIntegerField(null=True, blank=True)
    
    is_approved = models.BooleanField(default=False)
    approved_by = models.ForeignKey("accounts.User", on_delete=models.SET_NULL, null=True, blank=True)
    approved_at = models.DateTimeField(null=True, blank=True)
    
    class Meta:
        db_table = "creatives"
        ordering = ["-created_at"]
    
    def __str__(self):
        return f"{self.name} ({self.creative_type})"


class AdSpot(BaseModel):
    """Ad spot placement within campaigns."""
    campaign = models.ForeignKey(Campaign, on_delete=models.CASCADE, related_name="adspots")
    creative = models.ForeignKey(Creative, on_delete=models.CASCADE, related_name="adspots")
    
    name = models.CharField(max_length=255)
    position = models.PositiveIntegerField(default=1, help_text="Position in the ad break")
    
    # Scheduling
    start_time = models.DateTimeField()
    end_time = models.DateTimeField()
    
    # Targeting
    target_channels = models.ManyToManyField("channels.Channel", blank=True)
    target_demographics = models.JSONField(default=dict, blank=True)
    
    # Performance
    impressions = models.PositiveIntegerField(default=0)
    clicks = models.PositiveIntegerField(default=0)
    
    is_active = models.BooleanField(default=True)
    
    class Meta:
        db_table = "adspots"
        ordering = ["campaign", "position"]
    
    def __str__(self):
        return f"{self.name} - {self.campaign.name}"
    
    @property
    def ctr(self):
        """Click-through rate."""
        if self.impressions > 0:
            return (self.clicks / self.impressions) * 100
        return 0


class AdBreakHistory(BaseModel):
    """History of ad break executions."""
    adspot = models.ForeignKey(AdSpot, on_delete=models.CASCADE, related_name="history")
    channel = models.ForeignKey("channels.Channel", on_delete=models.CASCADE, related_name="campaign_adbreak_history")
    
    executed_at = models.DateTimeField()
    duration = models.PositiveIntegerField(help_text="Actual duration in seconds")
    
    # Performance metrics
    impressions = models.PositiveIntegerField(default=0)
    completion_rate = models.DecimalField(max_digits=5, decimal_places=2, default=0)
    
    # Technical details
    player_version = models.CharField(max_length=50, blank=True)
    user_agent = models.TextField(blank=True)
    ip_address = models.GenericIPAddressField(null=True, blank=True)
    
    class Meta:
        db_table = "adbreak_history"
        ordering = ["-executed_at"]
        verbose_name_plural = "Ad Break History"
    
    def __str__(self):
        return f"{self.adspot.name} on {self.channel.name} at {self.executed_at}"


class CampaignReport(BaseModel):
    """Campaign performance reports."""
    REPORT_TYPES = [
        ("daily", "Daily"),
        ("weekly", "Weekly"),
        ("monthly", "Monthly"),
        ("custom", "Custom"),
    ]
    
    campaign = models.ForeignKey(Campaign, on_delete=models.CASCADE, related_name="reports")
    report_type = models.CharField(max_length=20, choices=REPORT_TYPES)
    
    start_date = models.DateField()
    end_date = models.DateField()
    
    # Metrics
    total_impressions = models.PositiveIntegerField(default=0)
    total_clicks = models.PositiveIntegerField(default=0)
    total_spend = models.DecimalField(max_digits=12, decimal_places=2, default=0)
    
    # Calculated fields
    ctr = models.DecimalField(max_digits=5, decimal_places=2, default=0)
    cpm = models.DecimalField(max_digits=8, decimal_places=2, default=0)
    cpc = models.DecimalField(max_digits=8, decimal_places=2, default=0)
    
    generated_by = models.ForeignKey("accounts.User", on_delete=models.SET_NULL, null=True)
    
    class Meta:
        db_table = "campaign_reports"
        ordering = ["-created_at"]
        unique_together = ["campaign", "report_type", "start_date", "end_date"]
    
    def __str__(self):
        return f"{self.campaign.name} - {self.report_type} ({self.start_date} to {self.end_date})"