# Payments/ids.py

import secrets
import string

ALPHANUM = string.ascii_uppercase + string.digits  # A–Z0–9

def generate_client_txn_id(prefix: str = "VP", length: int = 10) -> str:
    prefix = (prefix or "").upper()
    if len(prefix) > length:
        raise ValueError(f"prefix '{prefix}' longer than length {length}")
    body_len = length - len(prefix)
    tail = ''.join(secrets.choice(ALPHANUM) for _ in range(body_len))
    return prefix + tail

from django.db import IntegrityError, transaction
from recharge.models import RechargeTransaction

def generate_and_reserve_client_txn_id(prefix="VP", length=10) -> str:
    for _ in range(5):
        candidate = generate_client_txn_id(prefix, length)
        try:
            with transaction.atomic():
                # Reserve via a tiny placeholder row if that fits your flow,
                # or better: only use create_txn_safely() above.
                RechargeTransaction.objects.create(client_txn_id=candidate)
                return candidate
        except IntegrityError:
            continue
    raise RuntimeError("Could not reserve a unique client_txn_id")


import random
import string
from recharge.models import RechargeTransaction

ALPHANUM = string.digits + string.ascii_uppercase

def generate_unique_provider_txnid(prefix="VP", length=10) -> str:
    """
    Generate a unique alphanumeric txnid for provider calls.
    Ensures length <= `length` and uniqueness in RechargeTransaction.
    """
    prefix = (prefix or "").upper()
    body_len = max(0, length - len(prefix))

    while True:
        body = "".join(random.choices(ALPHANUM, k=body_len))
        txnid = (prefix + body)[:length]
        # Check uniqueness in DB
        if not RechargeTransaction.objects.filter(client_txn_id=txnid).exists():
            return txnid
