import uuid
from decimal import Decimal
from django.db import models
from django.contrib.auth.models import AbstractUser
from django.utils import timezone
from datetime import timedelta
from django.core.exceptions import ValidationError

# ================= USERS =================
class User(AbstractUser):
    ROLE_CHOICES = [
        ("superadmin", "Super Admin"),
        ("admin", "Admin"),
        ("sales", "Sales"),
        ("customer", "Customer"),
    ]

    role = models.CharField(max_length=20, choices=ROLE_CHOICES, default="customer")
    phone = models.CharField(max_length=20, blank=True, null=True)

    def is_admin(self):
        return self.role in ["admin", "superadmin"] or self.is_superuser


# ================= PRODUCTS =================
class Product(models.Model):
    STYLE_CHOICES = [
        ("short_sleeve", "Short Sleeve"),
        ("full_sleeve", "Full Sleeve"),
        ("sleeveless", "Sleeveless"),
    ]

    name = models.CharField(max_length=150)
    description = models.TextField()
    price = models.DecimalField(max_digits=10, decimal_places=2)

    quantity = models.PositiveIntegerField(default=0)
    color = models.CharField(max_length=100)
    sizes = models.JSONField(default=list, blank=True)

    style = models.CharField(max_length=20, choices=STYLE_CHOICES, default="short_sleeve")

    created_at = models.DateTimeField(auto_now_add=True)
    is_active = models.BooleanField(default=True)

    def is_sold_out(self):
        return self.quantity == 0

    def __str__(self):
        return f"{self.name} ({self.get_style_display()})"


class ProductImage(models.Model):
    product = models.ForeignKey(Product, related_name="images", on_delete=models.CASCADE)
    image = models.ImageField(upload_to="products/")

    def __str__(self):
        return f"Image for {self.product.name}"


# ================= CART =================
class Cart(models.Model):
    user = models.OneToOneField(User, on_delete=models.CASCADE)
    created_at = models.DateTimeField(auto_now_add=True)

    def __str__(self):
        return f"{self.user.username}'s Cart"


class CartItem(models.Model):
    cart = models.ForeignKey(Cart, related_name="items", on_delete=models.CASCADE)
    product = models.ForeignKey(Product, on_delete=models.CASCADE)
    quantity = models.PositiveIntegerField(default=1)

    size = models.CharField(max_length=20, blank=True, null=True)
    color = models.CharField(max_length=20, blank=True, null=True)

    def subtotal(self):
        return self.product.price * self.quantity


# ================= ORDERS =================
class Order(models.Model):
    STATUS_CHOICES = (
        ('pending', 'Pending'),
        ('approved', 'Approved'),
        ('rejected', 'Rejected'),
        ('delivered', 'Delivered'),
    )

    user = models.ForeignKey(User, on_delete=models.CASCADE)
    status = models.CharField(max_length=20, choices=STATUS_CHOICES, default='pending')

    payment_screenshot = models.ImageField(upload_to='payments/')

    total_price = models.DecimalField(max_digits=10, decimal_places=2, default=0)
    discount = models.DecimalField(max_digits=10, decimal_places=2, default=0)  # ✅ new field
    paid_amount = models.DecimalField(max_digits=10, decimal_places=2, null=True, blank=True)
    remaining_birr = models.DecimalField(max_digits=10, decimal_places=2, null=True, blank=True)

    created_at = models.DateTimeField(auto_now_add=True)

    def calculate_total(self):
        total = sum(item.product.price * item.quantity for item in self.items.all())
        discount_total = Decimal("0.00")

        # Apply discount rules dynamically
        for item in self.items.all():
            for rule in item.product.discount_rules.all():
                if item.quantity >= rule.min_quantity:
                    discount_total += rule.discount_amount

        self.discount = discount_total
        return total - discount_total

    def save(self, *args, **kwargs):
        super().save(*args, **kwargs)  # Save first

        total = self.calculate_total()
        self.total_price = total

        if self.paid_amount is not None:
            if self.paid_amount > total:
                raise ValidationError("Paid amount cannot be greater than total price.")

            self.remaining_birr = total - self.paid_amount

            if self.remaining_birr == Decimal("0.00"):
                self.status = "approved"

        super().save(update_fields=["total_price", "discount", "remaining_birr", "status"])

    def __str__(self):
        return f"Order #{self.id} - {self.user.username}"


class OrderItem(models.Model):
    order = models.ForeignKey(Order, related_name="items", on_delete=models.CASCADE)
    product = models.ForeignKey(Product, on_delete=models.CASCADE)
    quantity = models.PositiveIntegerField()

    size = models.CharField(max_length=50, blank=True, null=True)
    color = models.CharField(max_length=50, blank=True, null=True)

    def get_total_price(self):
        return self.product.price * self.quantity

    def save(self, *args, **kwargs):

        # Only decrease stock when first created
        if not self.pk:

            if self.quantity > self.product.quantity:
                raise ValidationError(
                    f"Only {self.product.quantity} items available in stock."
                )

            self.product.quantity -= self.quantity
            self.product.save(update_fields=["quantity"])

        super().save(*args, **kwargs)

    def __str__(self):
        return f"{self.quantity} x {self.product.name}"


# ================= NOTIFICATIONS =================
class Notification(models.Model):
    user = models.ForeignKey(User, on_delete=models.CASCADE, null=True, blank=True)
    message = models.TextField()
    is_read = models.BooleanField(default=False)
    created_at = models.DateTimeField(auto_now_add=True)

    def __str__(self):
        return f"Notification #{self.id}"


# ================= PASSWORD RESET =================
class PasswordResetOTP(models.Model):
    user = models.ForeignKey(User, on_delete=models.CASCADE)
    otp = models.CharField(max_length=6)
    created_at = models.DateTimeField(auto_now_add=True)

    def is_expired(self):
        return timezone.now() > self.created_at + timedelta(minutes=2)

    def __str__(self):
        return f"{self.user.email} - {self.otp}"


# ================= DISCOUNT RULES =================
class DiscountRule(models.Model):
    product = models.ForeignKey(Product, on_delete=models.CASCADE, related_name="discount_rules")
    min_quantity = models.PositiveIntegerField()   # e.g., 3
    discount_amount = models.DecimalField(max_digits=10, decimal_places=2)  # e.g., 100.00

    def __str__(self):
        return f"{self.product.name}: Buy {self.min_quantity}+ → {self.discount_amount} birr off"
