from django.db import models
from django.core.exceptions import ValidationError
from shop_management.models.base import DataRoot
from shop_management.models.data.shop import Shop
from shop_management.models.data.purchase import PurchaseItem

class Stock(DataRoot):
    shop = models.ForeignKey(
        Shop, 
        on_delete=models.CASCADE, 
        related_name='stocks',
        help_text="The shop that owns this stock record."
    )
    purchase_item = models.ForeignKey(
        PurchaseItem, 
        on_delete=models.SET_NULL, 
        null=True, 
        blank=True, 
        related_name='stocks',
        help_text="The purchase item from which the product is taken and details (unit) are inherited."
    )
    quantity = models.IntegerField(
        default=0,
        help_text="The current quantity available in stock."
    )
    average_buy_price = models.DecimalField(
        max_digits=14,
        decimal_places=4,
        default="0.00",
        help_text="Weighted average purchase cost for the current stock quantity.",
    )
    average_wholesale_price = models.DecimalField(
        max_digits=14,
        decimal_places=4,
        null=True,
        blank=True,
        help_text="Weighted average wholesale price for the current stock quantity.",
    )
    average_retail_price = models.DecimalField(
        max_digits=14,
        decimal_places=4,
        null=True,
        blank=True,
        help_text="Weighted average retail price for the current stock quantity.",
    )
    sale_price = models.DecimalField(max_digits=14, decimal_places=4, default='0.0000',
                                     help_text="Active selling price used in sales")
    wholesale_price = models.DecimalField(max_digits=14, decimal_places=4, null=True, blank=True,
                                          help_text="Wholesale price (copied from purchase item)")
    retail_price = models.DecimalField(max_digits=14, decimal_places=4, null=True, blank=True,
                                       help_text="Retail price (copied from purchase item)")
    comments = models.TextField(blank=True, null=True, help_text="Additional comments for this stock item")
    is_deleted = models.BooleanField(default=False)

    class Meta:
        constraints = [
            models.CheckConstraint(
                check=models.Q(quantity__gte=0),
                name="legacy_stock_quantity_nonnegative",
            )
        ]

    def __str__(self):
        product_name = (self.purchase_item.product.name 
                        if self.purchase_item and self.purchase_item.product 
                        else "Unknown Product")
        return f"Stock of {product_name} at {self.shop.name} (Qty: {self.quantity})"

    def save(self, *args, **kwargs):
        if self.quantity is not None and self.quantity < 0:
            raise ValidationError(
                {"quantity": "Stock cannot go below zero. Reduce the requested quantity."}
            )
        # Prevent automatic stock updates from signals
        if hasattr(self, '_skip_stock_update'):
            super().save(*args, **kwargs)
            return
        super().save(*args, **kwargs)

    @property
    def unit(self):
        return self.purchase_item.unit if self.purchase_item else None

    @property
    def currency(self):
        if self.purchase_item and getattr(self.purchase_item, "currency", None):
            return self.purchase_item.currency
        if self.purchase_item and self.purchase_item.purchase:
            return self.purchase_item.purchase.currency
        return None

    @property
    def stock_value(self):
        quantity = self.quantity or 0
        average_buy_price = self.average_buy_price or 0
        return quantity * average_buy_price

    @property
    def average_wholesale(self):
        return self.average_wholesale_price if self.average_wholesale_price is not None else self.wholesale_price

    @property
    def average_retail(self):
        return self.average_retail_price if self.average_retail_price is not None else self.retail_price
