import uuid
from django.db import models
from django.utils import timezone
from django.utils.text import slugify
from businesses.models import Business
from products.models import Product
from payments.models import Payment
from core.models import TimeStampedModel


class Sale(TimeStampedModel):
    """
    A time-windowed flash sale belonging to a Business. Gets a permanent public URL.
    Status transitions are managed by a background task (upcoming -> live -> ended).
    """
    STATUS_CHOICES = [
        ('draft', 'Draft'),
        ('upcoming', 'Upcoming'),
        ('live', 'Live'),
        ('ended', 'Ended'),
    ]

    PRICING_MODEL_CHOICES = [
        ('daily_rate', 'Daily Rate'),
        ('commission', 'Commission (5% After Sale)'),
    ]

    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    business = models.ForeignKey(
        Business, on_delete=models.CASCADE, related_name='sales'
    )
    title = models.CharField(max_length=300, blank=True)
    slug = models.SlugField(max_length=320, unique=True)
    start_at = models.DateTimeField(help_text='Server-authoritative start time (UTC).')
    end_at = models.DateTimeField(help_text='Server-authoritative end time (UTC).')
    status = models.CharField(max_length=20, choices=STATUS_CHOICES, default='draft')
    pricing_model = models.CharField(
        max_length=20, choices=PRICING_MODEL_CHOICES, default='daily_rate',
        help_text='How the booking fee was calculated.'
    )
    booking_fee_amount = models.DecimalField(
        max_digits=10, decimal_places=2, default=0,
        help_text='Snapshot of price paid at booking time.'
    )
    booking_payment = models.ForeignKey(
        Payment, on_delete=models.SET_NULL, null=True, blank=True,
        related_name='booked_sale'
    )
    view_count = models.PositiveIntegerField(default=0)

    class Meta:
        ordering = ['-start_at']

    def __str__(self):
        return f"{self.title or self.business.name} ({self.get_status_display()})"

    def save(self, *args, **kwargs):
        if not self.slug:
            base = slugify(self.title or self.business.name)
            slug = base
            counter = 1
            while Sale.objects.filter(slug=slug).exists():
                slug = f"{base}-{counter}"
                counter += 1
            self.slug = slug
        super().save(*args, **kwargs)

    @property
    def is_upcoming(self):
        return self.status == 'upcoming'

    @property
    def is_live(self):
        return self.status == 'live'

    @property
    def is_ended(self):
        return self.status == 'ended'

    @property
    def duration_days(self):
        delta = self.end_at - self.start_at
        return max(delta.days, 1)

    def check_and_transition(self):
        """Check if the sale status should transition based on current time."""
        now = timezone.now()
        if self.status in ['upcoming', 'live']:
            if self.end_at <= now:
                if self.status != 'ended':
                    self.status = 'ended'
                    self.save(update_fields=['status', 'updated_at'])
                return 'ended'
            elif self.start_at <= now:
                if self.status != 'live':
                    self.status = 'live'
                    self.save(update_fields=['status', 'updated_at'])
                return 'live'
        return self.status

    @classmethod
    def update_all_statuses(cls):
        """Update statuses of all sales dynamically based on server timestamp."""
        now = timezone.now()
        cls.objects.filter(status__in=['upcoming', 'live'], end_at__lte=now).update(status='ended', updated_at=now)
        cls.objects.filter(status='upcoming', start_at__lte=now, end_at__gt=now).update(status='live', updated_at=now)



class SaleItem(TimeStampedModel):
    """
    A Product selected into a specific Sale, with sale-scoped price, discount,
    and stock. Stock is NEVER shared across sales -- each SaleItem is an
    independent inventory pool.
    """
    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    sale = models.ForeignKey(
        Sale, on_delete=models.CASCADE, related_name='items'
    )
    product = models.ForeignKey(
        Product, on_delete=models.CASCADE, related_name='sale_items'
    )
    price = models.DecimalField(
        max_digits=10, decimal_places=2,
        help_text='Actual selling price for this sale, independent of product.base_price.'
    )
    discount_percent = models.DecimalField(
        max_digits=5, decimal_places=2, null=True, blank=True,
        help_text='Displayed as strikethrough vs price. No coupon code layer.'
    )
    stock_total = models.PositiveIntegerField(
        help_text='Set by seller at sale-creation time.'
    )
    stock_remaining = models.PositiveIntegerField(
        help_text='Decremented atomically on order confirmation.'
    )

    class Meta:
        ordering = ['created_at']
        unique_together = ['sale', 'product']

    def __str__(self):
        return f"{self.product.name} in {self.sale}"

    @property
    def original_price(self):
        """Price before discount, for strikethrough display."""
        if self.discount_percent:
            return round(self.price / (1 - self.discount_percent / 100), 2)
        return self.price

    @property
    def is_sold_out(self):
        return self.stock_remaining <= 0

    @property
    def stock_percentage(self):
        if self.stock_total == 0:
            return 0
        return round((self.stock_remaining / self.stock_total) * 100)

    def save(self, *args, **kwargs):
        if self.stock_remaining is None:
            self.stock_remaining = self.stock_total
        super().save(*args, **kwargs)
