from decimal import Decimal

from django.db import models
from django.utils import timezone

from shop_management.models.data.shop_account import Account
from shop_management.models.data.utils import Currency


class AccountTransfer(models.Model):
    class Status(models.TextChoices):
        DRAFT = "DRAFT", "Draft"
        POSTED = "POSTED", "Posted"
        VOID = "VOID", "Cancelled"

    transfer_number = models.CharField(max_length=50, unique=True, null=True, blank=True)
    uses_controlled_engine = models.BooleanField(default=False)
    status = models.CharField(max_length=10, choices=Status.choices, default=Status.POSTED)
    from_account = models.ForeignKey(
        Account, on_delete=models.CASCADE, related_name="outgoing_transfers"
    )
    to_account = models.ForeignKey(
        Account, on_delete=models.CASCADE, related_name="incoming_transfers"
    )
    from_currency = models.ForeignKey(
        Currency,
        on_delete=models.PROTECT,
        related_name="account_transfers_as_from_currency",
    )
    to_currency = models.ForeignKey(
        Currency,
        on_delete=models.PROTECT,
        related_name="account_transfers_as_to_currency",
    )
    amount = models.DecimalField(max_digits=18, decimal_places=2)
    exchange_rate = models.DecimalField(max_digits=20, decimal_places=6)
    converted_amount = models.DecimalField(max_digits=18, decimal_places=2)
    service_charge = models.DecimalField(max_digits=18, decimal_places=2, default=0)
    service_charge_account = models.ForeignKey(Account, null=True, blank=True, on_delete=models.PROTECT, related_name="charged_account_transfers")
    reference = models.CharField(max_length=120, blank=True, null=True)
    note = models.TextField(blank=True, null=True)
    transfer_date = models.DateField(default=timezone.localdate)
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)
    posted_at = models.DateTimeField(null=True, blank=True)
    posted_by = models.ForeignKey("account.User", null=True, blank=True, on_delete=models.PROTECT, related_name="account_transfers_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="account_transfers_voided")
    void_reason = models.TextField(blank=True)

    class Meta:
        ordering = ["-transfer_date", "-id"]

    def __str__(self):
        return (
            f"Transfer {self.amount} {self.from_currency.title} "
            f"from {self.from_account.name} to {self.to_account.name}"
        )

    @property
    def shop_id(self):
        return self.from_account.shop_id

    @staticmethod
    def normalize_rate(rate):
        return Decimal(rate)
