"""Advertisers Signals

This module contains Django signal handlers for the advertisers app.
Handles automated tasks and model lifecycle events.

Signals:
    - Agency creation/update signals
    - Brand creation/update signals
    - User-advertiser relationship signals
    - Cleanup and maintenance signals
"""

import logging
from django.db.models.signals import post_save, post_delete, pre_delete
from django.dispatch import receiver
from django.contrib.auth import get_user_model
from django.core.mail import send_mail
from django.conf import settings
from django.utils import timezone

from .models import Agency, Brand, BrandCategory, UserAdvertiser


logger = logging.getLogger(__name__)
User = get_user_model()


# ============================================================================
# Agency Signals
# ============================================================================

@receiver(post_save, sender=Agency)
def agency_post_save(sender, instance, created, **kwargs):
    """Handle agency creation and updates.
    
    Actions performed:
    - Log agency creation/update
    - Send notification emails
    - Create default brand categories if needed
    """
    if created:
        logger.info(f"New agency created: {instance.name} (ID: {instance.id})")
        
        # Send welcome email to agency owner
        if instance.owner and instance.owner.email:
            try:
                send_mail(
                    subject=f"Welcome to Adtlas - Agency '{instance.name}' Created",
                    message=f"""
                    Dear {instance.owner.get_full_name() or instance.owner.username},
                    
                    Your agency '{instance.name}' has been successfully created in Adtlas.
                    
                    You can now start adding brands and managing your advertising campaigns.
                    
                    Best regards,
                    The Adtlas Team
                    """,
                    from_email=settings.DEFAULT_FROM_EMAIL,
                    recipient_list=[instance.owner.email],
                    fail_silently=True,
                )
                logger.info(f"Welcome email sent to {instance.owner.email} for agency {instance.name}")
            except Exception as e:
                logger.error(f"Failed to send welcome email for agency {instance.name}: {str(e)}")
        
        # Create default brand categories if none exist
        if not BrandCategory.objects.exists():
            default_categories = [
                {'name': 'Automotive', 'description': 'Car manufacturers and automotive services'},
                {'name': 'Food & Beverage', 'description': 'Food, drinks, and restaurant chains'},
                {'name': 'Technology', 'description': 'Tech companies and software services'},
                {'name': 'Fashion & Beauty', 'description': 'Clothing, cosmetics, and lifestyle brands'},
                {'name': 'Healthcare', 'description': 'Medical services and pharmaceutical companies'},
                {'name': 'Finance', 'description': 'Banks, insurance, and financial services'},
                {'name': 'Entertainment', 'description': 'Media, gaming, and entertainment companies'},
                {'name': 'Retail', 'description': 'Retail stores and e-commerce platforms'},
            ]
            
            for category_data in default_categories:
                BrandCategory.objects.get_or_create(**category_data)
            
            logger.info("Default brand categories created")
    
    else:
        logger.info(f"Agency updated: {instance.name} (ID: {instance.id})")


@receiver(pre_delete, sender=Agency)
def agency_pre_delete(sender, instance, **kwargs):
    """Handle agency deletion.
    
    Actions performed:
    - Log agency deletion
    - Archive related data instead of hard delete
    """
    logger.warning(f"Agency being deleted: {instance.name} (ID: {instance.id})")
    
    # Mark all brands as inactive instead of deleting
    instance.brands.update(status='inactive')
    
    # Deactivate user relationships
    UserAdvertiser.objects.filter(brand__agency=instance).update(is_active=False)


# ============================================================================
# Brand Signals
# ============================================================================

