from django.db import models
from suppliers.models import Supplier
from inventory.models import Product, Batch
from django.utils.timezone import now
from uuid import uuid4


class Order(models.Model):
    order_number = models.CharField(max_length=20, unique=True, editable=False)
    supplier = models.ForeignKey(Supplier, on_delete=models.CASCADE)
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)
    is_received = models.BooleanField(default=False)  # New field to track if the order has been received

    def save(self, *args, **kwargs):
        if not self.order_number:
            max_id = Order.objects.aggregate(max_id=models.Max('id'))['max_id']
            new_id = max_id + 1 if max_id else 1
            self.order_number = f'ORD{new_id:06d}'
        super().save(*args, **kwargs)

    def __str__(self):
        return self.order_number


class OrderItem(models.Model):
    order = models.ForeignKey(Order, related_name='items', on_delete=models.CASCADE)
    product = models.ForeignKey(Product, on_delete=models.CASCADE, related_name='supplier_order_items')
    quantity_ordered = models.PositiveIntegerField()
    quantity_delivered = models.PositiveIntegerField(default=0)  # New field for tracking delivered quantity
    buying_price = models.DecimalField(max_digits=10, decimal_places=2, null=True, blank=True)  # Made optional

    def __str__(self):
        return f"{self.product.name} ({self.quantity_ordered})"
    
    def get_display_price(self):
        """Return buying_price if set, otherwise return 'TBD' for display"""
        return self.buying_price if self.buying_price else "TBD"


class Receipt(models.Model):
    supplier = models.ForeignKey(Supplier, on_delete=models.SET_NULL, null=True, blank=True)
    created_at = models.DateTimeField(auto_now_add=True)
    notes = models.TextField(blank=True, null=True)

    def __str__(self):
        return f"Receipt #{self.id} - {self.supplier.name if self.supplier else 'Unknown Supplier'} ({self.created_at.date()})"


class StockReception(models.Model):
    receipt = models.ForeignKey(Receipt, related_name='stock_items', null=True, blank=True, on_delete=models.CASCADE)
    product = models.ForeignKey(Product, on_delete=models.CASCADE, related_name='stock_receptions')
    supplier = models.ForeignKey(Supplier, on_delete=models.SET_NULL, null=True, blank=True)
    quantity_received = models.PositiveIntegerField()
    buying_price = models.DecimalField(max_digits=10, decimal_places=2)
    selling_price = models.DecimalField(max_digits=10, decimal_places=2, blank=True, null=True)
    expiry_date = models.DateField(blank=True, null=True)
    batch_code = models.CharField(max_length=255, blank=True, null=True)
    received_date = models.DateField(default=now)
    notes = models.TextField(blank=True, null=True)

    def save(self, *args, **kwargs):
        """
        Save logic to handle batch creation or updating with dynamic pricing.
        """
        # Update product pricing based on new batch costs
        price_updated, message = self.product.update_pricing_from_batch(
            self.buying_price, 
            self.selling_price
        )
        
        # Create or update a batch
        batch, created = Batch.objects.get_or_create(
            product=self.product,
            batch_code=self.batch_code or f"BATCH-{uuid4().hex[:6].upper()}",
            defaults={
                'quantity': self.quantity_received,
                'buying_price': self.buying_price,
                'selling_price': self.selling_price,
                'expiry_date': self.expiry_date,
                'supplier': self.supplier,
                'received_date': self.received_date,
                'notes': self.notes,
            },
        )

        if not created:
            # Update existing batch
            batch.quantity += self.quantity_received
            batch.buying_price = self.buying_price
            batch.selling_price = self.selling_price
            batch.expiry_date = self.expiry_date
            batch.supplier = self.supplier
            batch.notes = self.notes
            batch.save()

        # Update product stock quantity
        self.product.stock_quantity += self.quantity_received
        self.product.save()

        # Assign the batch code to this StockReception (if newly created)
        self.batch_code = batch.batch_code

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

    def __str__(self):
        return f"StockReception: {self.quantity_received} of {self.product.name}"
