from recharge.utils import *
from decimal import Decimal, InvalidOperation, ROUND_HALF_UP
import logging

TWOPL = Decimal("0.01")
def _d(x):
    try:
        return Decimal(str(x))
    except (InvalidOperation, ValueError, TypeError):
        return Decimal("0")
def q2(x: Decimal) -> Decimal:
    return _d(x).quantize(TWOPL, rounding=ROUND_HALF_UP)

def perform_wallet_recharge(
    user,
    number,
    operator,
    circle,
    # legacy param:
    amount=None,                   # "1353.46" or Decimal
    # new params (preferred):
    amount_rupees=None,            # "1353.46" or Decimal
    amount_paise=None,             # int 135346 (optional; not needed for Goter)
    order_id=None,
    client_txn_id=None,
    use_ext="0.00",                # rupees; accept str/Decimal
    use_int="0.00",                # rupees; accept str/Decimal
    gateway_ref=None,              # human-friendly label like "External + Razorpay"
    # pass real Razorpay IDs (optional):
    razorpay_order_id=None,
    razorpay_payment_id=None,
):
    """
    Normalizes money, forwards to initiate_recharge exactly as Goter expects
    (amount as a rupee string with 2 decimals), and returns a normalized dict.
    """
    log = logging.getLogger(__name__)
    # ---- normalize money ----
    amt_r = q2(_d(amount_rupees if amount_rupees is not None else amount))
    use_ext_r = q2(_d(use_ext))
    use_int_r = q2(_d(use_int))

    # ---- call the provider flow ----
    result = initiate_recharge(
        user=user,
        number=number,
        operator=operator,
        circle=circle,
        amount=amt_r,                      # Decimal(2dp); initiate_recharge will format `f"{amt_r:.2f}"`
        order_id=order_id,
        client_txn_id=client_txn_id,
        use_ext=use_ext_r,                 # Decimal(2dp)
        use_int=use_int_r,                 # Decimal(2dp)
        gateway_ref=gateway_ref,           # label only
        razorpay_order_id=razorpay_order_id,
        razorpay_payment_id=razorpay_payment_id,
    )
    log.info("Inside Perform wallet recharge, printing initiate recharge result ")
    log.info(result)

    return {
        "status": result.get("status"),
        "message": result.get("message"),
        "transaction_id": result.get("client_txn_id"),
        "provider_ref": result.get("provider_order_id"),
    }

# accounts/utils.py  (or wherever perform_wallet_recharge lives)

from utilities.utils import initiate_bill_payment

def perform_bill_payment(
    *,
    user,
    service: str,
    provider: str,
    fields: dict,
    amount=None,                # legacy string rupees "1353.46"
    amount_rupees=None,         # new string rupees "1353.46"
    amount_paise=None,          # new int 135346
    order_id: str,
    client_txn_id: str,
    use_ext="0.00",
    use_int="0.00",
    gateway_ref: str | None,
    razorpay_order_id: str | None = None,
    razorpay_payment_id: str | None = None,
):
    res = initiate_bill_payment(
        user=user,
        service=service,
        provider=provider,
        fields=fields,
        amount=amount_rupees or amount,        # Decimal-normalized inside
        amount_paise=amount_paise,             # optional; preferred by adapters
        order_id=order_id,
        client_txn_id=client_txn_id,
        use_ext=use_ext,
        use_int=use_int,
        gateway_ref=gateway_ref,
        razorpay_order_id=razorpay_order_id,
        razorpay_payment_id=razorpay_payment_id,
    )
    return {
        "status": res.get("status"),
        "message": res.get("message"),
        "transaction_id": res.get("client_txn_id"),
        "provider_ref": res.get("provider_order_id"),
    }



# api/utils.py
from datetime import datetime, timedelta
from django.db.models import Q

DATE_FMT = "%Y-%m-%d"

def parse_range(start_str, end_str):
    """
    Returns (start_dt, end_dt) inclusive. If only one is present, use that bound only.
    End is normalized to end-of-day when given as date without time.
    """
    start_dt = None
    end_dt = None
    if start_str:
        start_dt = datetime.strptime(start_str, DATE_FMT)
    if end_str:
        end_dt = datetime.strptime(end_str, DATE_FMT) + timedelta(days=1) - timedelta(seconds=1)
    return start_dt, end_dt

def add_range(qs, field_name, start_dt, end_dt):
    if start_dt and end_dt:
        return qs.filter(**{f"{field_name}__range": (start_dt, end_dt)})
    if start_dt:
        return qs.filter(**{f"{field_name}__gte": start_dt})
    if end_dt:
        return qs.filter(**{f"{field_name}__lte": end_dt})
    return qs

