from decimal import Decimal, ROUND_HALF_UP

from apps.business.wallet.models import TDSLedger
from apps.business.wallet.services.wallet_service import WalletService


def _q(value):
    return Decimal(str(value)).quantize(Decimal('0.01'), rounding=ROUND_HALF_UP)


def _get_active_deduction_config():
    from apps.business.withdrawals.models import WithdrawalDeductionConfig

    return (
        WithdrawalDeductionConfig.objects.filter(is_active=True)
        .order_by('-updated_at')
        .first()
    )


def apply_deductions(amount):
    """Apply reward deductions and return a structured breakdown."""
    gross_amount = _q(amount)
    config = _get_active_deduction_config()

    tds_percent = Decimal(str(getattr(config, 'tds_percent', Decimal('5.000'))))
    repurchase_percent = Decimal(str(getattr(config, 'repurchase_percent', Decimal('5.000'))))
    welfare_percent = Decimal(str(getattr(config, 'welfare_fund_percent', Decimal('5.000'))))
    technology_percent = Decimal(str(getattr(config, 'technology_charges_percent', Decimal('5.000'))))
    operations_percent = Decimal(str(getattr(config, 'operations_charges_percent', Decimal('5.000'))))

    tds_amount = _q(gross_amount * tds_percent / Decimal('100'))
    repurchase_amount = _q(gross_amount * repurchase_percent / Decimal('100'))
    welfare_amount = _q(gross_amount * welfare_percent / Decimal('100'))
    technology_amount = _q(gross_amount * technology_percent / Decimal('100'))
    operations_amount = _q(gross_amount * operations_percent / Decimal('100'))

    internal_total = _q(repurchase_amount + welfare_amount + technology_amount + operations_amount)
    super_coin_credit = _q(gross_amount - internal_total)
    if super_coin_credit < Decimal('0.00'):
        super_coin_credit = Decimal('0.00')

    return {
        'gross_amount': gross_amount,
        'tds_percent': tds_percent,
        'tds_amount': tds_amount,
        'repurchase_percent': repurchase_percent,
        'repurchase_amount': repurchase_amount,
        'welfare_percent': welfare_percent,
        'welfare_amount': welfare_amount,
        'technology_percent': technology_percent,
        'technology_amount': technology_amount,
        'operations_percent': operations_percent,
        'operations_amount': operations_amount,
        'internal_total': internal_total,
        'super_coin_credit': super_coin_credit,
    }


def credit_supercoins(user, amount, source_type, reference_id, metadata=None):
    return WalletService.credit_supercoins(
        user=user,
        amount=amount,
        source_type=source_type,
        reference_id=reference_id,
        metadata=metadata or {},
    )


def process_level_reward(user, distributor_id, level_number, reward_amount):
    """Process a single level reward with TDS audit and super coin credit."""
    reference_id = f"LEVEL_REWARD_{distributor_id}_{level_number}"
    deductions = apply_deductions(reward_amount)

    TDSLedger.objects.create(
        user=user,
        distributor_id=str(distributor_id),
        context=TDSLedger.Context.LEVEL_REWARD,
        gross_amount=deductions['gross_amount'],
        tds_percent=deductions['tds_percent'],
        tds_amount=deductions['tds_amount'],
        reference_id=reference_id,
        metadata={
            'level_number': level_number,
            'repurchase_amount': str(deductions['repurchase_amount']),
            'welfare_amount': str(deductions['welfare_amount']),
            'technology_amount': str(deductions['technology_amount']),
            'operations_amount': str(deductions['operations_amount']),
        },
    )

    if deductions['super_coin_credit'] > Decimal('0.00'):
        credit_supercoins(
            user=user,
            amount=deductions['super_coin_credit'],
            source_type='LEVEL_REWARD',
            reference_id=reference_id,
            metadata={
                'level_number': level_number,
                'gross_amount': str(deductions['gross_amount']),
            },
        )

    return {
        'reference_id': reference_id,
        **{k: str(v) if isinstance(v, Decimal) else v for k, v in deductions.items()},
    }
