# payments/views_bulk_inspect.py
import time
from typing import List, Dict, Any
import razorpay
from django.conf import settings
from django.contrib.auth.mixins import LoginRequiredMixin
from django.shortcuts import render
from django.views import View
from django.db.models import Q

from payments.models import PaymentTransaction  # adjust if your path differs

def _parse_ids(raw: str) -> List[str]:
    """
    Accepts textarea content with IDs (one per line, csv, or space separated),
    cleans up and deduplicates while preserving order.
    """
    tokens = []
    for line in (raw or "").replace(",", "\n").splitlines():
        t = line.strip()
        if t:
            tokens.append(t)
    # dedupe preserving order
    seen = set()
    out = []
    for t in tokens:
        if t not in seen:
            seen.add(t)
            out.append(t)
    return out

class BulkPaymentInspectView(LoginRequiredMixin, View):
    """
    Paste many VP order_ids or Razorpay order_ids and get
    a flat grid of local + Razorpay order + Razorpay payments.
    One row per (order × payment). If an order has no payments,
    we still emit one row with '—' for payment fields.
    """
    template_name = "payments/payment_inspect_bulk.html"

    def get(self, request):
        return render(request, self.template_name, {"raw_ids": "", "rows": None, "error": None})

    def post(self, request):
        raw_ids = request.POST.get("raw_ids", "")
        ids = _parse_ids(raw_ids)
        if not ids:
            return render(request, self.template_name, {"raw_ids": raw_ids, "rows": None, "error": "Please paste at least one ID."})

        client = razorpay.Client(auth=(settings.RAZORPAY_API_KEY, settings.RAZORPAY_API_SECRET))

        rows: List[Dict[str, Any]] = []

        # Light rate-limit cushion so Razorpay doesn’t throttle if the list is huge.
        # Tweak/disable if you’re well within their limits.
        SLEEP_EVERY = 25
        SLEEP_SECS = 0.6

        for idx, q in enumerate(ids, start=1):
            looks_like_rzp = q.startswith("order_")

            # Local tx lookup by either VP order_id or razorpay_order_id
            tx = (PaymentTransaction.objects
                  .filter(Q(order_id=q) | Q(razorpay_order_id=q))
                  .order_by("-created_at")
                  .first())

            rzp_order_id = None
            if looks_like_rzp:
                rzp_order_id = q
            elif tx and tx.razorpay_order_id:
                rzp_order_id = tx.razorpay_order_id

            rzp_order = None
            rzp_payments = []
            rzp_err = None

            try:
                if rzp_order_id:
                    rzp_order = client.order.fetch(rzp_order_id)
                    rzp_payments = client.order.payments(rzp_order_id).get("items", [])
                    # show newest first
                    rzp_payments.sort(key=lambda p: p.get("created_at", 0), reverse=True)
            except Exception as e:
                rzp_err = str(e)

            # If there are no payments, still emit a row so you see the order
            if not rzp_payments:
                rows.append({
                    # Local
                    "order_id": tx.order_id if tx else (q if not looks_like_rzp else "—"),
                    "service": getattr(tx, "service", "—") if tx else "—",
                    "amount": getattr(tx, "amount", "—") if tx else "—",
                    "local_status": getattr(tx, "status", "—") if tx else "—",

                    # Razorpay order
                    "rzp_order_id": rzp_order.get("id") if rzp_order else (rzp_order_id or "—"),
                    "rzp_order_status": rzp_order.get("status") if rzp_order else ("—" if not rzp_err else f"error: {rzp_err}"),
                    "rzp_order_amount": rzp_order.get("amount") if rzp_order else "—",
                    "rzp_order_amount_paid": rzp_order.get("amount_paid") if rzp_order else "—",
                    "rzp_order_currency": rzp_order.get("currency") if rzp_order else "—",
                    "rzp_order_created_at": rzp_order.get("created_at") if rzp_order else "—",

                    # Payment (none)
                    "rzp_payment_id": "—",
                    "rzp_payment_status": "—",
                    "rzp_payment_amount": "—",
                    "rzp_payment_currency": "—",
                    "rzp_payment_method": "—",
                    "rzp_payment_email": "—",
                    "rzp_payment_contact": "—",
                    "rzp_payment_created_at": "—",

                    # Copy string
                    "copy_string": f"{tx.order_id if tx else (q if not looks_like_rzp else '')} | {(rzp_order.get('id') if rzp_order else (rzp_order_id or ''))} |  |  | {getattr(tx, 'amount', '') if tx else ''}".strip()
                })
            else:
                # Emit one row per payment
                for p in rzp_payments:
                    rows.append({
                        # Local
                        "order_id": tx.order_id if tx else (q if not looks_like_rzp else "—"),
                        "service": getattr(tx, "service", "—") if tx else "—",
                        "amount": getattr(tx, "amount", "—") if tx else "—",
                        "local_status": getattr(tx, "status", "—") if tx else "—",

                        # Razorpay order
                        "rzp_order_id": rzp_order.get("id") if rzp_order else (rzp_order_id or "—"),
                        "rzp_order_status": rzp_order.get("status") if rzp_order else "—",
                        "rzp_order_amount": rzp_order.get("amount") if rzp_order else "—",
                        "rzp_order_amount_paid": rzp_order.get("amount_paid") if rzp_order else "—",
                        "rzp_order_currency": rzp_order.get("currency") if rzp_order else "—",
                        "rzp_order_created_at": rzp_order.get("created_at") if rzp_order else "—",

                        # Payment
                        "rzp_payment_id": p.get("id", "—"),
                        "rzp_payment_status": p.get("status", "—"),
                        "rzp_payment_amount": p.get("amount", "—"),
                        "rzp_payment_currency": p.get("currency", "—"),
                        "rzp_payment_method": p.get("method", "—"),
                        "rzp_payment_email": p.get("email", "—"),
                        "rzp_payment_contact": p.get("contact", "—"),
                        "rzp_payment_created_at": p.get("created_at", "—"),

                        # Copy string (orderid | razorpay order_id | razorpay payment id | method, contact | amount)
                        "copy_string": f"{tx.order_id if tx else (q if not looks_like_rzp else '')} | {rzp_order.get('id') if rzp_order else (rzp_order_id or '')} | {p.get('id','')} | {p.get('method','')}, {p.get('contact','')} | {getattr(tx,'amount','') if tx else ''}".strip()
                    })

            # Gentle throttle
            if idx % SLEEP_EVERY == 0:
                time.sleep(SLEEP_SECS)

        return render(request, self.template_name, {
            "raw_ids": raw_ids,
            "rows": rows,
            "error": None
        })
