# -*- coding: utf-8 -*-

from django.db import models
from django.contrib.auth import get_user_model
from django.core.validators import MinValueValidator, MaxValueValidator
from django.utils import timezone
from django.urls import reverse
from decimal import Decimal
import uuid

User = get_user_model()


class CampaignObjective(models.Model):
    """
    Model representing campaign objectives and goals.
    
    Defines the primary goals and KPIs for advertising campaigns,
    helping to categorize and optimize campaigns based on their objectives.
    """
    
    OBJECTIVE_TYPES = [
        ('awareness', 'Brand Awareness'),
        ('traffic', 'Website Traffic'),
        ('engagement', 'Engagement'),
        ('leads', 'Lead Generation'),
        ('conversions', 'Conversions'),
        ('sales', 'Sales'),
        ('app_installs', 'App Installs'),
        ('video_views', 'Video Views'),
        ('reach', 'Reach'),
        ('impressions', 'Impressions'),
    ]
    
    name = models.CharField(
        max_length=100,
        verbose_name='Objective Name',
        help_text='Name of the campaign objective'
    )
    objective_type = models.CharField(
        max_length=20,
        choices=OBJECTIVE_TYPES,
        verbose_name='Objective Type',
        help_text='Type of campaign objective'
    )
    description = models.TextField(
        blank=True,
        verbose_name='Description',
        help_text='Detailed description of the objective'
    )
    kpi_metric = models.CharField(
        max_length=50,
        blank=True,
        verbose_name='KPI Metric',
        help_text='Key performance indicator metric (e.g., CTR, CPA, ROAS)'
    )
    target_value = models.DecimalField(
        max_digits=12,
        decimal_places=2,
        null=True,
        blank=True,
        verbose_name='Target Value',
        help_text='Target value for the KPI metric'
    )
    is_active = models.BooleanField(
        default=True,
        verbose_name='Active',
        help_text='Whether this objective is active'
    )
    created_at = models.DateTimeField(auto_now_add=True, verbose_name='Created At')
    updated_at = models.DateTimeField(auto_now=True, verbose_name='Updated At')
    
    class Meta:
        verbose_name = 'Campaign Objective'
        verbose_name_plural = 'Campaign Objectives'
        db_table = 'campaigns_objective'
        ordering = ['name']
        indexes = [
            models.Index(fields=['objective_type'], name='campaigns_objective_type_idx'),
            models.Index(fields=['is_active'], name='campaigns_objective_active_idx'),
        ]
    
    def __str__(self):
        return f"{self.name} ({self.get_objective_type_display()})"


