import uuid
import os
from io import BytesIO
from PIL import Image
from django.core.files.base import ContentFile
from django.db import models
from businesses.models import Business
from core.models import TimeStampedModel


class Product(TimeStampedModel):
    """
    A catalog product owned by a Business. Persists indefinitely and is reusable
    across any number of Sales. Has NO stock -- stock only exists on SaleItem.
    """
    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    business = models.ForeignKey(
        Business, on_delete=models.CASCADE, related_name='products'
    )
    name = models.CharField(max_length=300)
    description = models.TextField(blank=True)
    base_price = models.DecimalField(
        max_digits=10, decimal_places=2,
        help_text='Reference price only. Each SaleItem sets its own actual price.'
    )
    video = models.FileField(
        upload_to='products/videos/', blank=True, null=True,
        help_text='Product video demonstration (MP4, WebM).'
    )
    is_active = models.BooleanField(
        default=True,
        help_text='Soft-delete flag. Hides from sale picker without deleting sale history.'
    )

    class Meta:
        ordering = ['-created_at']

    def __str__(self):
        return self.name

    @property
    def primary_image(self):
        img = self.images.first()
        return img if img else None


class ProductImage(TimeStampedModel):
    """
    Image associated with a Product. Up to 3 per product.
    Automatically compresses images on save for fast mobile loading.
    """
    PROCESSING_STATUS_CHOICES = [
        ('pending', 'Pending'),
        ('processing', 'Processing'),
        ('done', 'Done'),
        ('failed', 'Failed'),
    ]

    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    product = models.ForeignKey(
        Product, on_delete=models.CASCADE, related_name='images'
    )
    image = models.ImageField(upload_to='products/originals/')
    thumbnail = models.ImageField(upload_to='products/thumbnails/', blank=True, null=True)
    medium = models.ImageField(upload_to='products/medium/', blank=True, null=True)
    large = models.ImageField(upload_to='products/large/', blank=True, null=True)
    webp = models.ImageField(upload_to='products/webp/', blank=True, null=True)
    order = models.PositiveIntegerField(default=0)
    processing_status = models.CharField(
        max_length=20, choices=PROCESSING_STATUS_CHOICES, default='pending'
    )

    class Meta:
        ordering = ['order', 'created_at']

    def __str__(self):
        return f"Image for {self.product.name} (#{self.order})"

    def compress_image(self):
        """Compress uploaded image and generate webp & thumbnail inline."""
        if not self.image or self.processing_status == 'done':
            return

        try:
            img = Image.open(self.image)
            if img.mode in ('RGBA', 'P'):
                img = img.convert('RGB')

            base_filename = os.path.splitext(os.path.basename(self.image.name))[0]

            # 1. Medium / Compressed JPG (max 800px)
            med = img.copy()
            med.thumbnail((800, 800), Image.LANCZOS)
            med_io = BytesIO()
            med.save(med_io, format='JPEG', quality=80, optimize=True)
            self.medium.save(f"med_{base_filename}.jpg", ContentFile(med_io.getvalue()), save=False)

            # 2. Thumbnail (max 300px)
            thumb = img.copy()
            thumb.thumbnail((300, 300), Image.LANCZOS)
            thumb_io = BytesIO()
            thumb.save(thumb_io, format='JPEG', quality=75, optimize=True)
            self.thumbnail.save(f"thumb_{base_filename}.jpg", ContentFile(thumb_io.getvalue()), save=False)

            # 3. WebP (max 800px)
            webp = img.copy()
            webp.thumbnail((800, 800), Image.LANCZOS)
            webp_io = BytesIO()
            webp.save(webp_io, format='WEBP', quality=80)
            self.webp.save(f"{base_filename}.webp", ContentFile(webp_io.getvalue()), save=False)

            self.processing_status = 'done'
        except Exception as e:
            self.processing_status = 'failed'
            print(f"Image compression error: {e}")

    def save(self, *args, **kwargs):
        is_new = self._state.adding
        super().save(*args, **kwargs)
        if is_new and self.image and self.processing_status == 'pending':
            self.compress_image()
            super().save(update_fields=['thumbnail', 'medium', 'webp', 'processing_status'])
