# catalog/models.py
from django.db import models
from django.utils.text import slugify


# -------- Categories & Products --------
class Category(models.Model):
    name = models.CharField("نام دسته", max_length=120, unique=True)
    slug = models.SlugField("نامک", max_length=140, unique=True, blank=True)
    description = models.TextField("توضیحات", blank=True)
    parent = models.ForeignKey(
        "self", null=True, blank=True, on_delete=models.SET_NULL, related_name="children"
    )

    class Meta:
        verbose_name = "دسته بندی"
        verbose_name_plural = "دسته بندی‌ها"
        ordering = ["name"]

    def save(self, *args, **kwargs):
        if not self.slug:
            self.slug = slugify(self.name, allow_unicode=True)
        super().save(*args, **kwargs)

    def __str__(self) -> str:
        return self.name


class Product(models.Model):
    title = models.CharField("عنوان", max_length=200)
    slug = models.SlugField("نامک", max_length=220, unique=True, blank=True)
    description = models.TextField("توضیحات", blank=True)
    price = models.DecimalField("قیمت", max_digits=12, decimal_places=2)
    unit = models.CharField("واحد", max_length=50, default="عدد")
    weight_grams = models.PositiveIntegerField("وزن (گرم)", default=0)
    category = models.ForeignKey(
        Category, on_delete=models.PROTECT, related_name="products", verbose_name="دسته"
    )
    in_stock = models.BooleanField("موجود", default=True)
    stock_qty = models.PositiveIntegerField("تعداد موجود", default=100)
    rating = models.FloatField("امتیاز", default=0.0)
    reviews_count = models.PositiveIntegerField("تعداد نظرات", default=0)
    tags = models.CharField("تگ‌ها (با , جدا شود)", max_length=300, blank=True)
    thumbnail = models.ImageField("تصویر شاخص", upload_to="products/", blank=True, null=True)

    class Meta:
        verbose_name = "محصول"
        verbose_name_plural = "محصولات"
        ordering = ["title"]

    def save(self, *args, **kwargs):
        if not self.slug:
            self.slug = slugify(self.title, allow_unicode=True)
        super().save(*args, **kwargs)

    def __str__(self) -> str:
        return self.title


class ProductImage(models.Model):
    product = models.ForeignKey(Product, on_delete=models.CASCADE, related_name="images")
    image = models.ImageField("تصویر", upload_to="products/")
    alt = models.CharField("ALT", max_length=200, blank=True)

    class Meta:
        verbose_name = "تصویر محصول"
        verbose_name_plural = "تصاویر محصول"

    def __str__(self) -> str:
        return f"تصویر {self.product}"


# -------- Site settings & newsletter --------
class SiteSetting(models.Model):
    site_name = models.CharField("Site name", max_length=120, default="MapleMart")
    store_title = models.CharField("Footer store title", max_length=160, default="MapleMart Grocery")

    # Address
    address_line1 = models.CharField("Address line 1", max_length=160, blank=True)
    address_line2 = models.CharField("Address line 2", max_length=160, blank=True)
    city = models.CharField(max_length=80, blank=True)
    region = models.CharField("State/Province", max_length=80, blank=True)
    postal_code = models.CharField(max_length=30, blank=True)
    country = models.CharField(max_length=80, blank=True)

    # Others
    hours_text = models.CharField(
        "Hours", max_length=160, blank=True, help_text="e.g. Mon–Sun 8:00–22:00"
    )
    newsletter_note = models.CharField(
        max_length=200, blank=True, default="We never share your email. Demo only."
    )
    updated_at = models.DateTimeField(auto_now=True)

    class Meta:
        verbose_name = "Site setting"
        verbose_name_plural = "Site settings"

    def __str__(self) -> str:
        return "Site settings"


class NewsletterSubscriber(models.Model):
    email = models.EmailField(unique=True)
    created_at = models.DateTimeField(auto_now_add=True)

    class Meta:
        ordering = ["-created_at"]

    def __str__(self) -> str:
        return self.email


# -------- Blog & contact --------
class BlogPost(models.Model):
    title = models.CharField(max_length=200)
    slug = models.SlugField(max_length=220, unique=True, blank=True)
    excerpt = models.TextField(blank=True)
    content = models.TextField()
    thumbnail = models.ImageField(upload_to="blog/", blank=True, null=True)
    is_published = models.BooleanField(default=True)
    published_at = models.DateTimeField(auto_now_add=True)

    class Meta:
        ordering = ["-published_at"]

    def save(self, *args, **kwargs):
        if not self.slug:
            self.slug = slugify(self.title, allow_unicode=True)
        return super().save(*args, **kwargs)

    def __str__(self) -> str:
        return self.title