class Campaign(models.Model):
    """
    Main model representing an advertising campaign.
    
    This model contains all the essential information for managing
    advertising campaigns including budget, targeting, scheduling,
    and performance tracking.
    """
    
    STATUS_CHOICES = [
        ('draft', 'Draft'),
        ('pending_approval', 'Pending Approval'),
        ('approved', 'Approved'),
        ('active', 'Active'),
        ('paused', 'Paused'),
        ('completed', 'Completed'),
        ('cancelled', 'Cancelled'),
        ('rejected', 'Rejected'),
    ]
    
    BUDGET_TYPES = [
        ('daily', 'Daily Budget'),
        ('total', 'Total Budget'),
        ('monthly', 'Monthly Budget'),
    ]
    
    BIDDING_STRATEGIES = [
        ('cpc', 'Cost Per Click'),
        ('cpm', 'Cost Per Mille'),
        ('cpa', 'Cost Per Acquisition'),
        ('ctr', 'Click Through Rate'),
        ('auto', 'Automatic Bidding'),
    ]
    
    # Basic Information
    id = models.UUIDField(
        primary_key=True,
        default=uuid.uuid4,
        editable=False,
        verbose_name='Campaign ID'
    )
    name = models.CharField(
        max_length=200,
        verbose_name='Campaign Name',
        help_text='Descriptive name for the campaign'
    )
    code = models.CharField(
        max_length=20,
        unique=True,
        verbose_name='Campaign Code',
        help_text='Unique campaign code (e.g., CMP001)'
    )
    description = models.TextField(
        blank=True,
        verbose_name='Description',
        help_text='Detailed campaign description'
    )
    
    # Relationships
    advertiser = models.ForeignKey(
        'advertisers.Advertiser',
        on_delete=models.CASCADE,
        related_name='campaigns',
        verbose_name='Advertiser',
        help_text='Campaign advertiser'
    )
    brand = models.ForeignKey(
        'advertisers.Brand',
        on_delete=models.SET_NULL,
        null=True,
        blank=True,
        related_name='campaigns',
        verbose_name='Brand',
        help_text='Associated brand'
    )
    objective = models.ForeignKey(
        CampaignObjective,
        on_delete=models.SET_NULL,
        null=True,
        blank=True,
        related_name='campaigns',
        verbose_name='Objective',
        help_text='Campaign objective'
    )
    created_by = models.ForeignKey(
        User,
        on_delete=models.SET_NULL,
        null=True,
        related_name='created_campaigns',
        verbose_name='Created By',
        help_text='User who created the campaign'
    )
    
    # Status and Lifecycle
    status = models.CharField(
        max_length=20,
        choices=STATUS_CHOICES,
        default='draft',
        verbose_name='Status',
        help_text='Current campaign status'
    )
    
    # Budget and Bidding
    budget_type = models.CharField(
        max_length=20,
        choices=BUDGET_TYPES,
        default='daily',
        verbose_name='Budget Type',
        help_text='Type of budget allocation'
    )
    budget_amount = models.DecimalField(
        max_digits=12,
        decimal_places=2,
        validators=[MinValueValidator(Decimal('0.01'))],
        verbose_name='Budget Amount',
        help_text='Campaign budget amount'
    )
    spent_amount = models.DecimalField(
        max_digits=12,
        decimal_places=2,
        default=Decimal('0.00'),
        verbose_name='Spent Amount',
        help_text='Amount already spent'
    )
    bidding_strategy = models.CharField(
        max_length=20,
        choices=BIDDING_STRATEGIES,
        default='cpc',
        verbose_name='Bidding Strategy',
        help_text='Campaign bidding strategy'
    )
    max_bid = models.DecimalField(
        max_digits=10,
        decimal_places=4,
        null=True,
        blank=True,
        validators=[MinValueValidator(Decimal('0.0001'))],
        verbose_name='Maximum Bid',
        help_text='Maximum bid amount'
    )
    
    # Scheduling
    start_date = models.DateTimeField(
        verbose_name='Start Date',
        help_text='Campaign start date and time'
    )
    end_date = models.DateTimeField(
        null=True,
        blank=True,
        verbose_name='End Date',
        help_text='Campaign end date and time (optional for ongoing campaigns)'
    )
    timezone = models.CharField(
        max_length=50,
        default='UTC',
        verbose_name='Timezone',
        help_text='Campaign timezone'
    )
    
    # Performance Tracking
    impressions = models.BigIntegerField(
        default=0,
        verbose_name='Impressions',
        help_text='Total impressions delivered'
    )
    clicks = models.BigIntegerField(
        default=0,
        verbose_name='Clicks',
        help_text='Total clicks received'
    )
    conversions = models.BigIntegerField(
        default=0,
        verbose_name='Conversions',
        help_text='Total conversions achieved'
    )
    
    # Settings
    is_active = models.BooleanField(
        default=True,
        verbose_name='Active',
        help_text='Whether this campaign is active'
    )
    auto_optimize = models.BooleanField(
        default=False,
        verbose_name='Auto Optimize',
        help_text='Enable automatic campaign optimization'
    )
    frequency_cap = models.PositiveIntegerField(
        null=True,
        blank=True,
        verbose_name='Frequency Cap',
        help_text='Maximum impressions per user'
    )
    
    # Timestamps
    created_at = models.DateTimeField(auto_now_add=True, verbose_name='Created At')
    updated_at = models.DateTimeField(auto_now=True, verbose_name='Updated At')
    approved_at = models.DateTimeField(
        null=True,
        blank=True,
        verbose_name='Approved At',
        help_text='When the campaign was approved'
    )
    launched_at = models.DateTimeField(
        null=True,
        blank=True,
        verbose_name='Launched At',
        help_text='When the campaign was launched'
    )
    
    class Meta:
        verbose_name = 'Campaign'
        verbose_name_plural = 'Campaigns'
        db_table = 'campaigns_campaign'
        ordering = ['-created_at']
        indexes = [
            models.Index(fields=['name'], name='campaigns_campaign_name_idx'),
            models.Index(fields=['code'], name='campaigns_campaign_code_idx'),
            models.Index(fields=['advertiser'], name='campaigns_campaign_advertiser_idx'),
            models.Index(fields=['brand'], name='campaigns_campaign_brand_idx'),
            models.Index(fields=['status'], name='campaigns_campaign_status_idx'),
            models.Index(fields=['start_date'], name='campaigns_campaign_start_idx'),
            models.Index(fields=['end_date'], name='campaigns_campaign_end_idx'),
            models.Index(fields=['budget_type'], name='campaigns_campaign_budget_type_idx'),
            models.Index(fields=['bidding_strategy'], name='campaigns_campaign_bidding_idx'),
            models.Index(fields=['is_active'], name='campaigns_campaign_active_idx'),
            models.Index(fields=['created_by'], name='campaigns_campaign_creator_idx'),
        ]
        constraints = [
            models.CheckConstraint(
                check=models.Q(budget_amount__gt=0),
                name='positive_budget_amount'
            ),
            models.CheckConstraint(
                check=models.Q(spent_amount__gte=0),
                name='non_negative_spent_amount'
            ),
            models.CheckConstraint(
                check=models.Q(end_date__isnull=True) | models.Q(end_date__gt=models.F('start_date')),
                name='valid_date_range'
            ),
        ]
    
    def __str__(self):
        return f"{self.name} ({self.code})"
    
    def get_absolute_url(self):
        """Return the absolute URL for this campaign."""
        return reverse('campaigns:campaign-detail', kwargs={'pk': self.pk})
    
    @property
    def remaining_budget(self):
        """Calculate remaining budget."""
        return self.budget_amount - self.spent_amount
    
    @property
    def budget_utilization(self):
        """Calculate budget utilization percentage."""
        if self.budget_amount > 0:
            return (self.spent_amount / self.budget_amount) * 100
        return 0
    
    @property
    def ctr(self):
        """Calculate click-through rate."""
        if self.impressions > 0:
            return (self.clicks / self.impressions) * 100
        return 0
    
    @property
    def conversion_rate(self):
        """Calculate conversion rate."""
        if self.clicks > 0:
            return (self.conversions / self.clicks) * 100
        return 0
    
    @property
    def is_running(self):
        """Check if campaign is currently running."""
        now = timezone.now()
        return (
            self.status == 'active' and
            self.start_date <= now and
            (self.end_date is None or self.end_date >= now)
        )
    
    def can_be_activated(self):
        """Check if campaign can be activated."""
        return self.status in ['approved', 'paused'] and self.remaining_budget > 0
    
    def pause(self):
        """Pause the campaign."""
        if self.status == 'active':
            self.status = 'paused'
            self.save(update_fields=['status', 'updated_at'])
    
    def activate(self):
        """Activate the campaign."""
        if self.can_be_activated():
            self.status = 'active'
            if not self.launched_at:
                self.launched_at = timezone.now()
            self.save(update_fields=['status', 'launched_at', 'updated_at'])


