# accounts/views_admin_v2.py  (add or replace the earlier OrderAuditListV2API)
from datetime import datetime, timezone, timedelta
from django.utils.decorators import method_decorator
from django.views.decorators.cache import never_cache
from rest_framework.views import APIView
from django.shortcuts import render
from django.db.models import Q
from rest_framework.response import Response
from rest_framework.permissions import IsAdminUser
from django.contrib.admin.views.decorators import staff_member_required

from payments.models import PaymentTransaction, RechargePaymentSummary
from recharge.models import RechargeTransaction

# from accounts.models import PaymentTransaction, RechargeTransaction, RechargePaymentSummary

@staff_member_required
def order_audit_v2_page(request):
    # simple template render
    return render(request, "recharge_order_audit_v2.html", {})

def _dt(dt):
    if not dt: return None
    if isinstance(dt, str): return dt
    return dt.strftime("%Y-%m-%d %H:%M:%S")

def _norm(s):
    if not s: return "PENDING"
    s = str(s).strip().upper()
    if s in {"FAIL", "FAILED", "FAILURE"}: return "FAILURE"
    if s in {"ERROR", "ERR"}: return "ERROR"
    if s in {"SUCCESS", "VERIFIED", "CAPTURED", "PROCESSED"}: return "SUCCESS"
    if s in {"PENDING", "INITIATED", "PROCESSING", "INPROGRESS", "NOTREQUIRED"}: return "PENDING"
    return s

def _money(x):
    try: return float(x)
    except: return 0.0

from django.conf import settings
import pytz

def _parse_date_range_local(q_from, q_to, tz_name=None):
    if not tz_name:
        tz_name = getattr(settings, "TIME_ZONE", "Asia/Kolkata")
    tz = pytz.timezone(tz_name)

    start_utc = end_utc = None
    if q_from:
        y,m,d = map(int, q_from.split("-"))
        start_local = datetime(y,m,d, 0,0,0, tzinfo=tz)
        start_utc = start_local.astimezone(timezone.utc)
    if q_to:
        y,m,d = map(int, q_to.split("-"))
        # inclusive “to”: add 1 day and use < end
        end_local = datetime(y,m,d, 0,0,0, tzinfo=tz) + timedelta(days=1)
        end_utc = end_local.astimezone(timezone.utc)
    return start_utc, end_utc




