from decimal import Decimal

from django.db import models

from shop_management.models.base import DataRoot


class CustomerCreditApplication(DataRoot):
    """Auditable use of an existing customer credit against a posted sale."""

    customer = models.ForeignKey(
        "shop_management.Customer",
        on_delete=models.PROTECT,
        related_name="credit_applications",
    )
    sale = models.ForeignKey(
        "shop_management.Sale",
        on_delete=models.CASCADE,
        related_name="credit_applications",
    )
    customer_payment = models.ForeignKey(
        "shop_management.CustomerPayment",
        null=True,
        blank=True,
        on_delete=models.PROTECT,
        related_name="credit_applications",
    )
    balance_payment = models.ForeignKey(
        "shop_management.CustomerBalancePayment",
        null=True,
        blank=True,
        on_delete=models.PROTECT,
        related_name="credit_applications",
    )
    source_currency = models.ForeignKey(
        "shop_management.Currency",
        on_delete=models.PROTECT,
        related_name="customer_credit_applications_from",
    )
    sale_currency = models.ForeignKey(
        "shop_management.Currency",
        on_delete=models.PROTECT,
        related_name="customer_credit_applications_to",
    )
    source_amount = models.DecimalField(max_digits=18, decimal_places=2)
    sale_amount = models.DecimalField(max_digits=18, decimal_places=2)
    exchange_rate = models.DecimalField(max_digits=20, decimal_places=6, default=Decimal("1"))

    class Meta:
        ordering = ["created_at", "id"]
        constraints = [
            models.CheckConstraint(
                check=(
                    models.Q(customer_payment__isnull=False, balance_payment__isnull=True)
                    | models.Q(customer_payment__isnull=True, balance_payment__isnull=False)
                ),
                name="customer_credit_application_one_source",
            ),
            models.CheckConstraint(
                check=models.Q(source_amount__gt=0, sale_amount__gt=0, exchange_rate__gt=0),
                name="customer_credit_application_positive_amounts",
            ),
        ]

