"""One-shot script: rewrites withdrawal_service.py cleanly."""
import pathlib

target = pathlib.Path("apps/business/withdrawals/services/withdrawal_service.py")

content = """\
import logging
logger = logging.getLogger("withdrawals")
from django.db import transaction
from django.utils import timezone
from decimal import Decimal, ROUND_HALF_UP
from ..models import WithdrawalDeductionConfig, WithdrawalRequest
from apps.business.wallet.models import Wallet
from apps.core.events import emit_event


def create_withdrawal_request(user, amount, bank_account=None):
    now = timezone.now()
    start_of_month = now.replace(day=1, hour=0, minute=0, second=0, microsecond=0)
    if WithdrawalRequest.objects.filter(user=user, created_at__gte=start_of_month).exists():
        raise Exception('Only one withdrawal allowed per user per month.')
    with transaction.atomic():
        wallet = Wallet.objects.select_for_update().get(user=user)
        amount = Decimal(amount)
        if amount <= 0:
            raise Exception('Withdrawal amount must be positive.')
        available_balance = wallet.main_balance - wallet.locked_amount
        if amount > available_balance:
            raise Exception('Insufficient available balance.')

        deduction_config = WithdrawalDeductionConfig.objects.filter(is_active=True).order_by('-updated_at').first()
        if not deduction_config:
            deduction_config = WithdrawalDeductionConfig.objects.create(
                name='Default',
                tds_percent=Decimal('5.000'),
                repurchase_percent=Decimal('5.000'),
                welfare_fund_percent=Decimal('5.000'),
                technology_charges_percent=Decimal('5.000'),
                operations_charges_percent=Decimal('5.000'),
                is_active=True,
            )

        tds_amount = (amount * Decimal(deduction_config.tds_percent) / Decimal('100')).quantize(Decimal('0.01'), rounding=ROUND_HALF_UP)
        other_percent = (
            Decimal(deduction_config.repurchase_percent)
            + Decimal(deduction_config.welfare_fund_percent)
            + Decimal(deduction_config.technology_charges_percent)
            + Decimal(deduction_config.operations_charges_percent)
        )
        admin_fee_amount = (amount * other_percent / Decimal('100')).quantize(Decimal('0.01'), rounding=ROUND_HALF_UP)
        processing_fee_amount = Decimal('0.00')

        total_deduction_amount = (tds_amount + admin_fee_amount + processing_fee_amount).quantize(Decimal('0.01'), rounding=ROUND_HALF_UP)
        net_amount = (amount - total_deduction_amount).quantize(Decimal('0.01'), rounding=ROUND_HALF_UP)

        if net_amount < 0:
            raise Exception('Configured deductions exceed requested amount.')

        wallet.locked_amount += amount
        if wallet.locked_amount < 0:
            logger.error({"event": "wallet_negative_lock", "user": user.id, "locked_amount": str(wallet.locked_amount)})
            raise Exception('Wallet locked amount cannot be negative.')
        wallet.save(update_fields=['locked_amount'])
        withdrawal = WithdrawalRequest.objects.create(
            user=user,
            bank_account=bank_account,
            amount_requested=amount,
            tds_amount=tds_amount,
            admin_fee_amount=admin_fee_amount,
            processing_fee_amount=processing_fee_amount,
            total_deduction_amount=total_deduction_amount,
            net_amount=net_amount,
            deduction_config=deduction_config,
            status=WithdrawalRequest.Status.PENDING
        )
        withdrawal.reference_id = f"WITHDRAW_{withdrawal.id}"
        withdrawal.save(update_fields=["reference_id"])
        logger.info({"event": "withdrawal_created", "user": user.id, "withdrawal_id": withdrawal.id, "amount": str(amount), "reference_id": withdrawal.reference_id})
        emit_event(
            "withdrawal_requested",
            {
                "user_id": user.id,
                "distributor_id": None,
                "amount": str(amount),
                "reference_id": withdrawal.reference_id,
            }
        )
        return withdrawal


def process_withdrawal(request_id, action, remarks=None):
    with transaction.atomic():
        withdrawal = WithdrawalRequest.objects.select_for_update().get(id=request_id)
        wallet = Wallet.objects.select_for_update().get(user=withdrawal.user)

        if withdrawal.status == WithdrawalRequest.Status.PAID:
            raise Exception('Withdrawal already paid.')

        if action == 'APPROVE':
            if withdrawal.status != WithdrawalRequest.Status.PENDING:
                raise Exception('Only pending withdrawals can be approved.')
            withdrawal.status = WithdrawalRequest.Status.APPROVED
            withdrawal.processed_at = timezone.now()
            logger.info({"event": "withdrawal_approved", "withdrawal_id": withdrawal.id, "user": withdrawal.user.id})

        elif action == 'REJECT':
            if withdrawal.status not in [WithdrawalRequest.Status.PENDING, WithdrawalRequest.Status.APPROVED]:
                raise Exception('Only pending or approved withdrawals can be rejected.')
            wallet.locked_amount = max(Decimal('0'), wallet.locked_amount - withdrawal.amount_requested)
            wallet.save(update_fields=['locked_amount'])
            withdrawal.status = WithdrawalRequest.Status.REJECTED
            withdrawal.processed_at = timezone.now()
            logger.info({"event": "withdrawal_rejected", "withdrawal_id": withdrawal.id, "user": withdrawal.user.id})

        elif action == 'PAID':
            if withdrawal.status != WithdrawalRequest.Status.APPROVED:
                raise Exception('Only approved withdrawals can be marked as paid.')
            if wallet.main_balance < withdrawal.amount_requested:
                raise Exception('Insufficient wallet balance for payout.')
            wallet.main_balance -= withdrawal.amount_requested
            wallet.locked_amount = max(Decimal('0'), wallet.locked_amount - withdrawal.amount_requested)
            wallet.save(update_fields=['main_balance', 'locked_amount'])
            withdrawal.status = WithdrawalRequest.Status.PAID
            withdrawal.processed_at = timezone.now()
            logger.info({"event": "withdrawal_paid", "withdrawal_id": withdrawal.id, "user": withdrawal.user.id})
            emit_event(
                "withdrawal_paid",
                {
                    "user_id": withdrawal.user.id,
                    "distributor_id": None,
                    "amount": str(withdrawal.amount_requested),
                    "reference_id": withdrawal.reference_id,
                }
            )
        else:
            raise Exception('Invalid action.')

        if remarks:
            withdrawal.remarks = remarks
        withdrawal.save()
        return withdrawal
"""

target.write_text(content, encoding='utf-8')
print(f"Written {len(content.splitlines())} lines to {target}")