@receiver(post_save, sender=Brand)
def brand_post_save(sender, instance, created, **kwargs):
    """Handle brand creation and updates.
    
    Actions performed:
    - Log brand creation/update
    - Update agency statistics
    - Send notifications
    """
    if created:
        logger.info(f"New brand created: {instance.name} for agency {instance.agency.name} (ID: {instance.id})")
        
        # Send notification to agency owner
        if instance.agency.owner and instance.agency.owner.email:
            try:
                send_mail(
                    subject=f"New Brand Added - {instance.name}",
                    message=f"""
                    Dear {instance.agency.owner.get_full_name() or instance.agency.owner.username},
                    
                    A new brand '{instance.name}' has been added to your agency '{instance.agency.name}'.
                    
                    Brand Details:
                    - Name: {instance.name}
                    - Industry: {instance.industry or 'Not specified'}
                    - Category: {instance.category.name if instance.category else 'Not specified'}
                    
                    You can now start creating campaigns for this brand.
                    
                    Best regards,
                    The Adtlas Team
                    """,
                    from_email=settings.DEFAULT_FROM_EMAIL,
                    recipient_list=[instance.agency.owner.email],
                    fail_silently=True,
                )
                logger.info(f"Brand creation notification sent for {instance.name}")
            except Exception as e:
                logger.error(f"Failed to send brand creation notification: {str(e)}")
    
    else:
        logger.info(f"Brand updated: {instance.name} (ID: {instance.id})")


@receiver(pre_delete, sender=Brand)
def brand_pre_delete(sender, instance, **kwargs):
    """Handle brand deletion.
    
    Actions performed:
    - Log brand deletion
    - Archive related campaigns
    """
    logger.warning(f"Brand being deleted: {instance.name} (ID: {instance.id})")
    
    # Deactivate user relationships
    instance.user_relationships.update(is_active=False)
    
    # Mark campaigns as inactive (if campaigns app exists)
    try:
        instance.campaigns.update(status='inactive')
        logger.info(f"Campaigns for brand {instance.name} marked as inactive")
    except Exception as e:
        logger.warning(f"Could not update campaigns for brand {instance.name}: {str(e)}")


# ============================================================================
# User-Advertiser Relationship Signals
# ============================================================================

@receiver(post_save, sender=UserAdvertiser)
def user_advertiser_post_save(sender, instance, created, **kwargs):
    """Handle user-advertiser relationship creation and updates.
    
    Actions performed:
    - Log relationship changes
    - Send access notifications
    - Update user permissions
    """
    if created:
        logger.info(
            f"New user-advertiser relationship: {instance.user.username} -> "
            f"{instance.brand.name} ({instance.role})"
        )
        
        # Send access notification to user
        if instance.user.email:
            try:
                send_mail(
                    subject=f"Brand Access Granted - {instance.brand.name}",
                    message=f"""
                    Dear {instance.user.get_full_name() or instance.user.username},
                    
                    You have been granted {instance.role} access to the brand '{instance.brand.name}' 
                    under agency '{instance.brand.agency.name}'.
                    
                    You can now access this brand's campaigns and data according to your role permissions.
                    
                    Best regards,
                    The Adtlas Team
                    """,
                    from_email=settings.DEFAULT_FROM_EMAIL,
                    recipient_list=[instance.user.email],
                    fail_silently=True,
                )
                logger.info(f"Access notification sent to {instance.user.email}")
            except Exception as e:
                logger.error(f"Failed to send access notification: {str(e)}")
        
        # Send notification to agency owner
        if instance.brand.agency.owner and instance.brand.agency.owner.email:
            try:
                send_mail(
                    subject=f"User Access Granted - {instance.brand.name}",
                    message=f"""
                    Dear {instance.brand.agency.owner.get_full_name() or instance.brand.agency.owner.username},
                    
                    User '{instance.user.get_full_name() or instance.user.username}' has been granted 
                    {instance.role} access to brand '{instance.brand.name}'.
                    
                    User Details:
                    - Name: {instance.user.get_full_name() or instance.user.username}
                    - Email: {instance.user.email}
                    - Role: {instance.role}
                    
                    Best regards,
                    The Adtlas Team
                    """,
                    from_email=settings.DEFAULT_FROM_EMAIL,
                    recipient_list=[instance.brand.agency.owner.email],
                    fail_silently=True,
                )
            except Exception as e:
                logger.error(f"Failed to send owner notification: {str(e)}")
    
    else:
        logger.info(
            f"User-advertiser relationship updated: {instance.user.username} -> "
            f"{instance.brand.name} ({instance.role}, active: {instance.is_active})"
        )


