from django.db import models
import uuid



from django.conf import settings
from apps.business.products.models import Product
from apps.business.distributor.models import DistributorID

class Order(models.Model):
    STATUS_CHOICES = [
        ("PENDING", "Pending"),
        ("PAYMENT_REVIEW", "Payment Review"),
        ("PARTIAL_PAID", "Partial Paid"),
        ("COMPLETED", "Completed"),
        ("FAILED", "Failed"),
    ]
    PAYMENT_MODE_CHOICES = [
        ("FULL", "Full Payment"),
        ("PART", "Part Payment"),
    ]
    OWNERSHIP_STATUS_CHOICES = [
        ("FULL_OWNED", "Full Owned"),
        ("PARTIAL_OWNED", "Partial Owned"),
        ("CONVERTED", "Converted"),
    ]
    PAYMENT_METHOD_CHOICES = [
        ("main_wallet", "Main Wallet"),
        ("repurchase_wallet", "Repurchase Wallet"),
        ("super_coins", "Super Coins"),
        ("razorpay", "Razorpay"),
        ("qr_scan", "QR Scan"),
        ("bank_transfer", "Bank Transfer"),
        ("phonepe", "PhonePe"),
        ("cash_payment", "Cash Payment"),
    ]
    FULFILLMENT_MODE_CHOICES = [
        ("STORE_DELIVERY", "Store Delivery"),
        ("CUSTOMER_PICKUP", "Customer Pickup"),
    ]
    FULFILLMENT_STATUS_CHOICES = [
        ("PENDING", "Pending"),
        ("IN_TRANSIT", "In Transit"),
        ("DELIVERED", "Delivered"),
        ("COLLECTED", "Collected"),
        ("CANCELLED", "Cancelled"),
    ]
    ORDER_TYPE_CHOICES = [
        ("BUNDLE", "Opportunity Bundle"),
        ("RETAIL", "Retail Marketplace"),
    ]
    id = models.UUIDField(primary_key=True, editable=False, default=uuid.uuid4)
    user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE, related_name="orders")
    product = models.ForeignKey(Product, on_delete=models.CASCADE)
    amount = models.DecimalField(max_digits=10, decimal_places=2)
    voucher_amount = models.DecimalField(max_digits=10, decimal_places=2, default=0)
    super_coin_amount = models.DecimalField(max_digits=10, decimal_places=2, default=0)
    cash_amount = models.DecimalField(max_digits=10, decimal_places=2, default=0)
    status = models.CharField(max_length=16, choices=STATUS_CHOICES, default="PENDING")
    reference_id = models.CharField(max_length=128, unique=True)
    distributor = models.ForeignKey(DistributorID, null=True, blank=True, on_delete=models.SET_NULL)
    franchise_assignment = models.ForeignKey('geo.FranchiseAssignment', null=True, blank=True, on_delete=models.SET_NULL, related_name='orders')
    delivery_store = models.ForeignKey('geo.FranchiseStore', null=True, blank=True, on_delete=models.SET_NULL, related_name='orders')
    fulfillment_mode = models.CharField(max_length=20, choices=FULFILLMENT_MODE_CHOICES, default="STORE_DELIVERY")
    franchise_fulfillment_status = models.CharField(max_length=20, choices=FULFILLMENT_STATUS_CHOICES, default="PENDING")
    client_reference_id = models.CharField(max_length=128, null=True, blank=True, db_index=True)
    payment_method = models.CharField(max_length=32, choices=PAYMENT_METHOD_CHOICES, default="main_wallet", blank=True)
    qr_reference = models.CharField(max_length=128, null=True, blank=True, help_text="Reference number for QR scan payments")
    # Invoice / fulfillment address snapshots (stored at order time)
    billing_address = models.JSONField(null=True, blank=True, help_text="Billing address snapshot at order time")
    shipping_address = models.JSONField(null=True, blank=True, help_text="Shipping address snapshot at order time")
    dispatch_address = models.JSONField(null=True, blank=True, help_text="Dispatch address snapshot at order time")
    buyer_gst_number = models.CharField(max_length=15, null=True, blank=True)
    buyer_company_name = models.CharField(max_length=255, null=True, blank=True)
    place_of_supply = models.CharField(max_length=50, null=True, blank=True, help_text="e.g. 36-Telangana")
    rejection_comment = models.TextField(null=True, blank=True, help_text="Admin rejection reason for QR/bank payment orders")
    reviewed_by = models.ForeignKey(settings.AUTH_USER_MODEL, null=True, blank=True, on_delete=models.SET_NULL, related_name='reviewed_orders', help_text="Admin who approved/rejected this payment")
    reviewed_at = models.DateTimeField(null=True, blank=True, help_text="When the payment was reviewed")
    payment_mode = models.CharField(max_length=8, choices=PAYMENT_MODE_CHOICES, default='FULL', db_index=True)
    ownership_status = models.CharField(max_length=20, choices=OWNERSHIP_STATUS_CHOICES, default='FULL_OWNED', db_index=True)
    is_availability_blocked = models.BooleanField(default=False)
    part_payment_percentage = models.PositiveIntegerField(default=50)
    part_total_amount = models.DecimalField(max_digits=10, decimal_places=2, null=True, blank=True)
    part_paid_amount = models.DecimalField(max_digits=10, decimal_places=2, default=0)
    part_pending_amount = models.DecimalField(max_digits=10, decimal_places=2, default=0)
    part_payment_started_at = models.DateTimeField(null=True, blank=True)
    part_payment_due_at = models.DateTimeField(null=True, blank=True, db_index=True)
    part_payment_completed_at = models.DateTimeField(null=True, blank=True)
    part_payment_converted_at = models.DateTimeField(null=True, blank=True)
    part_payment_conversion_product = models.ForeignKey(
        Product,
        null=True,
        blank=True,
        on_delete=models.SET_NULL,
        related_name='part_payment_orders',
    )
    part_payment_conversion_notes = models.TextField(null=True, blank=True)

    # -------------------------------------------------------------------------
    # MARKETPLACE EXTENSION FIELDS
    # These fields extend the bundle order model to support retail marketplace orders.
    # All are nullable so existing bundle orders are fully unaffected.
    # -------------------------------------------------------------------------

    order_type = models.CharField(
        max_length=10,
        choices=ORDER_TYPE_CHOICES,
        default="BUNDLE",
        db_index=True,
        help_text=(
            "BUNDLE = opportunity bundle purchase (activates DistributorID, binary tree)."
            " RETAIL = marketplace retail order (uses OrderItem, no binary logic)."
        ),
    )
    payment_transaction = models.ForeignKey(
        'payments.PaymentTransaction',
        null=True, blank=True,
        on_delete=models.SET_NULL,
        related_name='linked_orders',
        help_text="Gateway payment record when Razorpay/UPI is used for this order",
    )
    wallet_ledger_entry = models.ForeignKey(
        'wallet.WalletLedger',
        null=True, blank=True,
        on_delete=models.PROTECT,
        related_name='funded_orders',
        help_text="WalletLedger debit record for wallet-funded orders (atomicity anchor)",
    )

    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)

    class Meta:
        verbose_name = 'Order'
        verbose_name_plural = 'Orders'
        unique_together = ("user", "product", "client_reference_id")

    def __str__(self):
        return f"Order {self.reference_id}"


