from django.conf import settings
from django.db import models
from django.utils import timezone
from django.utils.text import slugify


class Vendor(models.Model):
    """
    A vendor / seller who registers on the ACA SaaS platform.
    Each vendor has one store and can add products directly.
    """

    user = models.OneToOneField(
        settings.AUTH_USER_MODEL,
        on_delete=models.CASCADE,
        related_name="vendor_profile",
    )
    store_name = models.CharField(max_length=200)
    store_slug = models.SlugField(max_length=200, unique=True)
    description = models.TextField(blank=True, default="")
    logo_url = models.URLField(blank=True, default="")
    phone = models.CharField(max_length=30, blank=True, default="")
    address = models.TextField(blank=True, default="")
    delivery_fee = models.DecimalField(max_digits=10, decimal_places=2, default=0)
    free_delivery_threshold = models.DecimalField(
        max_digits=10, decimal_places=2, null=True, blank=True
    )
    is_approved = models.BooleanField(default=True)
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)

    class Meta:
        ordering = ["-created_at"]

    def __str__(self):
        return self.store_name

    def save(self, *args, **kwargs):
        if not self.store_slug:
            self.store_slug = slugify(self.store_name)
        super().save(*args, **kwargs)

    @property
    def subscription_is_active(self) -> bool:
        """Returns True if the vendor has a valid active/free subscription."""
        try:
            sub = self.subscription
        except VendorSubscription.DoesNotExist:
            return False
        return sub.is_active

    @property
    def subscription_expires_at(self):
        try:
            return self.subscription.expires_at
        except VendorSubscription.DoesNotExist:
            return None


def product_image_upload_path(instance, filename):
    """Upload images to media/products/<vendor_slug>/<filename>."""
    return f"products/{instance.product.vendor.store_slug}/{filename}"


class VendorProduct(models.Model):
    """
    A product added by a vendor directly on the ACA platform.
    These are searchable by the AI and can be added to the unified cart.
    """

    vendor = models.ForeignKey(
        Vendor, on_delete=models.CASCADE, related_name="products"
    )
    name = models.CharField(max_length=300)
    description = models.TextField(blank=True, default="")
    price = models.DecimalField(max_digits=10, decimal_places=2)
    currency = models.CharField(max_length=10, default="GHS")
    image_url = models.URLField(blank=True, default="")  # legacy / fallback
    category = models.CharField(max_length=100, blank=True, default="")
    brand = models.CharField(max_length=100, blank=True, default="")
    quantity = models.PositiveIntegerField(default=0, help_text="Available stock quantity")
    in_stock = models.BooleanField(default=True)
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)

    class Meta:
        ordering = ["-created_at"]

    def __str__(self):
        return f"{self.name} ({self.vendor.store_name})"

    def save(self, *args, **kwargs):
        # Auto-set in_stock based on quantity
        self.in_stock = self.quantity > 0
        super().save(*args, **kwargs)

    def reduce_stock(self, amount: int = 1):
        """Reduce stock by amount and update in_stock flag."""
        self.quantity = max(0, self.quantity - amount)
        self.in_stock = self.quantity > 0
        self.save(update_fields=["quantity", "in_stock", "updated_at"])

    @property
    def primary_image_url(self):
        """Return the URL of the first uploaded image, or fall back to image_url."""
        first = self.images.first()
        if first and first.image:
            return first.image.url
        return self.image_url or ""

    @property
    def all_image_urls(self):
        """Return a list of all image URLs for this product."""
        urls = [img.image.url for img in self.images.all() if img.image]
        if not urls and self.image_url:
            urls = [self.image_url]
        return urls


class ProductImage(models.Model):
    """
    An image attached to a VendorProduct. Supports multiple images per product.
    """

    product = models.ForeignKey(
        VendorProduct, on_delete=models.CASCADE, related_name="images"
    )
    image = models.ImageField(upload_to=product_image_upload_path)
    alt_text = models.CharField(max_length=200, blank=True, default="")
    position = models.PositiveIntegerField(default=0, help_text="Display order (0 = primary)")
    created_at = models.DateTimeField(auto_now_add=True)

    class Meta:
        ordering = ["position", "created_at"]

    def __str__(self):
        return f"Image {self.position} for {self.product.name}"


class VendorSubscription(models.Model):
    """
    Tracks the subscription status for a vendor.
    Created at registration — either paid (via Paystack) or free (admin toggle).
    """

    STATUS_PENDING = "pending_payment"
    STATUS_ACTIVE = "active"
    STATUS_EXPIRED = "expired"
    STATUS_FREE = "free"

    STATUS_CHOICES = [
        (STATUS_PENDING, "Pending Payment"),
        (STATUS_ACTIVE, "Active"),
        (STATUS_EXPIRED, "Expired"),
        (STATUS_FREE, "Free"),
    ]

    vendor = models.OneToOneField(
        Vendor,
        on_delete=models.CASCADE,
        related_name="subscription",
    )
    status = models.CharField(
        max_length=20,
        choices=STATUS_CHOICES,
        default=STATUS_PENDING,
        db_index=True,
    )
    amount_paid = models.DecimalField(max_digits=10, decimal_places=2, default=0)
    currency = models.CharField(max_length=10, default="GHS")
    paystack_reference = models.CharField(max_length=200, blank=True, default="", db_index=True)
    activated_at = models.DateTimeField(null=True, blank=True)
    expires_at = models.DateTimeField(null=True, blank=True)
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)

    class Meta:
        ordering = ["-created_at"]
        verbose_name = "Vendor Subscription"
        verbose_name_plural = "Vendor Subscriptions"

    def __str__(self):
        return f"{self.vendor.store_name} — {self.get_status_display()}"

    @property
    def is_active(self) -> bool:
        if self.status in (self.STATUS_ACTIVE, self.STATUS_FREE):
            if self.expires_at and timezone.now() > self.expires_at:
                # Mark expired (lazy)
                VendorSubscription.objects.filter(pk=self.pk).update(status=self.STATUS_EXPIRED)
                return False
            return True
        return False

    @property
    def days_remaining(self):
        if not self.expires_at:
            return None
        delta = self.expires_at - timezone.now()
        return max(0, delta.days)