class TargetingRule(models.Model):
    """
    Model representing campaign targeting rules.
    
    Defines audience targeting criteria for campaigns including
    demographic, geographic, behavioral, and interest-based targeting.
    """
    
    TARGETING_TYPES = [
        ('demographic', 'Demographic'),
        ('geographic', 'Geographic'),
        ('behavioral', 'Behavioral'),
        ('interest', 'Interest'),
        ('device', 'Device'),
        ('platform', 'Platform'),
        ('custom', 'Custom Audience'),
    ]
    
    OPERATORS = [
        ('equals', 'Equals'),
        ('not_equals', 'Not Equals'),
        ('contains', 'Contains'),
        ('not_contains', 'Does Not Contain'),
        ('in', 'In List'),
        ('not_in', 'Not In List'),
        ('greater_than', 'Greater Than'),
        ('less_than', 'Less Than'),
        ('between', 'Between'),
    ]
    
    campaign = models.ForeignKey(
        Campaign,
        on_delete=models.CASCADE,
        related_name='targeting_rules',
        verbose_name='Campaign',
        help_text='Associated campaign'
    )
    name = models.CharField(
        max_length=100,
        verbose_name='Rule Name',
        help_text='Descriptive name for the targeting rule'
    )
    targeting_type = models.CharField(
        max_length=20,
        choices=TARGETING_TYPES,
        verbose_name='Targeting Type',
        help_text='Type of targeting rule'
    )
    field_name = models.CharField(
        max_length=50,
        verbose_name='Field Name',
        help_text='Target field name (e.g., age, location, interest)'
    )
    operator = models.CharField(
        max_length=20,
        choices=OPERATORS,
        verbose_name='Operator',
        help_text='Comparison operator'
    )
    value = models.TextField(
        verbose_name='Value',
        help_text='Target value(s) - JSON format for complex values'
    )
    is_include = models.BooleanField(
        default=True,
        verbose_name='Include',
        help_text='True for include rule, False for exclude rule'
    )
    priority = models.PositiveIntegerField(
        default=0,
        verbose_name='Priority',
        help_text='Rule priority (higher numbers = higher priority)'
    )
    is_active = models.BooleanField(
        default=True,
        verbose_name='Active',
        help_text='Whether this rule is active'
    )
    created_at = models.DateTimeField(auto_now_add=True, verbose_name='Created At')
    updated_at = models.DateTimeField(auto_now=True, verbose_name='Updated At')
    
    class Meta:
        verbose_name = 'Targeting Rule'
        verbose_name_plural = 'Targeting Rules'
        db_table = 'campaigns_targeting_rule'
        ordering = ['-priority', 'name']
        indexes = [
            models.Index(fields=['campaign'], name='campaigns_targeting_campaign_idx'),
            models.Index(fields=['targeting_type'], name='campaigns_targeting_type_idx'),
            models.Index(fields=['field_name'], name='campaigns_targeting_field_idx'),
            models.Index(fields=['is_active'], name='campaigns_targeting_active_idx'),
            models.Index(fields=['priority'], name='campaigns_targeting_priority_idx'),
        ]
    
    def __str__(self):
        return f"{self.name} ({self.campaign.name})"


