from django.db import models
from django.conf import settings
from decimal import Decimal

class Wallet(models.Model):
    user = models.OneToOneField(settings.AUTH_USER_MODEL, on_delete=models.CASCADE, related_name='wallet')
    main_balance = models.DecimalField(max_digits=12, decimal_places=2, default=Decimal('0.00'))
    repurchase_balance = models.DecimalField(max_digits=12, decimal_places=2, default=Decimal('0.00'))
    voucher_balance = models.DecimalField(max_digits=12, decimal_places=2, default=Decimal('0.00'))
    locked_amount = models.DecimalField(max_digits=12, decimal_places=2, default=0)

    @property
    def twm_coins_balance(self):
        """Backward-compatible alias for renamed voucher wallet."""
        return self.voucher_balance

    def __str__(self):
        return f"Wallet({self.user_id}) - Main: {self.main_balance} | Repurchase: {self.repurchase_balance} (Locked: {self.locked_amount})"

class WalletLedger(models.Model):
    class TransactionType(models.TextChoices):
        CREDIT = 'CREDIT', 'Credit'
        DEBIT = 'DEBIT', 'Debit'

    class WalletType(models.TextChoices):
        EARNINGS = 'EARNINGS', 'Earnings'
        REPURCHASE = 'REPURCHASE', 'Repurchase'
        VOUCHER = 'VOUCHER', 'Voucher'
        SUPER_COINS = 'SUPER_COINS', 'Super Coins'

    class SourceType(models.TextChoices):
        DIRECT_INCENTIVE = 'DIRECT_INCENTIVE', 'Direct Incentive'
        LEVEL_REWARD = 'LEVEL_REWARD', 'Level Reward'
        POWER_STREAM = 'POWER_STREAM', 'Power Stream'
        LUCKY_DIP = 'LUCKY_DIP', 'Lucky Dip'
        PURCHASE = 'PURCHASE', 'Purchase'
        VOUCHER_PURCHASE = 'VOUCHER_PURCHASE', 'Voucher Purchase'
        VOUCHER_REDEMPTION = 'VOUCHER_REDEMPTION', 'Voucher Redemption'
        VOUCHER_ADJUSTMENT = 'VOUCHER_ADJUSTMENT', 'Voucher Adjustment'
        SUPER_COIN_CREDIT = 'SUPER_COIN_CREDIT', 'Super Coin Credit'
        SUPER_COIN_DEBIT = 'SUPER_COIN_DEBIT', 'Super Coin Debit'
        SUPER_COIN_CONVERSION = 'SUPER_COIN_CONVERSION', 'Super Coin Conversion'
        TDS_DEDUCTION = 'TDS_DEDUCTION', 'TDS Deduction'

    user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE, related_name='wallet_ledgers')
    wallet = models.ForeignKey(Wallet, on_delete=models.CASCADE, related_name='ledgers')
    transaction_type = models.CharField(max_length=8, choices=TransactionType.choices)
    wallet_type = models.CharField(max_length=12, choices=WalletType.choices)
    source_type = models.CharField(max_length=32, choices=SourceType.choices)
    amount = models.DecimalField(max_digits=12, decimal_places=2)
    reference_id = models.CharField(max_length=64)
    remarks = models.CharField(max_length=500, blank=True, default='')
    metadata = models.JSONField(blank=True, null=True)
    created_at = models.DateTimeField(auto_now_add=True)

    class Meta:
        ordering = ['-created_at']
        indexes = [
            models.Index(fields=['user', 'created_at']),
            models.Index(fields=['wallet', 'created_at']),
            models.Index(fields=['reference_id']),
            models.Index(fields=['created_at']),
        ]
        constraints = [
            models.UniqueConstraint(fields=['reference_id', 'source_type'], name='unique_reference_source')
        ]

    def __str__(self):
        return f"{self.transaction_type} {self.amount} for {self.user_id} ({self.reference_id})"


class UserVoucherCode(models.Model):
    class Status(models.TextChoices):
        ACTIVE = 'ACTIVE', 'Active'
        PARTIAL = 'PARTIAL', 'Partially Used'
        USED = 'USED', 'Used'
        EXPIRED = 'EXPIRED', 'Expired'

    user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE, related_name='voucher_codes')
    wallet = models.ForeignKey(Wallet, on_delete=models.CASCADE, related_name='voucher_codes')
    code = models.CharField(max_length=32, unique=True, db_index=True)
    total_value = models.DecimalField(max_digits=12, decimal_places=2)
    remaining_value = models.DecimalField(max_digits=12, decimal_places=2)
    source_reference_id = models.CharField(max_length=64, db_index=True)
    expires_at = models.DateTimeField(blank=True, null=True, db_index=True)
    status = models.CharField(max_length=12, choices=Status.choices, default=Status.ACTIVE, db_index=True)
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)

    class Meta:
        ordering = ['-created_at']
        indexes = [
            models.Index(fields=['user', 'status', 'created_at']),
            models.Index(fields=['wallet', 'status', 'created_at']),
        ]

    def __str__(self):
        return f"{self.code} ({self.user_id})"


class SuperCoinWallet(models.Model):
    user = models.OneToOneField(settings.AUTH_USER_MODEL, on_delete=models.CASCADE, related_name='super_coin_wallet')
    balance = models.DecimalField(max_digits=12, decimal_places=2, default=Decimal('0.00'))
    updated_at = models.DateTimeField(auto_now=True)

    class Meta:
        indexes = [
            models.Index(fields=['user']),
        ]

    def __str__(self):
        return f"SuperCoinWallet({self.user_id}) - Balance: {self.balance}"