class OrderPartPaymentLog(models.Model):
    EVENT_CHOICES = [
        ('CREATED', 'Created'),
        ('PAYMENT_REVIEW_SUBMITTED', 'Payment Review Submitted'),
        ('PART_PAYMENT_ACTIVATED', 'Part Payment Activated'),
        ('FULL_PAYMENT_SETTLED', 'Full Payment Settled'),
        ('COOLING_ELAPSED', 'Cooling Elapsed'),
        ('CONVERTED', 'Converted'),
        ('CONVERSION_FAILED', 'Conversion Failed'),
    ]

    id = models.UUIDField(primary_key=True, editable=False, default=uuid.uuid4)
    order = models.ForeignKey(Order, on_delete=models.CASCADE, related_name='part_payment_logs')
    event = models.CharField(max_length=40, choices=EVENT_CHOICES, db_index=True)
    actor = models.ForeignKey(settings.AUTH_USER_MODEL, null=True, blank=True, on_delete=models.SET_NULL, related_name='order_part_payment_logs')
    notes = models.TextField(blank=True, default='')
    metadata = models.JSONField(null=True, blank=True)
    created_at = models.DateTimeField(auto_now_add=True, db_index=True)

    class Meta:
        ordering = ['-created_at']

    def __str__(self):
        return f"{self.order.reference_id} - {self.event}"