class Creative(models.Model):
    """
    Model representing campaign creative assets.
    
    Manages creative assets including images, videos, text,
    and other media used in advertising campaigns.
    """
    
    CREATIVE_TYPES = [
        ('image', 'Image'),
        ('video', 'Video'),
        ('text', 'Text'),
        ('html', 'HTML'),
        ('banner', 'Banner'),
        ('native', 'Native'),
        ('audio', 'Audio'),
    ]
    
    FORMATS = [
        ('jpg', 'JPEG'),
        ('png', 'PNG'),
        ('gif', 'GIF'),
        ('mp4', 'MP4'),
        ('webm', 'WebM'),
        ('html', 'HTML'),
        ('txt', 'Text'),
    ]
    
    campaign = models.ForeignKey(
        Campaign,
        on_delete=models.CASCADE,
        related_name='creatives',
        verbose_name='Campaign',
        help_text='Associated campaign'
    )
    name = models.CharField(
        max_length=200,
        verbose_name='Creative Name',
        help_text='Descriptive name for the creative'
    )
    creative_type = models.CharField(
        max_length=20,
        choices=CREATIVE_TYPES,
        verbose_name='Creative Type',
        help_text='Type of creative asset'
    )
    format = models.CharField(
        max_length=10,
        choices=FORMATS,
        verbose_name='Format',
        help_text='File format of the creative'
    )
    
    # Content
    title = models.CharField(
        max_length=200,
        blank=True,
        verbose_name='Title',
        help_text='Creative title or headline'
    )
    description = models.TextField(
        blank=True,
        verbose_name='Description',
        help_text='Creative description or body text'
    )
    call_to_action = models.CharField(
        max_length=50,
        blank=True,
        verbose_name='Call to Action',
        help_text='Call to action text (e.g., "Learn More", "Buy Now")'
    )
    
    # Media Files
    image_file = models.ImageField(
        upload_to='campaigns/creatives/images/',
        null=True,
        blank=True,
        verbose_name='Image File',
        help_text='Image creative file'
    )
    video_file = models.FileField(
        upload_to='campaigns/creatives/videos/',
        null=True,
        blank=True,
        verbose_name='Video File',
        help_text='Video creative file'
    )
    html_content = models.TextField(
        blank=True,
        verbose_name='HTML Content',
        help_text='HTML creative content'
    )
    
    # URLs
    landing_url = models.URLField(
        blank=True,
        verbose_name='Landing URL',
        help_text='Destination URL when creative is clicked'
    )
    tracking_url = models.URLField(
        blank=True,
        verbose_name='Tracking URL',
        help_text='URL for tracking clicks and conversions'
    )
    
    # Dimensions and Specifications
    width = models.PositiveIntegerField(
        null=True,
        blank=True,
        verbose_name='Width',
        help_text='Creative width in pixels'
    )
    height = models.PositiveIntegerField(
        null=True,
        blank=True,
        verbose_name='Height',
        help_text='Creative height in pixels'
    )
    file_size = models.PositiveIntegerField(
        null=True,
        blank=True,
        verbose_name='File Size',
        help_text='File size in bytes'
    )
    duration = models.PositiveIntegerField(
        null=True,
        blank=True,
        verbose_name='Duration',
        help_text='Duration in seconds (for video/audio)'
    )
    
    # Performance
    impressions = models.BigIntegerField(
        default=0,
        verbose_name='Impressions',
        help_text='Total impressions for this creative'
    )
    clicks = models.BigIntegerField(
        default=0,
        verbose_name='Clicks',
        help_text='Total clicks for this creative'
    )
    conversions = models.BigIntegerField(
        default=0,
        verbose_name='Conversions',
        help_text='Total conversions for this creative'
    )
    
    # Status
    is_active = models.BooleanField(
        default=True,
        verbose_name='Active',
        help_text='Whether this creative is active'
    )
    is_approved = models.BooleanField(
        default=False,
        verbose_name='Approved',
        help_text='Whether this creative is approved'
    )
    
    # Timestamps
    created_at = models.DateTimeField(auto_now_add=True, verbose_name='Created At')
    updated_at = models.DateTimeField(auto_now=True, verbose_name='Updated At')
    approved_at = models.DateTimeField(
        null=True,
        blank=True,
        verbose_name='Approved At',
        help_text='When the creative was approved'
    )
    
    class Meta:
        verbose_name = 'Creative'
        verbose_name_plural = 'Creatives'
        db_table = 'campaigns_creative'
        ordering = ['-created_at']
        indexes = [
            models.Index(fields=['campaign'], name='campaigns_creative_campaign_idx'),
            models.Index(fields=['creative_type'], name='campaigns_creative_type_idx'),
            models.Index(fields=['format'], name='campaigns_creative_format_idx'),
            models.Index(fields=['is_active'], name='campaigns_creative_active_idx'),
            models.Index(fields=['is_approved'], name='campaigns_creative_approved_idx'),
        ]
    
    def __str__(self):
        return f"{self.name} ({self.creative_type})"
    
    @property
    def ctr(self):
        """Calculate click-through rate for this creative."""
        if self.impressions > 0:
            return (self.clicks / self.impressions) * 100
        return 0
    
    @property
    def conversion_rate(self):
        """Calculate conversion rate for this creative."""
        if self.clicks > 0:
            return (self.conversions / self.clicks) * 100
        return 0


