"""Django models for wallet transactions."""

from __future__ import annotations

from decimal import Decimal

from django.db import models


class AbstractWalletTransaction(models.Model):
    """
    Abstract base model for storing wallet transaction records.
    
    Extend this model if you want to customize the table name or field definitions.
    When you extend this abstract model with a custom db_table, only ONE table
    will be created (your custom table), not the default wallet_transactions table.
    
    Example:
        class CustomWalletTransaction(AbstractWalletTransaction):
            amount = models.DecimalField(max_digits=20, decimal_places=8)
            balance = models.DecimalField(max_digits=20, decimal_places=8)
            
            class Meta:
                db_table = "custom_wallet_trans"  # Only this table will be created
    """

    wtype = models.CharField(
        max_length=50,
        db_index=True,
        help_text="Wallet type / point type (e.g., 'credit_balance', 'reward_points')",
    )
    iid = models.BigIntegerField(
        db_index=True,
        help_text="Initiator ID - user who performed this transaction (-100 for system)",
    )
    uid = models.BigIntegerField(
        db_index=True,
        help_text="User ID - owner of the wallet",
    )
    type = models.CharField(
        max_length=1,
        choices=[("c", "Credit/Add"), ("d", "Debit/Deduct")],
        help_text="Transaction type: 'c' for credit/add, 'd' for debit/deduct",
    )
    amount = models.DecimalField(
        max_digits=20,
        decimal_places=2,
        help_text="Transaction amount",
    )
    balance = models.DecimalField(
        max_digits=20,
        decimal_places=2,
        help_text="Balance after this transaction",
    )
    trans_type = models.IntegerField(
        db_index=True,
        null=True,
        blank=True,
        help_text="Transaction type code (integer constant, e.g., 1000 for wallet-deposit)",
    )
    descr = models.TextField(
        blank=True,
        default="",
        help_text="Remarks/description",
    )
    cdate = models.DateTimeField(
        auto_now_add=True,
        db_index=True,
        help_text="Creation date/time",
    )
    extra_data = models.JSONField(
        default=dict,
        blank=True,
        help_text="Additional fields stored as JSON",
    )

    class Meta:
        abstract = True
        indexes = [
            models.Index(fields=["uid", "wtype"]),
            models.Index(fields=["uid", "cdate"]),
            models.Index(fields=["wtype", "trans_type"]),
            models.Index(fields=["iid", "cdate"]),
        ]
        ordering = ["-cdate"]

    def __str__(self) -> str:
        return f"{self.type.upper()} {self.amount} {self.wtype} - User {self.uid}"


class WalletTransaction(AbstractWalletTransaction):
    """
    Concrete model for storing wallet transaction records.
    
    This is the default implementation that creates the 'wallet_transactions' table.
    Use this model directly, or extend AbstractWalletTransaction for custom implementations.
    
    If you extend AbstractWalletTransaction with a custom db_table, only your custom
    table will be created (not this one), as long as you skip running wallet_utils
    migrations or exclude this model from migrations.
    """

    class Meta(AbstractWalletTransaction.Meta):
        db_table = "wallet_transactions"
