"""Advertisers Models

This module defines the database models for advertiser and brand management.
It includes models for agencies, brands, and their relationships.

Models:
    - Agency: Advertising agency information
    - Brand: Brand/advertiser information
    - BrandCategory: Brand categorization
    - UserAdvertiser: User-advertiser relationships
"""


from django.db import models
from django.contrib.auth import get_user_model
from django.core.validators import EmailValidator, URLValidator
from django.utils import timezone
from django.utils.translation import gettext_lazy as _

from apps.common.models import BaseModel, AuditModel, StatusModel 
from apps.advertisers.utils import agencies_logo_upload_path

User = get_user_model()


class Agency(BaseModel, AuditModel, StatusModel):
    """Advertising Agency model.
    
    Represents advertising agencies that manage multiple brands
    and campaigns. Agencies can have multiple users and brands
    associated with them.
    
    Attributes:
        name (str): Agency name
        description (str): Agency description
        email (str): Primary contact email
        phone (str): Primary contact phone
        website (str): Agency website URL
        address (str): Physical address
        city (str): City location
        country (str): Country location
        logo (ImageField): Agency logo
        contact_person (str): Primary contact person name
        is_active (bool): Whether agency is active
    """
    
    name = models.CharField(
        max_length=255,
        unique=True,
        help_text="Agency name (must be unique)"
    )
    
    description = models.TextField(
        blank=True,
        null=True,
        help_text="Detailed description of the agency"
    )
    
    email = models.EmailField(
        validators=[EmailValidator()],
        help_text="Primary contact email for the agency"
    )
    
    phone = models.CharField(
        max_length=20,
        blank=True,
        null=True,
        help_text="Primary contact phone number"
    )
    
    website = models.URLField(
        blank=True,
        null=True,
        validators=[URLValidator()],
        help_text="Agency website URL"
    )
    
    address = models.TextField(
        blank=True,
        null=True,
        help_text="Physical address of the agency"
    )
    
    city = models.CharField(
        max_length=100,
        blank=True,
        null=True,
        help_text="City where agency is located"
    )
    
    country = models.CharField(
        max_length=100,
        blank=True,
        null=True,
        help_text="Country where agency is located"
    )
    
    logo = models.ImageField(
        upload_to=agencies_logo_upload_path,
        blank=True,
        null=True,
        help_text="Agency logo image"
    )
    
    contact_person = models.CharField(
        max_length=255,
        blank=True,
        null=True,
        help_text="Primary contact person at the agency"
    )
    
    # Relationships
    owner = models.ForeignKey(
        User,
        on_delete=models.SET_NULL,
        null=True,
        blank=True,
        related_name='owned_agencies',
        help_text="User who owns/manages this agency"
    )
    
    class Meta:
        db_table = 'agencies'
        verbose_name = 'Agency'
        verbose_name_plural = 'Agencies'
        ordering = ['name']
        indexes = [
            models.Index(fields=['name']),
            models.Index(fields=['status']),
            models.Index(fields=['created_at']),
        ]
    
    def __str__(self):
        return self.name
    
    @property
    def total_brands(self):
        """Get total number of brands associated with this agency."""
        return self.brands.filter(status='active').count()
    
    @property
    def total_campaigns(self):
        """Get total number of campaigns for this agency's brands."""
        from apps.campaigns.models import Campaign
        return Campaign.objects.filter(
            advertiser__agency=self,
            status='active'
        ).count()


class BrandCategory(BaseModel):
    """Brand Category model for organizing brands.
    
    Provides categorization for brands to help with organization
    and filtering in the system.
    
    Attributes:
        name (str): Category name
        description (str): Category description
        parent (ForeignKey): Parent category for hierarchical structure
    """
    
    name = models.CharField(
        max_length=100,
        unique=True,
        help_text="Category name (must be unique)"
    )
    
    description = models.TextField(
        blank=True,
        null=True,
        help_text="Description of the category"
    )
    
    parent = models.ForeignKey(
        'self',
        on_delete=models.CASCADE,
        null=True,
        blank=True,
        related_name='subcategories',
        help_text="Parent category for hierarchical organization"
    )
    
    class Meta:
        db_table = 'brand_categories'
        verbose_name = 'Brand Category'
        verbose_name_plural = 'Brand Categories'
        ordering = ['name']
    
    def __str__(self):
        if self.parent:
            return f"{self.parent.name} > {self.name}"
        return self.name