class CampaignSchedule(models.Model):
    """
    Model representing campaign scheduling rules.
    
    Manages time-based campaign scheduling including
    day-of-week, hour-of-day, and date-specific scheduling.
    """
    
    SCHEDULE_TYPES = [
        ('always', 'Always On'),
        ('daily', 'Daily Schedule'),
        ('weekly', 'Weekly Schedule'),
        ('custom', 'Custom Schedule'),
    ]
    
    DAYS_OF_WEEK = [
        (0, 'Monday'),
        (1, 'Tuesday'),
        (2, 'Wednesday'),
        (3, 'Thursday'),
        (4, 'Friday'),
        (5, 'Saturday'),
        (6, 'Sunday'),
    ]
    
    campaign = models.ForeignKey(
        Campaign,
        on_delete=models.CASCADE,
        related_name='schedules',
        verbose_name='Campaign',
        help_text='Associated campaign'
    )
    name = models.CharField(
        max_length=100,
        verbose_name='Schedule Name',
        help_text='Descriptive name for the schedule'
    )
    schedule_type = models.CharField(
        max_length=20,
        choices=SCHEDULE_TYPES,
        default='always',
        verbose_name='Schedule Type',
        help_text='Type of scheduling'
    )
    
    # Time-based scheduling
    days_of_week = models.JSONField(
        default=list,
        blank=True,
        verbose_name='Days of Week',
        help_text='List of days when campaign should run (0=Monday, 6=Sunday)'
    )
    start_time = models.TimeField(
        null=True,
        blank=True,
        verbose_name='Start Time',
        help_text='Daily start time'
    )
    end_time = models.TimeField(
        null=True,
        blank=True,
        verbose_name='End Time',
        help_text='Daily end time'
    )
    
    # Date-specific scheduling
    specific_dates = models.JSONField(
        default=list,
        blank=True,
        verbose_name='Specific Dates',
        help_text='List of specific dates when campaign should run'
    )
    exclude_dates = models.JSONField(
        default=list,
        blank=True,
        verbose_name='Exclude Dates',
        help_text='List of dates when campaign should not run'
    )
    
    # Budget allocation
    budget_percentage = models.DecimalField(
        max_digits=5,
        decimal_places=2,
        default=Decimal('100.00'),
        validators=[MinValueValidator(Decimal('0.01')), MaxValueValidator(Decimal('100.00'))],
        verbose_name='Budget Percentage',
        help_text='Percentage of campaign budget allocated to this schedule'
    )
    
    # Status
    is_active = models.BooleanField(
        default=True,
        verbose_name='Active',
        help_text='Whether this schedule is active'
    )
    
    # Timestamps
    created_at = models.DateTimeField(auto_now_add=True, verbose_name='Created At')
    updated_at = models.DateTimeField(auto_now=True, verbose_name='Updated At')
    
    class Meta:
        verbose_name = 'Campaign Schedule'
        verbose_name_plural = 'Campaign Schedules'
        db_table = 'campaigns_schedule'
        ordering = ['name']
        indexes = [
            models.Index(fields=['campaign'], name='campaigns_schedule_campaign_idx'),
            models.Index(fields=['schedule_type'], name='campaigns_schedule_type_idx'),
            models.Index(fields=['is_active'], name='campaigns_schedule_active_idx'),
        ]
    
    def __str__(self):
        return f"{self.name} ({self.campaign.name})"
    
    def is_active_now(self):
        """Check if the schedule is currently active."""
        if not self.is_active:
            return False
        
        if self.schedule_type == 'always':
            return True
        
        now = timezone.now()
        current_time = now.time()
        current_day = now.weekday()
        current_date = now.date()
        
        # Check time-based scheduling
        if self.start_time and self.end_time:
            if not (self.start_time <= current_time <= self.end_time):
                return False
        
        # Check day-of-week scheduling
        if self.days_of_week and current_day not in self.days_of_week:
            return False
        
        # Check specific dates
        if self.specific_dates:
            date_strings = [str(date) for date in self.specific_dates]
            if str(current_date) not in date_strings:
                return False
        
        # Check exclude dates
        if self.exclude_dates:
            date_strings = [str(date) for date in self.exclude_dates]
            if str(current_date) in date_strings:
                return False
        
        return True