class SuperCoinTransaction(models.Model):
    class TransactionType(models.TextChoices):
        CREDIT = 'CREDIT', 'Credit'
        DEBIT = 'DEBIT', 'Debit'

    class SourceType(models.TextChoices):
        LEVEL_REWARD = 'LEVEL_REWARD', 'Level Reward'
        PURCHASE = 'PURCHASE', 'Purchase'
        SERVICE_PAYMENT = 'SERVICE_PAYMENT', 'Service Payment'
        MONTHLY_CONVERSION = 'MONTHLY_CONVERSION', 'Monthly Conversion'
        ADJUSTMENT = 'ADJUSTMENT', 'Adjustment'

    user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE, related_name='super_coin_transactions')
    wallet = models.ForeignKey(SuperCoinWallet, on_delete=models.CASCADE, related_name='transactions')
    transaction_type = models.CharField(max_length=8, choices=TransactionType.choices)
    source_type = models.CharField(max_length=24, choices=SourceType.choices)
    amount = models.DecimalField(max_digits=12, decimal_places=2)
    reference_id = models.CharField(max_length=64, db_index=True)
    metadata = models.JSONField(blank=True, null=True)
    created_at = models.DateTimeField(auto_now_add=True)

    class Meta:
        ordering = ['-created_at']
        indexes = [
            models.Index(fields=['user', 'created_at']),
            models.Index(fields=['wallet', 'created_at']),
            models.Index(fields=['reference_id']),
        ]
        constraints = [
            models.UniqueConstraint(fields=['reference_id', 'source_type'], name='uniq_super_coin_reference_source')
        ]


class TDSLedger(models.Model):
    class Context(models.TextChoices):
        LEVEL_REWARD = 'LEVEL_REWARD', 'Level Reward'
        CONVERSION = 'CONVERSION', 'Conversion'
        WITHDRAWAL = 'WITHDRAWAL', 'Withdrawal'

    user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE, related_name='tds_ledgers')
    distributor_id = models.CharField(max_length=64, blank=True, null=True, db_index=True)
    context = models.CharField(max_length=20, choices=Context.choices, db_index=True)
    gross_amount = models.DecimalField(max_digits=12, decimal_places=2)
    tds_percent = models.DecimalField(max_digits=6, decimal_places=3)
    tds_amount = models.DecimalField(max_digits=12, decimal_places=2)
    reference_id = models.CharField(max_length=64, db_index=True)
    month = models.DateField(blank=True, null=True, db_index=True)
    metadata = models.JSONField(blank=True, null=True)
    created_at = models.DateTimeField(auto_now_add=True)

    class Meta:
        ordering = ['-created_at']
        indexes = [
            models.Index(fields=['user', 'context', 'created_at']),
            models.Index(fields=['month', 'context']),
            models.Index(fields=['reference_id']),
        ]


class ConversionRule(models.Model):
    user = models.OneToOneField(settings.AUTH_USER_MODEL, on_delete=models.CASCADE, related_name='conversion_rule')
    distributor_id = models.CharField(max_length=64, db_index=True)
    monthly_limit = models.DecimalField(max_digits=12, decimal_places=2, default=Decimal('0.00'))
    conversion_percentage = models.DecimalField(max_digits=6, decimal_places=3, blank=True, null=True)
    is_active = models.BooleanField(default=True, db_index=True)
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)

    class Meta:
        indexes = [
            models.Index(fields=['distributor_id', 'is_active']),
        ]


class MonthlyConversionLog(models.Model):
    user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE, related_name='monthly_conversion_logs')
    distributor_id = models.CharField(max_length=64, db_index=True)
    total_supercoins = models.DecimalField(max_digits=12, decimal_places=2)
    converted_amount = models.DecimalField(max_digits=12, decimal_places=2)
    tds_deducted = models.DecimalField(max_digits=12, decimal_places=2)
    net_amount = models.DecimalField(max_digits=12, decimal_places=2)
    month = models.DateField(db_index=True)
    reference_id = models.CharField(max_length=64, db_index=True)
    created_at = models.DateTimeField(auto_now_add=True)

    class Meta:
        ordering = ['-month', '-created_at']
        constraints = [
            models.UniqueConstraint(fields=['user', 'month'], name='uniq_monthly_conversion_per_user')
        ]


class TWMCoinGrant(models.Model):
    user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE, related_name='twm_coin_grants')
    granted_by = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.SET_NULL, null=True, blank=True, related_name='twm_coin_grants_made')
    amount = models.DecimalField(max_digits=12, decimal_places=2)
    expiry_days = models.PositiveIntegerField(default=0)
    expires_at = models.DateTimeField(blank=True, null=True, db_index=True)
    reason = models.CharField(max_length=500)
    reference_id = models.CharField(max_length=64, unique=True, db_index=True)
    created_at = models.DateTimeField(auto_now_add=True)

    class Meta:
        ordering = ['-created_at']
        indexes = [
            models.Index(fields=['user', 'created_at']),
            models.Index(fields=['expires_at']),
        ]

    def __str__(self):
        return f"{self.user_id} {self.amount} ({self.reference_id})"