@method_decorator(never_cache, name="dispatch")
class OrderAuditListV2API(APIView):
    """
    GET /api/recharge/admin/v2/order-audit/?page=1&page_size=25&from=YYYY-MM-DD&to=YYYY-MM-DD&order_id=VP...
    Returns a paginated list of consolidated orders (pt/rt/rps), sorted newest->oldest
    by RechargeTransaction.created_at (fallback: PaymentTransaction.created_at).

    Provider status is NOT embedded (to keep list fast). The HTML lazily calls your existing
    snapshot v2 endpoint with verify_provider=1 per row when needed.
    """
    permission_classes = [IsAdminUser]

    def get(self, request):
        q_from = (request.query_params.get("from") or "").strip()
        q_to   = (request.query_params.get("to") or "").strip()
        q_oid  = (request.query_params.get("order_id") or "").strip()
        
        q_rt  = (request.query_params.get("rt_status") or "").strip().upper()
        q_rps = (request.query_params.get("rps_status") or "").strip().upper()
        q_ref = (request.query_params.get("refunded") or "").strip()  # '1' means only refunded

        q_rt  = _norm(q_rt)
        q_rps = _norm(q_rps)

        start_utc, end_utc = _parse_date_range_local(q_from, q_to)

        try:
            page = max(1, int(request.query_params.get("page", 1)))
        except: page = 1
        try:
            page_size = min(200, max(1, int(request.query_params.get("page_size", 25))))
        except: page_size = 25

        # 1) Build a *bounded* order_id set using RechargeTransaction first (it has created_at)
        rt_qs = RechargeTransaction.objects.all()
        # if q_from: rt_qs = rt_qs.filter(created_at__date__gte=q_from)
        # if q_to:   rt_qs = rt_qs.filter(created_at__date__lte=q_to)
        # if q_oid:  rt_qs = rt_qs.filter(order_id__icontains=q_oid)

        if start_utc: rt_qs = rt_qs.filter(created_at__gte=start_utc)
        if end_utc:   rt_qs = rt_qs.filter(created_at__lt=end_utc)
        if q_oid:     rt_qs = rt_qs.filter(order_id__icontains=q_oid)
        if q_rt:      rt_qs = rt_qs.filter(status__iexact=q_rt)


        # If no dates provided, bound to recent (e.g., last 60 days) to avoid scanning the world
        if not q_from and not q_to:
            cutoff = datetime.now(tz=timezone.utc) - timedelta(days=60)
            rt_qs = rt_qs.filter(created_at__gte=cutoff)

        # newest -> oldest by created_at
        rt_ids_sorted = list(
            rt_qs.order_by("-created_at").values_list("order_id", flat=True).distinct()
        )

        # Also allow orders that exist only in PT/RPS (rare), but keep bounded
        # pt_qs = PaymentTransaction.objects.all()
        # rps_qs = RechargePaymentSummary.objects.all()
        # if q_from:
        #     pt_qs  = pt_qs.filter(created_at__date__gte=q_from)
        #     rps_qs = rps_qs.filter(updated_at__date__gte=q_from)
        # if q_to:
        #     pt_qs  = pt_qs.filter(created_at__date__lte=q_to)
        #     rps_qs = rps_qs.filter(updated_at__date__lte=q_to)
        # if q_oid:
        #     pt_qs  = pt_qs.filter(order_id__icontains=q_oid)
        #     rps_qs = rps_qs.filter(order_id__icontains=q_oid)

        # if not q_from and not q_to:
        #     cutoff = datetime.now(tz=timezone.utc) - timedelta(days=60)
        #     pt_qs = pt_qs.filter(created_at__gte=cutoff)
        # rps updated_at could be null; we won’t bound rps here
        pt_qs = PaymentTransaction.objects.all()
        rps_qs = RechargePaymentSummary.objects.all()
        if start_utc: pt_qs = pt_qs.filter(created_at__gte=start_utc)
        if end_utc:   pt_qs = pt_qs.filter(created_at__lt=end_utc)
        if q_oid:     pt_qs = pt_qs.filter(order_id__icontains=q_oid)

        if start_utc: rps_qs = rps_qs.filter(updated_at__gte=start_utc)
        if end_utc:   rps_qs = rps_qs.filter(updated_at__lt=end_utc)
        if q_oid:     rps_qs = rps_qs.filter(order_id__icontains=q_oid)
        if q_rps:     rps_qs = rps_qs.filter(recharge_status__iexact=q_rps)

        if not q_from and not q_to:
            cutoff = datetime.now(tz=timezone.utc) - timedelta(days=60)
            pt_qs = pt_qs.filter(created_at__gte=cutoff)



        if q_ref == "1":
            rps_ref_ids = set(
                rps_qs.filter(is_refunded=False).values_list("order_id", flat=True)
            )
            rt_ref_ids = set(
                rt_qs.filter(refund_status__in=["None"]).values_list("order_id", flat=True)
            )
            refunded_ids = rps_ref_ids #| rt_ref_ids
        else:
            refunded_ids = None


        # extra_ids = set(pt_qs.values_list("order_id", flat=True)) | set(rps_qs.values_list("order_id", flat=True))
        # # merge, preserving rt order first
        # seen = set(rt_ids_sorted)
        # merged_ids = rt_ids_sorted + [oid for oid in extra_ids if oid not in seen]

        rt_ids_sorted = list(rt_qs.order_by("-created_at").values_list("order_id", flat=True).distinct())
        extra_ids = set(pt_qs.values_list("order_id", flat=True)) | set(rps_qs.values_list("order_id", flat=True))
        seen = set(rt_ids_sorted)
        merged_ids = rt_ids_sorted + [oid for oid in extra_ids if oid not in seen]

        # If refunded=1, filter here
        if refunded_ids is not None:
            merged_ids = [oid for oid in merged_ids if oid in refunded_ids]


        total = len(merged_ids)
        start = (page-1) * page_size
        end   = start + page_size
        page_ids = merged_ids[start:end]

        rows = []
        for oid in page_ids:
            pt = PaymentTransaction.objects.filter(order_id=oid).order_by("-created_at").first()
            rt = RechargeTransaction.objects.filter(order_id=oid).order_by("-created_at").first()
            rps = RechargePaymentSummary.objects.filter(order_id=oid).order_by("-updated_at").first()

            rows.append({
                "order_id": oid,
                "amount": _money(getattr(pt, "amount", 0) or getattr(rt, "amount", 0)),
                "badges": {
                    "pt_wallet": _norm(getattr(pt, "wallet_status", None)),
                    "pt_gateway": _norm(getattr(pt, "status", None)),
                    "rt": _norm(getattr(rt, "status", None)),
                    "rps": _norm(getattr(rps, "recharge_status", None)),


                },
                # display dates (compact)
                "rt_created_at": _dt(getattr(rt, "created_at", None)),
                "pt_created_at": _dt(getattr(pt, "created_at", None)),

                # everything needed for row expansion
                "pt": {
                    "wallet_status": getattr(pt, "wallet_status", None),
                    "status": getattr(pt, "status", None),
                    "amount": getattr(pt, "amount", None),
                    "wallet_amount": getattr(pt, "wallet_amount", None),
                    "gateway_amount": getattr(pt, "gateway_amount", None),
                    "razorpay_order_id": getattr(pt, "razorpay_order_id", None),
                    "razorpay_payment_id": getattr(pt, "razorpay_payment_id", None),
                    "created_at": _dt(getattr(pt, "created_at", None)),
                },
                "rt": {
                    "operator_str": getattr(rt, "operator_str", None) if rt else getattr(getattr(rt, "operator", None), "name", None),
                    "circle_str": getattr(rt, "circle_str", None) if rt else getattr(getattr(rt, "circle", None), "name", None),
                    "number": getattr(rt, "number", None),
                    "created_at": _dt(getattr(rt, "created_at", None)),
                    "status": getattr(rt, "status", None),
                    "status_message": getattr(rt, "status_message", None),
                    "refund_status": getattr(rt, "refund_status", None),
                    "response_data": getattr(rt, "response_data", None),
                },
                "rps": {
                    "recharge_status": getattr(rps, "recharge_status", None),
                    "status_message": getattr(rps, "status_message", None),
                    "is_refunded": bool(getattr(rps, "is_refunded", False)),
                    "updated_at": _dt(getattr(rps, "updated_at", None)),
                    "refunded_on": _dt(getattr(rps, "refunded_on", None)),
                },
            })

        resp = Response({
            "page": page,
            "page_size": page_size,
            "total": total,
            "orders": rows,
        }, status=200)
        resp['Cache-Control'] = 'no-store, no-cache, must-revalidate, max-age=0'
        resp['Pragma'] = 'no-cache'
        resp['Expires'] = '0'
        return resp