class CampaignPerformance(models.Model):
    """
    Model for tracking campaign performance metrics.
    
    Stores daily performance data for campaigns including
    impressions, clicks, conversions, and costs.
    """
    
    campaign = models.ForeignKey(
        Campaign,
        on_delete=models.CASCADE,
        related_name='performance_data',
        verbose_name='Campaign',
        help_text='Associated campaign'
    )
    date = models.DateField(
        verbose_name='Date',
        help_text='Performance data date'
    )
    
    # Traffic Metrics
    impressions = models.BigIntegerField(
        default=0,
        verbose_name='Impressions',
        help_text='Number of impressions'
    )
    clicks = models.BigIntegerField(
        default=0,
        verbose_name='Clicks',
        help_text='Number of clicks'
    )
    unique_clicks = models.BigIntegerField(
        default=0,
        verbose_name='Unique Clicks',
        help_text='Number of unique clicks'
    )
    
    # Conversion Metrics
    conversions = models.BigIntegerField(
        default=0,
        verbose_name='Conversions',
        help_text='Number of conversions'
    )
    conversion_value = models.DecimalField(
        max_digits=12,
        decimal_places=2,
        default=Decimal('0.00'),
        verbose_name='Conversion Value',
        help_text='Total value of conversions'
    )
    
    # Cost Metrics
    cost = models.DecimalField(
        max_digits=12,
        decimal_places=2,
        default=Decimal('0.00'),
        verbose_name='Cost',
        help_text='Total cost for the day'
    )
    
    # Calculated Metrics (stored for performance)
    ctr = models.DecimalField(
        max_digits=8,
        decimal_places=4,
        default=Decimal('0.0000'),
        verbose_name='CTR (%)',
        help_text='Click-through rate percentage'
    )
    cpc = models.DecimalField(
        max_digits=10,
        decimal_places=4,
        default=Decimal('0.0000'),
        verbose_name='CPC',
        help_text='Cost per click'
    )
    cpm = models.DecimalField(
        max_digits=10,
        decimal_places=4,
        default=Decimal('0.0000'),
        verbose_name='CPM',
        help_text='Cost per mille (thousand impressions)'
    )
    cpa = models.DecimalField(
        max_digits=10,
        decimal_places=4,
        default=Decimal('0.0000'),
        verbose_name='CPA',
        help_text='Cost per acquisition'
    )
    roas = models.DecimalField(
        max_digits=10,
        decimal_places=4,
        default=Decimal('0.0000'),
        verbose_name='ROAS',
        help_text='Return on ad spend'
    )
    
    # Timestamps
    created_at = models.DateTimeField(auto_now_add=True, verbose_name='Created At')
    updated_at = models.DateTimeField(auto_now=True, verbose_name='Updated At')
    
    class Meta:
        verbose_name = 'Campaign Performance'
        verbose_name_plural = 'Campaign Performance'
        db_table = 'campaigns_performance'
        ordering = ['-date']
        unique_together = ['campaign', 'date']
        indexes = [
            models.Index(fields=['campaign'], name='campaigns_performance_campaign_idx'),
            models.Index(fields=['date'], name='campaigns_performance_date_idx'),
            models.Index(fields=['campaign', 'date'], name='campaigns_performance_campaign_date_idx'),
        ]
    
    def __str__(self):
        return f"{self.campaign.name} - {self.date}"
    
    def save(self, *args, **kwargs):
        """Calculate derived metrics before saving."""
        # Calculate CTR
        if self.impressions > 0:
            self.ctr = (self.clicks / self.impressions) * 100
        
        # Calculate CPC
        if self.clicks > 0:
            self.cpc = self.cost / self.clicks
        
        # Calculate CPM
        if self.impressions > 0:
            self.cpm = (self.cost / self.impressions) * 1000
        
        # Calculate CPA
        if self.conversions > 0:
            self.cpa = self.cost / self.conversions
        
        # Calculate ROAS
        if self.cost > 0:
            self.roas = self.conversion_value / self.cost
        
        super().save(*args, **kwargs)