class Brand(BaseModel, AuditModel, StatusModel):
    """Brand/Advertiser model.
    
    Represents brands or advertisers that create advertising campaigns.
    Brands are associated with agencies and can have multiple campaigns.
    
    Attributes:
        name (str): Brand name
        description (str): Brand description
        category (ForeignKey): Brand category
        agency (ForeignKey): Associated agency
        logo (ImageField): Brand logo
        website (str): Brand website
        contact_email (str): Brand contact email
        contact_phone (str): Brand contact phone
        industry (str): Industry sector
        target_audience (str): Primary target audience
        is_active (bool): Whether brand is active
    """
    
    name = models.CharField(
        max_length=255,
        help_text="Brand or advertiser name"
    )
    
    description = models.TextField(
        blank=True,
        null=True,
        help_text="Detailed description of the brand"
    )
    
    # Relationships
    category = models.ForeignKey(
        BrandCategory,
        on_delete=models.SET_NULL,
        null=True,
        blank=True,
        related_name='brands',
        help_text="Brand category for organization"
    )
    
    agency = models.ForeignKey(
        Agency,
        on_delete=models.CASCADE,
        related_name='brands',
        help_text="Agency managing this brand"
    )
    
    # Brand details
    logo = models.ImageField(
        upload_to='brands/logos/',
        blank=True,
        null=True,
        help_text="Brand logo image"
    )
    
    website = models.URLField(
        blank=True,
        null=True,
        validators=[URLValidator()],
        help_text="Brand website URL"
    )
    
    contact_email = models.EmailField(
        blank=True,
        null=True,
        validators=[EmailValidator()],
        help_text="Brand contact email"
    )
    
    contact_phone = models.CharField(
        max_length=20,
        blank=True,
        null=True,
        help_text="Brand contact phone number"
    )
    
    industry = models.CharField(
        max_length=100,
        blank=True,
        null=True,
        help_text="Industry sector (e.g., Automotive, Food & Beverage)"
    )
    
    target_audience = models.TextField(
        blank=True,
        null=True,
        help_text="Description of primary target audience"
    )
    
    # Business information
    annual_budget = models.DecimalField(
        max_digits=12,
        decimal_places=2,
        null=True,
        blank=True,
        help_text="Annual advertising budget"
    )
    
    class Meta:
        db_table = 'brands'
        verbose_name = 'Brand'
        verbose_name_plural = 'Brands'
        ordering = ['name']
        indexes = [
            models.Index(fields=['name']),
            models.Index(fields=['agency']),
            models.Index(fields=['category']),
            models.Index(fields=['status']),
            models.Index(fields=['created_at']),
        ]
        constraints = [
            models.UniqueConstraint(
                fields=['name', 'agency'],
                name='unique_brand_per_agency'
            )
        ]
    
    def __str__(self):
        return f"{self.name} ({self.agency.name})"
    
    @property
    def total_campaigns(self):
        """Get total number of campaigns for this brand."""
        return self.campaigns.filter(status='active').count()
    
    @property
    def active_campaigns(self):
        """Get currently active campaigns for this brand."""
        from apps.campaigns.models import Campaign
        now = timezone.now()
        return self.campaigns.filter(
            status='active',
            start_date__lte=now,
            end_date__gte=now
        )
    
    @property
    def total_budget_spent(self):
        """Calculate total budget spent across all campaigns."""
        from apps.campaigns.models import Campaign
        from django.db.models import Sum
        
        result = self.campaigns.aggregate(
            total=Sum('budget')
        )
        return result['total'] or 0


class UserAdvertiser(BaseModel, AuditModel, StatusModel):
    """User-Advertiser relationship model.
    
    Manages the many-to-many relationship between users and advertisers/brands.
    Allows users to have access to specific brands with different permission levels.
    
    Attributes:
        user (ForeignKey): User account
        brand (ForeignKey): Associated brand
        role (str): User's role for this brand
        permissions (str): Specific permissions
        is_active (bool): Whether relationship is active
    """
    
    ROLE_CHOICES = [
        ('viewer', 'Viewer'),
        ('editor', 'Editor'),
        ('manager', 'Manager'),
        ('admin', 'Administrator'),
    ]
    
    user = models.ForeignKey(
        User,
        on_delete=models.CASCADE,
        related_name='brand_relationships',
        help_text="User account"
    )
    
    brand = models.ForeignKey(
        Brand,
        on_delete=models.CASCADE,
        related_name='user_relationships',
        help_text="Associated brand"
    )
    
    role = models.CharField(
        max_length=20,
        choices=ROLE_CHOICES,
        default='viewer',
        help_text="User's role for this brand"
    )
    
    permissions = models.JSONField(
        default=dict,
        blank=True,
        help_text="Specific permissions for this user-brand relationship"
    )
    
    is_active = models.BooleanField(
        default=True,
        help_text="Whether this relationship is currently active"
    )
    
    class Meta:
        db_table = 'user_advertisers'
        verbose_name = 'User-Advertiser Relationship'
        verbose_name_plural = 'User-Advertiser Relationships'
        ordering = ['user__username', 'brand__name']
        constraints = [
            models.UniqueConstraint(
                fields=['user', 'brand'],
                name='unique_user_brand_relationship'
            )
        ]
    
    def __str__(self):
        return f"{self.user.username} - {self.brand.name} ({self.role})"
    
    def has_permission(self, permission):
        """Check if user has specific permission for this brand."""
        if self.role == 'admin':
            return True
        return permission in self.permissions.get('allowed', [])