from django.db import models
from django.utils import timezone

from shop_management.models.base import DataRoot


class CustomerPayment(DataRoot):
    class Status(models.TextChoices):
        DRAFT = "DRAFT", "Draft"
        POSTED = "POSTED", "Posted"
        VOID = "VOID", "Cancelled"

    customer = models.ForeignKey("shop_management.Customer", on_delete=models.PROTECT, related_name="customer_payments")
    shop = models.ForeignKey("shop_management.Shop", on_delete=models.PROTECT, related_name="customer_payments")
    financial_account = models.ForeignKey("shop_management.Account", on_delete=models.PROTECT, related_name="customer_payments")
    payment_date = models.DateField(default=timezone.localdate)
    currency = models.ForeignKey("shop_management.Currency", on_delete=models.PROTECT, related_name="customer_payments_new")
    amount = models.DecimalField(max_digits=18, decimal_places=2)
    exchange_rate_used = models.DecimalField(max_digits=20, decimal_places=6, default=1)
    base_amount = models.DecimalField(max_digits=18, decimal_places=2, default=0)
    reference = models.CharField(max_length=100, blank=True)
    notes = models.TextField(blank=True)
    status = models.CharField(max_length=10, choices=Status.choices, default=Status.DRAFT)
    posted_at = models.DateTimeField(null=True, blank=True)
    posted_by = models.ForeignKey("account.User", null=True, blank=True, on_delete=models.PROTECT, related_name="customer_payments_posted")
    voided_at = models.DateTimeField(null=True, blank=True)
    voided_by = models.ForeignKey("account.User", null=True, blank=True, on_delete=models.PROTECT, related_name="customer_payments_voided")
    void_reason = models.TextField(blank=True)

    class Meta:
        ordering = ["-payment_date", "-id"]

    @property
    def allocated_amount(self):
        return sum((row.allocated_amount for row in self.allocations.all()), 0)

    @property
    def unallocated_amount(self):
        return self.amount - self.allocated_amount


class CustomerPaymentAllocation(DataRoot):
    payment = models.ForeignKey(CustomerPayment, on_delete=models.CASCADE, related_name="allocations")
    sale = models.ForeignKey("shop_management.Sale", on_delete=models.PROTECT, related_name="customer_payment_allocations")
    allocated_amount = models.DecimalField(max_digits=18, decimal_places=2)

    class Meta:
        constraints = [models.UniqueConstraint(fields=["payment", "sale"], name="unique_customer_payment_sale")]