class ContactMessage(models.Model):
    name = models.CharField(max_length=120)
    email = models.EmailField()
    message = models.TextField()
    created_at = models.DateTimeField(auto_now_add=True)

    class Meta:
        ordering = ["-created_at"]

    def __str__(self) -> str:
        return f"{self.name} <{self.email}>"
class Order(models.Model):
    STATUS_CHOICES = [
        ("pending", "Pending"),
        ("paid", "Paid"),
        ("canceled", "Canceled"),
    ]

    name = models.CharField(max_length=120)
    email = models.EmailField()
    phone = models.CharField(max_length=30)

    address_line1 = models.CharField(max_length=160)
    address_line2 = models.CharField(max_length=160, blank=True)
    city = models.CharField(max_length=80)
    region = models.CharField(max_length=80)
    postal_code = models.CharField(max_length=30)
    country = models.CharField(max_length=80)

    notes = models.TextField(blank=True)
    total = models.DecimalField(max_digits=12, decimal_places=2, default=0)
    status = models.CharField(max_length=20, choices=STATUS_CHOICES, default="pending")

    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"Order #{self.id} - {self.name}"


class OrderItem(models.Model):
    order = models.ForeignKey(Order, on_delete=models.CASCADE, related_name="items")
    product = models.ForeignKey("Product", on_delete=models.PROTECT)
    title = models.CharField(max_length=200)                  # snapshot
    unit_price = models.DecimalField(max_digits=12, decimal_places=2)
    qty = models.PositiveIntegerField()
    line_total = models.DecimalField(max_digits=12, decimal_places=2)

    def __str__(self):
        return f"{self.title} × {self.qty}"
    
# --- Reviews ---
from django.conf import settings
from django.db.models import Avg, Count
from django.db.models.signals import post_save, post_delete
from django.dispatch import receiver

class ReviewCategory(models.Model):
    name = models.CharField(max_length=80, unique=True)
    slug = models.SlugField(max_length=100, unique=True, blank=True)
    description = models.CharField(max_length=200, blank=True)
    order = models.PositiveIntegerField(default=0)

    class Meta:
        ordering = ["order", "name"]

    def save(self, *args, **kwargs):
        if not self.slug:
            self.slug = slugify(self.name, allow_unicode=True)
        return super().save(*args, **kwargs)

    def __str__(self):
        return self.name


class ProductReview(models.Model):
    STATUS = (
        ("pending", "Pending"),
        ("approved", "Approved"),
        ("rejected", "Rejected"),
    )
    product = models.ForeignKey("Product", on_delete=models.CASCADE, related_name="reviews")
    user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.SET_NULL, null=True, blank=True)
    name = models.CharField(max_length=120, blank=True)   # for guests
    email = models.EmailField(blank=True)                 # for guests
    rating = models.PositiveSmallIntegerField(default=5)  # 1..5
    title = models.CharField(max_length=160, blank=True)
    body = models.TextField()
    categories = models.ManyToManyField(ReviewCategory, blank=True, related_name="reviews")
    status = models.CharField(max_length=10, choices=STATUS, default="pending")
    created_at = models.DateTimeField(auto_now_add=True)

    class Meta:
        indexes = [
            models.Index(fields=["product", "status"]),
            models.Index(fields=["status", "rating"]),
        ]
        ordering = ["-created_at"]

    def display_name(self):
        if self.user and (self.user.get_full_name() or self.user.username):
            return self.user.get_full_name() or self.user.username
        return self.name or "Guest"

    def __str__(self):
        return f"Review #{self.id} on {self.product}"

def _recalc_product_stats(product_id):
    from .models import ProductReview, Product
    agg = ProductReview.objects.filter(product_id=product_id, status="approved") \
                               .aggregate(avg=Avg("rating"), cnt=Count("id"))
    Product.objects.filter(id=product_id).update(
        rating=float(agg["avg"] or 0.0),
        reviews_count=int(agg["cnt"] or 0),
    )

@receiver(post_save, sender=ProductReview)
def _review_saved(sender, instance, **kwargs):
    _recalc_product_stats(instance.product_id)

@receiver(post_delete, sender=ProductReview)
def _review_deleted(sender, instance, **kwargs):
    _recalc_product_stats(instance.product_id)