@receiver(post_delete, sender=UserAdvertiser)
def user_advertiser_post_delete(sender, instance, **kwargs):
    """Handle user-advertiser relationship deletion.
    
    Actions performed:
    - Log relationship removal
    - Send access revocation notifications
    """
    logger.info(
        f"User-advertiser relationship deleted: {instance.user.username} -> "
        f"{instance.brand.name}"
    )
    
    # Send access revocation notification to user
    if instance.user.email:
        try:
            send_mail(
                subject=f"Brand Access Revoked - {instance.brand.name}",
                message=f"""
                Dear {instance.user.get_full_name() or instance.user.username},
                
                Your access to brand '{instance.brand.name}' under agency '{instance.brand.agency.name}' 
                has been revoked.
                
                If you believe this is an error, please contact your administrator.
                
                Best regards,
                The Adtlas Team
                """,
                from_email=settings.DEFAULT_FROM_EMAIL,
                recipient_list=[instance.user.email],
                fail_silently=True,
            )
            logger.info(f"Access revocation notification sent to {instance.user.email}")
        except Exception as e:
            logger.error(f"Failed to send access revocation notification: {str(e)}")


# ============================================================================
# Brand Category Signals
# ============================================================================

@receiver(post_save, sender=BrandCategory)
def brand_category_post_save(sender, instance, created, **kwargs):
    """Handle brand category creation and updates.
    
    Actions performed:
    - Log category changes
    - Validate hierarchy
    """
    if created:
        logger.info(f"New brand category created: {instance.name} (ID: {instance.id})")
    else:
        logger.info(f"Brand category updated: {instance.name} (ID: {instance.id})")
    
    # Validate category hierarchy (prevent circular references)
    if instance.parent:
        current = instance.parent
        visited = {instance.id}
        
        while current:
            if current.id in visited:
                logger.error(f"Circular reference detected in category hierarchy for {instance.name}")
                # You might want to raise an exception or fix the hierarchy here
                break
            visited.add(current.id)
            current = current.parent


# ============================================================================
# Cleanup and Maintenance Signals
# ============================================================================

@receiver(post_delete, sender=User)
def user_post_delete(sender, instance, **kwargs):
    """Handle user deletion cleanup.
    
    Actions performed:
    - Clean up orphaned agencies
    - Deactivate user-advertiser relationships
    """
    logger.info(f"User deleted: {instance.username} (ID: {instance.id})")
    
    # Handle agencies owned by deleted user
    orphaned_agencies = Agency.objects.filter(owner=instance)
    if orphaned_agencies.exists():
        logger.warning(f"Found {orphaned_agencies.count()} orphaned agencies for deleted user {instance.username}")
        
        # You might want to:
        # 1. Transfer ownership to another user
        # 2. Mark agencies as inactive
        # 3. Delete agencies (be careful!)
        
        # For now, we'll mark them as inactive
        orphaned_agencies.update(status='inactive', owner=None)
        logger.info(f"Marked {orphaned_agencies.count()} agencies as inactive due to owner deletion")


# ============================================================================
# Utility Functions for Signals
# ============================================================================

def send_bulk_notification(subject, message, recipient_list):
    """Send bulk email notifications with error handling.
    
    Args:
        subject (str): Email subject
        message (str): Email message
        recipient_list (list): List of email addresses
    
    Returns:
        int: Number of successfully sent emails
    """
    sent_count = 0
    
    for email in recipient_list:
        try:
            send_mail(
                subject=subject,
                message=message,
                from_email=settings.DEFAULT_FROM_EMAIL,
                recipient_list=[email],
                fail_silently=False,
            )
            sent_count += 1
        except Exception as e:
            logger.error(f"Failed to send email to {email}: {str(e)}")
    
    return sent_count


def log_model_change(instance, action, user=None):
    """Log model changes for audit purposes.
    
    Args:
        instance: Model instance
        action (str): Action performed (created, updated, deleted)
        user: User who performed the action (optional)
    """
    model_name = instance.__class__.__name__
    instance_id = getattr(instance, 'id', 'unknown')
    user_info = f" by {user.username}" if user else ""
    
    logger.info(
        f"{model_name} {action}: {instance} (ID: {instance_id}){user_info} at {timezone.now()}"
    )