from django.conf import settings
from django.db import models

from apps.common.models import TimeStampedModel


class Order(TimeStampedModel):
    """
    A single sold line item. Product attributes are snapshotted at sale time so
    history survives later product edits/deletion. Orders placed together share
    an `order_number`.
    """

    class Status(models.TextChoices):
        PENDING_REVIEW = 'pending_review', 'Pending review'
        PAYMENT_UPLOADED = 'payment_uploaded', 'Payment uploaded'
        APPROVED = 'approved', 'Approved'
        OUT_OF_STOCK = 'out_of_stock', 'Out of stock'
        PAYMENT_CONFIRMED = 'payment_confirmed', 'Payment confirmed'
        PAYMENT_REJECTED = 'payment_rejected', 'Payment rejected'
        IN_FULFILLMENT = 'in_fulfillment', 'In fulfillment'
        DELIVERED = 'delivered', 'Delivered'
        COMPLETED = 'completed', 'Completed'
        CANCELLED = 'cancelled', 'Cancelled'

    class Logistics(models.TextChoices):
        PROCESSING = 'processing', 'Processing'
        FROM_VENDOR = 'from_vendor', 'From vendor'
        AT_WAREHOUSE = 'at_warehouse', 'At warehouse'
        OUT_FOR_DELIVERY = 'out_for_delivery', 'Out for delivery'

    # Terminal states that can no longer transition.
    TERMINAL = {Status.COMPLETED, Status.CANCELLED}
    # States in which the seller has not yet earned, but the order is still live.
    PENDING_EARNING = {
        Status.PENDING_REVIEW, Status.PAYMENT_UPLOADED, Status.APPROVED,
        Status.PAYMENT_CONFIRMED, Status.IN_FULFILLMENT, Status.DELIVERED,
    }

    user = models.ForeignKey(
        settings.AUTH_USER_MODEL, on_delete=models.PROTECT, related_name='orders')
    product = models.ForeignKey(
        'catalog.Product', null=True, blank=True,
        on_delete=models.SET_NULL, related_name='orders')

    # Snapshot fields
    product_name = models.CharField(max_length=200)
    product_code = models.CharField(max_length=40, blank=True)
    category = models.CharField(max_length=120, blank=True)
    selling_price = models.DecimalField(max_digits=14, decimal_places=2)
    buying_price = models.DecimalField(max_digits=14, decimal_places=2, default=0)
    profit = models.DecimalField(max_digits=14, decimal_places=2, default=0)
    commission = models.DecimalField(max_digits=14, decimal_places=2, default=0)
    commission_percent = models.FloatField(default=0)
    vat_amount = models.DecimalField(max_digits=14, decimal_places=2, default=0)
    quantity = models.PositiveIntegerField(default=1)

    selected_size = models.CharField(max_length=60, blank=True)
    selected_color = models.CharField(max_length=60, blank=True)
    item_notes = models.TextField(blank=True)

    customer_name = models.CharField(max_length=120, blank=True)
    customer_phone = models.CharField(max_length=30, blank=True)
    order_number = models.CharField(max_length=40, db_index=True)

    status = models.CharField(
        max_length=20, choices=Status.choices, default=Status.PENDING_REVIEW, db_index=True)
    logistics_status = models.CharField(
        max_length=20, choices=Logistics.choices, null=True, blank=True)

    admin_notes = models.TextField(blank=True)
    reviewed_by = models.ForeignKey(
        settings.AUTH_USER_MODEL, null=True, blank=True,
        on_delete=models.SET_NULL, related_name='reviewed_orders')
    completed_at = models.DateTimeField(null=True, blank=True)

    payment_proof = models.JSONField(default=list, blank=True)
    product_images = models.JSONField(default=list, blank=True)

    # True once commission has been posted to the ledger (guards double-pay).
    commission_posted = models.BooleanField(default=False)

    class Meta:
        db_table = 'orders'
        ordering = ['-created_at']
        indexes = [
            models.Index(fields=['user', 'status']),
            models.Index(fields=['order_number']),
        ]

    def __str__(self):
        return f'{self.order_number} · {self.product_name}'

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


class OrderEvent(models.Model):
    """An immutable status-change record powering the order timeline."""

    order = models.ForeignKey(Order, on_delete=models.CASCADE, related_name='events')
    from_status = models.CharField(max_length=20, blank=True)
    to_status = models.CharField(max_length=20)
    note = models.CharField(max_length=255, blank=True)
    changed_by = models.ForeignKey(
        settings.AUTH_USER_MODEL, null=True, blank=True,
        on_delete=models.SET_NULL, related_name='order_events')
    created_at = models.DateTimeField(auto_now_add=True)

    class Meta:
        db_table = 'order_events'
        ordering = ['-created_at']
