from django.core.management.base import BaseCommand
from django.conf import settings
import json

from recharge.services.goterpay_api import GoterPayAPI, GoterPayConfig, GoterPayError

# Optional: use your shared generator if you have it
try:
    from utils.ids import generate_unique_provider_txnid as gen_txn
except Exception:
    # Fallback: simple generator (no DB uniqueness check)
    import random, string
    ALPHANUM = string.digits + string.ascii_uppercase
    def gen_txn(prefix="VP", length=10):
        prefix = (prefix or "").upper()[:length]
        body_len = max(0, length - len(prefix))
        return (prefix + "".join(random.choices(ALPHANUM, k=body_len)))[:length]


class Command(BaseCommand):
    help = "Check Goter BillFetch for a given operator & number (uses settings.RECHARGE_PROVIDERS['goterpay'])"

    def add_arguments(self, parser):
        parser.add_argument("operator", type=str, help="Operator code (e.g., ADEM, WBSEDCL, etc.)")
        parser.add_argument("number", type=str, help="Consumer/Account number")
        parser.add_argument("--optional1", type=str, default=None, help="Optional1 if required by the operator")
        parser.add_argument("--txnid", type=str, default=None, help="Custom txnid (<=10 chars). If omitted, auto-generated.")
        parser.add_argument("--timeout", type=int, default=20, help="HTTP timeout seconds")

    def handle(self, *args, **opts):
        operator = opts["operator"].strip()
        number = opts["number"].strip()
        optional1 = (opts["optional1"] or None)
        timeout = opts["timeout"]

        # Read Goter config from settings
        goter_cfg = settings.RECHARGE_PROVIDERS.get("goterpay", {}) or {}
        mid = goter_cfg.get("mid")
        mkey = goter_cfg.get("mkey")
        subwallet = goter_cfg.get("subwallet")  # not required for BillFetch
        if not mid or not mkey:
            self.stderr.write(self.style.ERROR("Missing creds: RECHARGE_PROVIDERS['goterpay']['mid'/'mkey']"))
            return

        # Prepare API client
        api = GoterPayAPI(GoterPayConfig(mid=mid, mkey=mkey, subwallet=subwallet, timeout=timeout))

        # TxnId must be <= 10 chars
        txnid = (opts["txnid"] or gen_txn("VP", 10))[:10]

        self.stdout.write(self.style.NOTICE(f"BillFetch → operator={operator} number={number} txnid={txnid}"))
        if optional1:
            self.stdout.write(self.style.NOTICE(f"Optional1  : {optional1}"))

        try:
            resp = api.bill_fetch(number=number, operator_code=operator, txnid=txnid, optional1=optional1)
        except GoterPayError as ge:
            self.stderr.write(self.style.ERROR(f"GoterPayError: {ge} [status={ge.status_code}]"))
            if ge.payload:
                self.stderr.write(str(ge.payload))
            return
        except Exception as e:
            self.stderr.write(self.style.ERROR(f"Unexpected error: {e}"))
            return

        # Full JSON
        self.stdout.write(self.style.SUCCESS("✅ API call successful"))
        try:
            self.stdout.write(json.dumps(resp, indent=2, ensure_ascii=False))
        except Exception:
            self.stdout.write(str(resp))

        # Summary (based on the sample you shared)
        try:
            status = resp.get("status") or resp.get("Status")
            message = resp.get("message") or resp.get("Message") or resp.get("resText") or ""
            op_name = resp.get("operator")
            due_amount = resp.get("dueAmount") or resp.get("billAmount")
            due_date = resp.get("dueDate")
            cust = resp.get("customerName")
            bill_no = resp.get("billNumber")
            bill_date = resp.get("billDate")
            bill_period = resp.get("billPeriod")
            ref_id = resp.get("refId") or resp.get("RefId")

            self.stdout.write("\n--- Summary ---")
            self.stdout.write(f"Status       : {status}")
            if message:     self.stdout.write(f"Message      : {message}")
            if op_name:     self.stdout.write(f"Operator     : {op_name}")
            if cust:        self.stdout.write(f"Customer     : {cust}")
            if due_amount:  self.stdout.write(f"Due Amount   : {due_amount}")
            if due_date:    self.stdout.write(f"Due Date     : {due_date}")
            if bill_no:     self.stdout.write(f"Bill Number  : {bill_no}")
            if bill_date:   self.stdout.write(f"Bill Date    : {bill_date}")
            if bill_period: self.stdout.write(f"Bill Period  : {bill_period}")
            if ref_id:      self.stdout.write(f"Ref Id       : {ref_id}")
        except Exception:
            # summary is best-effort; ignore if structure differs
            pass
