from django.db import models
from django.db.models import Q


class Product(models.Model):
    """Product synced from Shopify to Digistore."""
    shopify_product_id = models.CharField(max_length=64, unique=True, db_index=True)
    digistore_product_id = models.CharField(max_length=64, blank=True)
    digistore_paymentplan_id = models.CharField(
        max_length=64,
        blank=True,
        default="",
        help_text="Canonical Digistore single-payment plan id; avoids duplicate creates when listPaymentPlans fails.",
    )
    shopify_variant_id = models.CharField(max_length=64, blank=True)
    title = models.CharField(max_length=512, blank=True)
    raw_payload = models.JSONField(null=True, blank=True)
    sync_error = models.TextField(blank=True, default="")
    is_volume_pricing_enabled = models.BooleanField(default=False)
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)

    def __str__(self):
        return self.title or self.shopify_product_id

class PricingRule(models.Model):
    """Volume pricing rules per product"""

    product = models.ForeignKey(Product, on_delete=models.CASCADE, related_name="pricing_rules")

    quantity = models.PositiveIntegerField()
    unit_price = models.DecimalField(max_digits=10, decimal_places=2)

    is_active = models.BooleanField(default=True)
    is_default = models.BooleanField(default=False)

    class Meta:
        ordering = ["quantity"]
        constraints = [
            models.UniqueConstraint(
                fields=["product"],
                condition=Q(is_default=True),
                name="unique_default_pricing_rule_per_product",
            )
        ]

    def save(self, *args, **kwargs):
        if self.is_default and self.product_id:
            # Clear previous default before saving this row to avoid
            # violating the unique partial index during admin form saves.
            qs = self.__class__.objects.filter(
                product_id=self.product_id,
                is_default=True,
            )
            if self.pk:
                qs = qs.exclude(pk=self.pk)
            qs.update(is_default=False)

        super().save(*args, **kwargs)

    def __str__(self):
        return f"{self.product} → {self.quantity} @ {self.unit_price}"