import uuid
from django.db import models
from sales.models import Sale, SaleItem
from payments.models import Payment
from businesses.models import DeliveryOption
from core.models import TimeStampedModel


class Order(TimeStampedModel):
    """
    A guest checkout order against a live Sale. No buyer account required.
    Stock is decremented only on verified payment, never on cart add.
    """
    STATUS_CHOICES = [
        ('pending', 'Pending'),
        ('paid', 'Paid'),
        ('failed', 'Failed'),
        ('refunded', 'Refunded'),
    ]

    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    sale = models.ForeignKey(
        Sale, on_delete=models.CASCADE, related_name='orders'
    )
    buyer_name = models.CharField(max_length=200)
    buyer_phone = models.CharField(max_length=20)
    buyer_email = models.EmailField()

    # Delivery fields
    delivery_option = models.ForeignKey(
        DeliveryOption, on_delete=models.SET_NULL, null=True, blank=True,
        related_name='orders'
    )
    delivery_fee = models.DecimalField(max_digits=10, decimal_places=2, default=0.00)
    delivery_address = models.TextField(blank=True, help_text='Buyer delivery address / landmark notes')

    status = models.CharField(max_length=20, choices=STATUS_CHOICES, default='pending')
    payment = models.OneToOneField(
        Payment, on_delete=models.SET_NULL, null=True, blank=True,
        related_name='order'
    )
    total_amount = models.DecimalField(max_digits=10, decimal_places=2, default=0)

    class Meta:
        ordering = ['-created_at']

    def __str__(self):
        return f"Order {str(self.id)[:8]} - {self.buyer_name} ({self.status})"

    @property
    def order_number(self):
        return str(self.id)[:8].upper()

    @property
    def items_subtotal(self):
        return sum(item.line_total for item in self.items.all())

    @classmethod
    def release_expired_pending_orders(cls, timeout_minutes=15):
        """
        Cancels pending orders older than `timeout_minutes` and restores their reserved stock.
        Prevents stock lockup from abandoned checkouts.
        """
        from django.utils import timezone
        import datetime
        from django.db import transaction
        from django.db.models import F
        from sales.models import SaleItem

        cutoff = timezone.now() - datetime.timedelta(minutes=timeout_minutes)
        expired_orders = cls.objects.filter(status='pending', created_at__lt=cutoff)
        for order in expired_orders:
            try:
                with transaction.atomic():
                    ord_locked = cls.objects.select_for_update().filter(id=order.id, status='pending').first()
                    if ord_locked:
                        ord_locked.status = 'failed'
                        ord_locked.save(update_fields=['status', 'updated_at'])
                        for item in ord_locked.items.all():
                            SaleItem.objects.filter(id=item.sale_item_id).update(
                                stock_remaining=F('stock_remaining') + item.quantity
                            )
            except Exception as e:
                print(f"[StockRelease] Error releasing order {order.id}: {e}")


class OrderItem(models.Model):
    """
    A line item in an Order. Snapshots the unit_price at order time to protect
    order history if a seller edits a live sale.
    """
    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    order = models.ForeignKey(
        Order, on_delete=models.CASCADE, related_name='items'
    )
    sale_item = models.ForeignKey(
        SaleItem, on_delete=models.CASCADE, related_name='order_items'
    )
    quantity = models.PositiveIntegerField(default=1)
    unit_price = models.DecimalField(
        max_digits=10, decimal_places=2,
        help_text='Snapshot of sale_item.price at order time.'
    )

    def __str__(self):
        return f"{self.sale_item.product.name} x{self.quantity}"

    @property
    def line_total(self):
        return self.quantity * self.unit_price
