"""
Customer loan disbursement: cash given to a customer from an account.
Deducts from the account and increases what the customer owes.
"""
from decimal import Decimal
from django.db import models
from django.utils import timezone
from shop_management.models.base import DataRoot
from shop_management.models.data.customer import Customer
from shop_management.models.data.shop_account import Account
from shop_management.models.data.utils import Currency


class CustomerDebtor(DataRoot):
    """Money lent / given to a customer — increases customer balance, debits account."""

    customer = models.ForeignKey(
        Customer,
        on_delete=models.CASCADE,
        related_name="debtor_loans",
    )
    account = models.ForeignKey(
        Account,
        on_delete=models.SET_NULL,
        null=True,
        blank=True,
        related_name="customer_debtors",
    )
    amount = models.DecimalField(max_digits=14, decimal_places=2)
    settled_amount = models.DecimalField(
        max_digits=14,
        decimal_places=2,
        default=Decimal("0"),
        help_text="Amount already repaid via customer payments",
    )
    currency = models.ForeignKey(
        Currency,
        on_delete=models.SET_NULL,
        null=True,
        blank=True,
        related_name="customer_debtors",
    )
    exchange_rate = models.DecimalField(max_digits=20, decimal_places=6, default=1)
    converted_amount = models.DecimalField(max_digits=18, decimal_places=2, default=0)
    loan_date = models.DateTimeField(default=timezone.now)
    notes = models.TextField(blank=True, null=True)

    class Meta:
        ordering = ["-loan_date", "-id"]

    def __str__(self):
        curr = self.currency.title if self.currency else ""
        return f"Loan {self.amount} {curr} to {self.customer.name}"

    @property
    def outstanding_amount(self):
        amount = Decimal(str(self.amount or 0))
        settled = Decimal(str(self.settled_amount or 0))
        remaining = amount - settled
        return remaining if remaining > 0 else Decimal("0")
