"""
Media models for ThrillWiki Django backend.

This module contains models for handling media content:
- Photo: CloudFlare Images integration with generic relations
"""
from django.db import models
from django.contrib.contenttypes.fields import GenericForeignKey
from django.contrib.contenttypes.models import ContentType
from django_lifecycle import hook, AFTER_CREATE, AFTER_UPDATE, BEFORE_SAVE

from apps.core.models import BaseModel


class Photo(BaseModel):
    """
    Represents a photo stored in CloudFlare Images.
    Uses generic relations to attach to any entity (Park, Ride, Company, etc.)
    """
    
    PHOTO_TYPE_CHOICES = [
        ('main', 'Main Photo'),
        ('gallery', 'Gallery Photo'),
        ('banner', 'Banner Image'),
        ('logo', 'Logo'),
        ('thumbnail', 'Thumbnail'),
        ('other', 'Other'),
    ]
    
    MODERATION_STATUS_CHOICES = [
        ('pending', 'Pending Review'),
        ('approved', 'Approved'),
        ('rejected', 'Rejected'),
        ('flagged', 'Flagged'),
    ]
    
    # CloudFlare Image Integration
    cloudflare_image_id = models.CharField(
        max_length=255,
        unique=True,
        db_index=True,
        help_text="Unique CloudFlare image identifier"
    )
    cloudflare_url = models.URLField(
        help_text="CloudFlare CDN URL for the image"
    )
    cloudflare_thumbnail_url = models.URLField(
        blank=True,
        help_text="CloudFlare thumbnail URL (if different from main URL)"
    )
    
    # Metadata
    title = models.CharField(
        max_length=255,
        blank=True,
        help_text="Photo title or caption"
    )
    description = models.TextField(
        blank=True,
        help_text="Photo description or details"
    )
    credit = models.CharField(
        max_length=255,
        blank=True,
        help_text="Photo credit/photographer name"
    )
    
    # Photo Type
    photo_type = models.CharField(
        max_length=50,
        choices=PHOTO_TYPE_CHOICES,
        default='gallery',
        db_index=True,
        help_text="Type of photo"
    )
    
    # Generic relation to attach to any entity
    content_type = models.ForeignKey(
        ContentType,
        on_delete=models.CASCADE,
        help_text="Type of entity this photo belongs to"
    )
    object_id = models.UUIDField(
        db_index=True,
        help_text="ID of the entity this photo belongs to"
    )
    content_object = GenericForeignKey('content_type', 'object_id')
    
    # User who uploaded
    uploaded_by = models.ForeignKey(
        'users.User',
        on_delete=models.SET_NULL,
        null=True,
        blank=True,
        related_name='uploaded_photos',
        help_text="User who uploaded this photo"
    )
    
    # Moderation
    moderation_status = models.CharField(
        max_length=50,
        choices=MODERATION_STATUS_CHOICES,
        default='pending',
        db_index=True,
        help_text="Moderation status"
    )
    is_approved = models.BooleanField(
        default=False,
        db_index=True,
        help_text="Quick filter for approved photos"
    )
    moderated_by = models.ForeignKey(
        'users.User',
        on_delete=models.SET_NULL,
        null=True,
        blank=True,
        related_name='moderated_photos',
        help_text="Moderator who approved/rejected this photo"
    )
    moderated_at = models.DateTimeField(
        null=True,
        blank=True,
        help_text="When the photo was moderated"
    )
    moderation_notes = models.TextField(
        blank=True,
        help_text="Notes from moderator"
    )
    
    # Image Metadata
    width = models.IntegerField(
        null=True,
        blank=True,
        help_text="Image width in pixels"
    )
    height = models.IntegerField(
        null=True,
        blank=True,
        help_text="Image height in pixels"
    )
    file_size = models.IntegerField(
        null=True,
        blank=True,
        help_text="File size in bytes"
    )
    
    # Display Order
    display_order = models.IntegerField(
        default=0,
        db_index=True,
        help_text="Order for displaying in galleries (lower numbers first)"
    )
    
    # Visibility
    is_featured = models.BooleanField(
        default=False,
        db_index=True,
        help_text="Is this a featured photo?"
    )
    is_public = models.BooleanField(
        default=True,
        db_index=True,
        help_text="Is this photo publicly visible?"
    )
    
    class Meta:
        verbose_name = 'Photo'
        verbose_name_plural = 'Photos'
        ordering = ['display_order', '-created']
        indexes = [
            models.Index(fields=['content_type', 'object_id']),
            models.Index(fields=['cloudflare_image_id']),
            models.Index(fields=['moderation_status']),
            models.Index(fields=['is_approved']),
            models.Index(fields=['uploaded_by']),
            models.Index(fields=['photo_type']),
            models.Index(fields=['display_order']),
        ]
    
    def __str__(self):
        if self.title:
            return self.title
        return f"Photo {self.cloudflare_image_id[:8]}..."
    
    @hook(AFTER_UPDATE, when='moderation_status', was='pending', is_now='approved')
    def set_approved_flag_on_approval(self):
        """Set is_approved flag when status changes to approved."""
        self.is_approved = True
        self.save(update_fields=['is_approved'])
    
    @hook(AFTER_UPDATE, when='moderation_status', was='approved', is_not='approved')
    def clear_approved_flag_on_rejection(self):
        """Clear is_approved flag when status changes from approved."""
        self.is_approved = False
        self.save(update_fields=['is_approved'])
    
    def approve(self, moderator, notes=''):
        """Approve this photo."""
        from django.utils import timezone
        
        self.moderation_status = 'approved'
        self.is_approved = True
        self.moderated_by = moderator
        self.moderated_at = timezone.now()
        self.moderation_notes = notes
        self.save(update_fields=[
            'moderation_status',
            'is_approved',
            'moderated_by',
            'moderated_at',
            'moderation_notes'
        ])
    
    def reject(self, moderator, notes=''):
        """Reject this photo."""
        from django.utils import timezone
        
        self.moderation_status = 'rejected'
        self.is_approved = False
        self.moderated_by = moderator
        self.moderated_at = timezone.now()
        self.moderation_notes = notes
        self.save(update_fields=[
            'moderation_status',
            'is_approved',
            'moderated_by',
            'moderated_at',
            'moderation_notes'
        ])
    
    def flag(self, moderator, notes=''):
        """Flag this photo for review."""
        from django.utils import timezone
        
        self.moderation_status = 'flagged'
        self.is_approved = False
        self.moderated_by = moderator
        self.moderated_at = timezone.now()
        self.moderation_notes = notes
        self.save(update_fields=[
            'moderation_status',
            'is_approved',
            'moderated_by',
            'moderated_at',
            'moderation_notes'
        ])


class PhotoManager(models.Manager):
    """Custom manager for Photo model."""
    
    def approved(self):
        """Return only approved photos."""
        return self.filter(is_approved=True)
    
    def pending(self):
        """Return only pending photos."""
        return self.filter(moderation_status='pending')
    
    def public(self):
        """Return only public, approved photos."""
        return self.filter(is_approved=True, is_public=True)


# Add custom manager to Photo model
Photo.add_to_class('objects', PhotoManager())
