import uuid
from django.db import models

# Account Types
class AccountType(models.TextChoices):
    USER = 'USER', 'User Account'
    SERVICE = 'SERVICE', 'Service Account'
    ASSET = 'ASSET', 'Asset Account'
    LIABILITY = 'LIABILITY', 'Liability Account'
    REVENUE = 'REVENUE', 'Revenue Account'
    EXPENSE = 'EXPENSE', 'Expense Account'


class Account(models.Model):
    """
    Represents an account in our system, mapped to a TigerBeetle account.
    This model serves as a local reference for account metadata.
    """
    uuid = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    name = models.CharField(max_length=255, help_text="Name or identifier for the account")
    account_type = models.CharField(
        max_length=50,
        choices=AccountType.choices,
        default=AccountType.USER,
        help_text="Type of the account (e.g., User, Service, Revenue)"
    )
    description = models.TextField(blank=True, null=True, help_text="Detailed description of the account")
    @property
    def tigerbeetle_account_id(self):
        """The TigerBeetle account ID is derived from the UUID."""
        return self.uuid.int
    created_at = models.DateTimeField(auto_now_add=True)

    def __str__(self):
        return f"{self.name} ({self.account_type}) - TB ID: {self.tigerbeetle_account_id}"

    class Meta:
        verbose_name = "Billing Account"
        verbose_name_plural = "Billing Accounts"
        ordering = ['-created_at']


class TransactionReason(models.Model):
    """
    Defines the business reason or type for a financial operation.
    E.g., 'Deposit', 'Payment for Service', 'Refund'.
    """
    name = models.CharField(max_length=255, unique=True, help_text="Unique name for the transaction reason")
    description = models.TextField(blank=True, null=True, help_text="Detailed description of this transaction reason")
    created_at = models.DateTimeField(auto_now_add=True)

    def __str__(self):
        return self.name

    class Meta:
        verbose_name = "Transaction Reason"
        verbose_name_plural = "Transaction Reasons"
        ordering = ['name']


class OperationState(models.TextChoices):
    PENDING = 'PENDING', 'Pending TigerBeetle transfer'
    COMPLETED = 'COMPLETED', 'TigerBeetle transfer completed'
    FAILED = 'FAILED', 'TigerBeetle transfer failed'


class Operation(models.Model):
    """
    Represents a business operation that results in one or more TigerBeetle transfers.
    This links the business context to the financial movement.
    """
    uuid = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    source_account = models.ForeignKey(
        Account,
        on_delete=models.PROTECT,
        related_name='outgoing_operations',
        help_text="The account from which funds are moved"
    )
    destination_account = models.ForeignKey(
        Account,
        on_delete=models.PROTECT,
        related_name='incoming_operations',
        help_text="The account to which funds are moved"
    )
    amount = models.DecimalField(
        max_digits=20,
        decimal_places=4,
        help_text="The amount transferred in this operation"
    )
    reason = models.ForeignKey(
        TransactionReason,
        on_delete=models.PROTECT,
        related_name='operations',
        help_text="The business reason for this operation"
    )
    state = models.CharField(
        max_length=50,
        choices=OperationState.choices,
        default=OperationState.PENDING,
        help_text="Current state of the TigerBeetle transfer for this operation"
    )
    tigerbeetle_transfer_id = models.BigIntegerField(
        unique=True,
        null=True,
        blank=True,
        help_text="The unique ID of the transfer in TigerBeetle, set after successful transfer"
    )
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)

    def __str__(self):
        return (
            f"Operation {self.uuid}: {self.reason.name} "
            f"from {self.source_account.name} to {self.destination_account.name} "
            f"for {self.amount}"
        )

    class Meta:
        verbose_name = "Business Operation"
        verbose_name_plural = "Business Operations"
        ordering = ['-created_at']
