#payments/views.py
import uuid
import json
import hmac
import hashlib
from decimal import Decimal
from django.utils import timezone
from payments.utils import distribute_commissions

import razorpay

from django.conf import settings
from django.shortcuts import render, redirect, get_object_or_404
from django.http import JsonResponse
from django.views.decorators.csrf import csrf_exempt
from django.views.decorators.http import require_POST
from django.contrib import messages
from django.contrib.auth import get_user_model
from django.contrib.auth.decorators import login_required, user_passes_test
from django.core.paginator import Paginator
from django.db.models import Sum

from .models import (
    PaymentTransaction,
    RechargePaymentSummary,
    ExternalWalletTopUp,
    ExternalWalletUsage,
    ViralPeWallet,
    ViralPeWalletUsage,
)

from recharge.models import RechargeTransaction, Operator, Circle
from recharge.services.a1topup_api import A1TopupAPI
from notifications.services import send_notification

User = get_user_model()

# Staff-only decorator
def staff_only(view_func):
    return user_passes_test(lambda u: u.is_staff)(view_func)

@login_required
def recharge_page(request):
    return render(request, 'payments/recharge_page.html', {
        'razorpay_key_id': settings.RAZORPAY_API_KEY,  # 🚨 match this with JS variable
        'user_mobile': request.user.mobile_number,  # or .mobile if you have that field
        'user_email': request.user.email or "",
        'user_name': f"{request.user.first_name} {request.user.last_name}".strip()
    })

@csrf_exempt
def create_razorpay_order(request):
    try:
        data = json.loads(request.body)
        amount = int(float(data.get('amount', 0)) * 100)  # Convert to paise
        # print('-----------------create_razorpay_order-------------------------')
        # print("🔑 API KEY:", settings.RAZORPAY_API_KEY)
        # print("🔐 API SECRET (Hidden)", settings.RAZORPAY_API_SECRET)
        client = razorpay.Client(auth=(settings.RAZORPAY_API_KEY, settings.RAZORPAY_API_SECRET))
        order = client.order.create(dict(amount=amount, currency='INR', payment_capture='1'))

        transaction = PaymentTransaction.objects.create(
            user=request.user,
            amount=amount / 100,
            razorpay_order_id=order['id']
        )
        return JsonResponse(order)
    except Exception as e:
        print("⚠️ Razorpay Order Creation Failed:", str(e))
        return JsonResponse({"error": "Razorpay order creation failed."}, status=500)

@login_required
@csrf_exempt
def create_order(request):
    data = json.loads(request.body)
    amount = int(data["amount"]) * 100  # INR to paise

    client = razorpay.Client(auth=(settings.RAZORPAY_API_KEY, settings.RAZORPAY_API_SECRET))
    order = client.order.create(dict(amount=amount, currency="INR", payment_capture="1"))

    PaymentTransaction.objects.create(
        user=request.user, 
        amount=amount / 100,
        razorpay_order_id=order["id"]
    )
    return JsonResponse(order)



from django.db.models import Sum
from .models import ExternalWallet, ExternalWalletTransaction
# from accounts.models import User
from django.shortcuts import render, redirect
from django.contrib.admin.views.decorators import staff_member_required
from decimal import Decimal
from django.contrib.auth import get_user_model
User = get_user_model()
from decimal import Decimal, InvalidOperation  # ✅ Add at top
from decimal import Decimal, InvalidOperation
from django.shortcuts import render, redirect, get_object_or_404
from django.contrib.admin.views.decorators import staff_member_required
from django.conf import settings
from payments.models import ExternalWallet, ExternalWalletTransaction
from django.contrib.auth import get_user_model

User = get_user_model()

@staff_member_required
def external_wallet_topup_view(request):
    context = {
        'pagetitle': '💰 External Wallet Top-Up',
        'breadcrumbs': [
            {'label': 'Dashboard', 'url': reverse('dashboard')},
            {'label': 'Wallet Top-Up'}
        ]
    }

    user = None

    if request.method == 'POST':
        mobile = request.POST.get('mobile')
        amount_str = request.POST.get('amount')

        try:
            amount = Decimal(amount_str)
        except (InvalidOperation, TypeError):
            context['error'] = "Invalid amount entered."
            return render(request, 'payments/external_wallet_topup.html', context)

        if not mobile or amount <= 0:
            context['error'] = "Please enter both mobile number and a valid amount."
            return render(request, 'payments/external_wallet_topup.html', context)

        try:
            user = User.objects.get(mobile_number=mobile)
        except User.DoesNotExist:
            context['error'] = "User not found with this mobile number."
            return render(request, 'payments/external_wallet_topup.html', context)

        # Get or create wallet
        wallet, _ = ExternalWallet.objects.get_or_create(user=user)
        wallet.balance += amount
        wallet.save()

        # Log transaction
        ExternalWalletTransaction.objects.create(
            user=user,
            amount=amount,
            transaction_type="credit",
            purpose="Admin Top-Up",
            reference_user=request.user
        )

        return redirect(f"{request.path}?mobile={mobile}&success=1")  # Add success=1

    # On GET
    mobile = request.GET.get('mobile')
    if request.GET.get("success") == "1":
        context["success"] = True
        context["mobile"] = mobile

    if mobile:
        try:
            user = User.objects.get(mobile_number=mobile)
        except User.DoesNotExist:
            user = None

    if user:
        wallet, _ = ExternalWallet.objects.get_or_create(user=user)
        context['balance'] = wallet.balance
        context['target_user'] = user
        context['transactions'] = ExternalWalletTransaction.objects.filter(user=user).order_by('-created_at')[:10]

    return render(request, 'payments/external_wallet_topup.html', context)


from django.core.paginator import Paginator
from django.http import JsonResponse
from django.shortcuts import get_object_or_404
from django.conf import settings
from .models import ExternalWalletTransaction

User = settings.AUTH_USER_MODEL  # ✅ Best practice

@staff_only
def external_wallet_log_view(request, user_id):
    print("Fetching logs for user:", user_id)

    user = get_object_or_404(User, id=user_id)
    page = int(request.GET.get("page", 1))

    # logs_queryset = ExternalWalletTransaction.objects.filter(user=user).order_by("-used_on")
    logs_queryset = ExternalWalletTransaction.objects.filter(user=user).order_by('-created_at')

    paginator = Paginator(logs_queryset, 5)
    logs_page = paginator.get_page(page)

    log_data = [
        {
            "amount": float(log.amount),
            "used_on": log.created_at.strftime("%Y-%m-%d %H:%M"),
            "type": log.transaction_type,
            "purpose": log.purpose or "",
        }
        for log in logs_page
    ]

    return JsonResponse({
        "logs": log_data,
        "has_next": logs_page.has_next(),
        "has_previous": logs_page.has_previous(),
        "page_number": logs_page.number,
        "total_pages": paginator.num_pages,
    })

def initiate_razorpay_payment(request):
    amount = float(request.POST.get("amount"))  # in INR
    user = request.user
    client = razorpay.Client(auth=(settings.RAZORPAY_API_KEY, settings.RAZORPAY_API_SECRET))
    payment = client.order.create({'amount': int(amount * 100), 'currency': 'INR', 'payment_capture': '1'})

    transaction = PaymentTransaction.objects.create(
        user=user,
        amount=amount,
        razorpay_order_id=payment['id']
    )

    return JsonResponse({
        "order_id": payment['id'],
        "amount": amount,
        "key": settings.RAZORPAY_API_KEY,
    })

def perform_recharge_test(request):
    if request.method == "POST" and request.user.is_authenticated:
        amount = float(request.POST.get("amount", 0))
        amount_in_paise = int(amount * 100)
        print(amount_in_paise)
        print(settings.RAZORPAY_API_KEY)
        print(settings.RAZORPAY_API_SECRET)
        try:
            client = razorpay.Client(auth=(settings.RAZORPAY_API_KEY, settings.RAZORPAY_API_SECRET))
            razorpay_order = client.order.create({
                "amount": amount_in_paise,
                "currency": "INR",
                "payment_capture": "1"
            })
        except razorpay.errors.BadRequestError as e:
            print("Razorpay Error:", e)
            return JsonResponse({"error": "Razorpay Authentication Failed. Check your credentials."}, status=400)

        transaction = PaymentTransaction.objects.create(
            user=request.user,
            amount=amount,
            razorpay_order_id=razorpay_order["id"],
            status="initiated"
        )

        return JsonResponse({
            "order_id": razorpay_order["id"],
            "amount": amount_in_paise,
            "currency": "INR",
            "key": settings.RAZORPAY_API_KEY,
            "username": f"{request.user.first_name} {request.user.last_name}",
            "email": request.user.email or "",  # fallback in case it's null
            "mobile": request.user.mobile_number
        })

    return JsonResponse({"error": "Unauthorized or Invalid request"}, status=400)

@csrf_exempt
def perform_recharge(request):
    if request.method == "POST" and request.user.is_authenticated:
        try:
            number = request.POST.get("number")
            amount = Decimal(request.POST.get("amount", 0))
            operator = request.POST.get("operator")
            circle = request.POST.get("circle")
            use_ext = Decimal(request.POST.get("use_ext_wallet", 0))
            use_vp = Decimal(request.POST.get("use_viralpe_wallet", 0))

            # 🔐 Razorpay info (optional)
            razorpay_payment_id = request.POST.get("razorpay_payment_id") or None
            razorpay_order_id = request.POST.get("razorpay_order_id") or None

            # ✅ Validate amount
            if not (number and operator and circle and amount > 0):
                return JsonResponse({"error": "Missing or invalid recharge data"}, status=400)

            # 🧾 Generate order_id
            order_id = f"VP-{request.user.id}-{number[-4:]}-{uuid.uuid4().hex[:6].upper()}"

            # ✅ Deduct External Wallet
            if use_ext > 0:
                usage = ExternalWalletUsage.objects.create(
                    user=request.user,
                    amount_used=use_ext,
                    used_for=f"Recharge {number} - {order_id}"
                )
                print(use_ext)
                print("External Wallet Usage Created:", usage.id, usage.amount_used)


            # ✅ Deduct ViralPe Wallet
            if use_vp > 0:
                vp_wallet = ViralPeWallet.objects.filter(user=request.user).first()
                if vp_wallet and vp_wallet.balance >= use_vp:
                    print("Before Deducting:", vp_wallet.balance)
                    vp_wallet.balance -= use_vp
                    vp_wallet.save()
                    vp_usage = ViralPeWalletUsage.objects.create(
                        user=request.user,
                        amount_used=use_vp,
                        purpose=f"Recharge {number} - {order_id}"
                    )
                    # print("ViralPe Wallet Usage Created:", vp_usage.id, vp_usage.amount_used)
                else:
                    return JsonResponse({"error": "Insufficient ViralPe Wallet Balance"}, status=400)


            # 🔌 API Call
            a1_api = A1TopupAPI(settings.A1TOPUP_USERNAME, settings.A1TOPUP_PASSWORD)
            result = a1_api.make_recharge(
                circlecode=circle,
                operatorcode=operator,
                number=number,
                amount=float(amount),
                orderid=order_id
            )
            # 📝 Save Transaction
            transaction = RechargeTransaction.objects.create(
                operator=Operator.objects.get(code=operator),
                circle=Circle.objects.filter(code=circle).first(),
                number=number,
                amount=amount,
                order_id=order_id,
                status=result.get("status", "Pending"),  # fallback to 'Pending'
                status_updated_at=timezone.now(),  # ✅ NEW: Track update time
                response_data=result,
                used_ext_wallet=use_ext,           # ✅ NEW
                used_viralpe_wallet=use_vp,        # ✅ NEW
                razorpay_order_id=razorpay_order_id,  # ✅ NEW
                razorpay_payment_id=razorpay_payment_id  # ✅ NEW
            )

            # 📣 Notification
            send_notification(
                user=request.user,
                type_key="recharge_success",
                context={
                    'user': request.user,
                    'number': number,
                    'amount': amount,
                    'order_id': order_id,
                    'operator': transaction.operator,
                    'created_at': transaction.created_at,
                    'year': timezone.now().year,
                    'payment_id': razorpay_payment_id or "WALLET-ONLY"
                },
                message=f"Recharge of INR {amount} for {number} was successful."
            )

            # ✅ Response to client
            return JsonResponse({
                "success": True,
                "order_id": order_id,
                "payment_id": razorpay_payment_id or "WALLET-ONLY",
                "message": "Recharge Successful!"
            })
        
        except Exception as e:
            return JsonResponse({"error": str(e)}, status=500)

    return JsonResponse({"error": "Unauthorized or Invalid request"}, status=400)

from payments.models import ExternalWallet, ViralPeWallet

from decimal import Decimal

def get_wallet_balances(user):
    # External Wallet Balance
    ext_wallet = ExternalWallet.objects.filter(user=user).first()
    ext_balance = Decimal(ext_wallet.balance) if ext_wallet else Decimal("0.00")

    # ViralPe Wallet Balance
    vp_wallet = ViralPeWallet.objects.filter(user=user).first()
    vp_balance = Decimal(vp_wallet.balance) if vp_wallet else Decimal("0.00")

    # print(f"[Wallet Balances] User: {user} | External: Rs.{ext_balance} | ViralPe: Rs.{vp_balance}")

    return ext_balance, vp_balance


from django.http import JsonResponse
# from payments.utils import get_wallet_balances  # Ensure this exists

def determine_payment_strategy(request):
    if request.method == 'POST' and request.user.is_authenticated:
        try:
            amount_str = request.POST.get('amount', '').strip()
            if not amount_str or not amount_str.replace('.', '', 1).isdigit():
                return JsonResponse({"error": "Invalid amount"}, status=400)

            amount = float(amount_str)
            if amount <= 0:
                return JsonResponse({"error": "Amount must be greater than zero"}, status=400)

            # Fetch wallet balances
            ext_balance, vp_balance = get_wallet_balances(request.user)

            # Determine how much can be paid via each
            use_ext = min(ext_balance, amount)
            remaining = amount - use_ext

            use_vp = min(vp_balance, remaining)
            remaining -= use_vp

            # Determine payment strategy
            if remaining <= 0:
                if use_ext and use_vp:
                    strategy = "hybrid_wallet"
                elif use_ext:
                    strategy = "external_only"
                else:
                    strategy = "viralpe_only"
            else:
                strategy = "razorpay_needed"

            # Optional debug log
            # print(f"Strategy: {strategy} | Ext: {use_ext}, VP: {use_vp}, Razorpay: {remaining}")

            return JsonResponse({
                "strategy": strategy,
                "amount": round(amount, 2),
                "use_ext_wallet": round(use_ext, 2),
                "use_viralpe_wallet": round(use_vp, 2),
                "razorpay_amount": round(remaining, 2),
                "total_ext_wallet": round(ext_balance, 2),
                "total_viralpe_wallet": round(vp_balance, 2),
            })

        except Exception as e:
            return JsonResponse({"error": str(e)}, status=400)

    return JsonResponse({"error": "Unauthorized or invalid request"}, status=403)

from decimal import Decimal, InvalidOperation
from django.contrib import messages
from django.contrib.auth.decorators import login_required, permission_required
from django.shortcuts import render
from django.core.exceptions import ObjectDoesNotExist
from accounts.models import User
from payments.models import ViralPeWallet, ViralPeWalletUsage
from payments.utils import generate_wallet_credit_order_id
from notifications.services import send_notification

@login_required
@permission_required('payments.add_viralpewalletusage', raise_exception=True)
def wallet_topup(request):
    wallet_data = None
    page_title = "ViralPe Wallet Top-Up"

    if request.method == 'POST':
        mobile = (request.POST.get('mobile') or '').strip()
        amount_raw = (request.POST.get('amount') or '').strip()
        # purpose_code = request.POST.get('purpose_code') or 'manual_admin'
        # purpose_note = (request.POST.get('purpose_note') or '').strip()
        purpose_code = (request.POST.get('purpose_code') or 'manual_admin').strip()
        purpose_note = (request.POST.get('purpose_note') or '').strip()

        # map code -> human string (what you store in 'purpose')
        PURPOSE_MAP = {
            'manual_test': 'Manual Top-Up (Testing)',
            'manual_admin': 'Manual Top-Up (Admin)',
            'oneapp_withdrawal': 'Credit from 1App Withdrawal',
            'other': 'Other',
        }
        purpose_str = PURPOSE_MAP.get(purpose_code, 'Manual Top-Up (Admin)')

        try:
            if not mobile:
                raise ValueError("Mobile number is required")
            try:
                amount = Decimal(amount_raw)
            except (InvalidOperation, TypeError):
                raise ValueError("Invalid amount")

            if amount <= 0:
                raise ValueError("Amount must be greater than zero")

            # locate wallet owner
            try:
                user = User.objects.get(mobile_number=mobile)
            except ObjectDoesNotExist:
                raise ValueError(f"User with mobile {mobile} does not exist.")

            wallet, _ = ViralPeWallet.objects.get_or_create(user=user)
            wallet.balance = (Decimal(wallet.balance) if wallet.balance is not None else Decimal('0.00')) + amount
            wallet.save()

            # generate unique order id (15 chars)
            order_id = generate_wallet_credit_order_id()

            # record usage as CREDIT
            usage = ViralPeWalletUsage.objects.create(
                user=user,
                amount_used=amount,
                transaction_type='credit',
                purpose=purpose_str if not purpose_note else f"{purpose_str} | {purpose_note}",
                # if you added the optional fields:
                purpose_code=purpose_code,   # if hasattr(ViralPeWalletUsage, 'purpose_code') else None,
                purpose_note=purpose_note,   # if hasattr(ViralPeWalletUsage, 'purpose_note') else "",
                order_id=order_id,
                reference_user=request.user
            )

            messages.success(
                request,
                f"INR {amount} credited to {mobile}. "
                f"Order ID: {order_id}."
            )
            wallet_data = wallet
            
        except ValueError as ve:
            messages.error(request, str(ve))
        except Exception as e:
            messages.error(request, f"Error: {e}")
        send_notification(
            user=user,
            type_key="wallet_topup_credit",
            context={
                "user": user,
                "amount": amount,
                "order_id": usage.order_id,
                "balance": wallet.balance,
                "purpose": usage.purpose,
            },
            message=f"INR {amount} added to your ViralPe Wallet. Order {usage.order_id}.",
        )

    return render(request, 'payments/wallet_topup.html', {
        'wallet': wallet_data,
        'pagetitle': page_title,
    })


from django.contrib.auth.decorators import login_required
from django.shortcuts import render
from recharge.models import RechargeTransaction
from payments.models import RechargePaymentSummary, PaymentTransaction
from payments.utils import get_all_user_transactions  # ⬅️ new import

@login_required
def transaction_history(request):
    user = request.user
    filter_type = request.GET.get("type")
    service = request.GET.get("service")

    all_txns = get_all_user_transactions(user)

    if filter_type == "credit":
        all_txns = [t for t in all_txns if t["is_credit"]]
    elif filter_type == "debit":
        all_txns = [t for t in all_txns if not t["is_credit"]]
    if service:
        all_txns = [t for t in all_txns if t["service"] == service]

    return render(request, "payments/transaction_history.html", {
        "transactions": all_txns
    })

from django.http import JsonResponse, Http404
from django.template.loader import render_to_string
from django.contrib.auth.decorators import login_required
from payments.models import ExternalWalletTopUp, ExternalWalletUsage, ViralPeWalletUsage
from recharge.models import RechargeTransaction

@login_required
def transaction_detail_view(request, txn_id):
    user = request.user
    txn_type, obj_id = txn_id.split("-", 1)

    context = {}

    try:
        if txn_type == "recharge":
            txn = RechargeTransaction.objects.get(id=obj_id)
            context["type"] = "Recharge"
            context["txn"] = txn
            context["amount"] = txn.amount
            context["status"] = txn.status
            context["order_id"] = txn.order_id
            context["extra"] = txn.response_data
            context["date"] = txn.created_at
            context["number"] = txn.number

        elif txn_type == "topup":
            txn = ExternalWalletTopUp.objects.get(id=obj_id, user=user)
            context["type"] = "Wallet Top-up"
            context["txn"] = txn
            context["amount"] = txn.amount
            context["status"] = "Success"
            context["order_id"] = f"EXT-{txn.id}"
            context["date"] = txn.added_on

        elif txn_type == "extuse":
            txn = ExternalWalletUsage.objects.get(id=obj_id, user=user)
            context["type"] = "Wallet Debit"
            context["txn"] = txn
            context["amount"] = txn.amount_used
            context["status"] = "Used"
            context["order_id"] = f"EXTU-{txn.id}"
            context["date"] = txn.used_on
            context["details"] = txn.used_for

        elif txn_type == "vpuse":
            txn = ViralPeWalletUsage.objects.get(id=obj_id, user=user)
            context["type"] = "VP Wallet Debit"
            context["txn"] = txn
            context["amount"] = txn.amount_used
            context["status"] = "Used"
            context["order_id"] = f"VPU-{txn.id}"
            context["date"] = txn.used_on
            context["details"] = txn.purpose

        else:
            raise Http404("Invalid transaction type")

        html = render_to_string("payments/_transaction_detail_modal.html", context, request=request)
        return JsonResponse({"html": html})

    except Exception as e:
        return JsonResponse({"error": str(e)}, status=404)


from django.shortcuts import render, get_object_or_404, redirect
from .models import CommissionConfig, CommissionSplitConfig
from .forms import CommissionConfigForm, CommissionSplitForm
from django.contrib import messages
from django.urls import reverse

def commission_config_list(request):
    configs = CommissionConfig.objects.all().order_by('-created_at')
    return render(request, 'commissions/commission_config_list.html', {
        'configs': configs,
        'pagetitle': '🔧 Commission Configurations',
        'breadcrumbs': [{'label': 'Dashboard', 'url': reverse('commission_config_list')}, {'label': 'Commission Config'}]
    })

# payments/views.py
from django.shortcuts import render, get_object_or_404, redirect
from payments.models import CommissionConfig
from payments.forms import CommissionConfigForm  # You need to create this form
from django.contrib import messages

def commission_config_create(request):
    form = CommissionConfigForm(request.POST or None)
    if form.is_valid():
        form.save()
        messages.success(request, "Commission configuration added.")
        return redirect('commission_config_list')
    return render(request, "commissions/commission_config_form.html", {
        "form": form,
        "pagetitle": "➕ Add Commission Config",
        'breadcrumbs': [{'label': 'Dashboard', 'url': reverse('commission_config_list')}, {'label': 'Commission Config'}]
    })

def commission_config_edit(request, pk):
    config = get_object_or_404(CommissionConfig, pk=pk)
    form = CommissionConfigForm(request.POST or None, instance=config)
    if form.is_valid():
        form.save()
        messages.success(request, "Commission configuration updated.")
        return redirect('commission_config_list')
    return render(request, "commissions/commission_config_form.html", {
        "form": form,
        "pagetitle": "✏️ Edit Commission Config",
        'breadcrumbs': [{'label': 'Dashboard', 'url': reverse('commission_config_list')}, {'label': 'Commission Config'}]
    })
from django.shortcuts import render, redirect, get_object_or_404
from django.urls import reverse
from payments.models import CommissionSplitConfig
from payments.forms import CommissionSplitConfigForm  # You'll create this form
from django.db import models

def commission_split_list(request):
    splits = CommissionSplitConfig.objects.all()
    total_percentage = splits.aggregate(models.Sum('percentage'))['percentage__sum'] or 0
    remaining_percentage = 100 - total_percentage

    return render(request, 'commissions/commission_split_list.html', {
        'splits': splits,
        'total_percentage': total_percentage,
        'remaining_percentage': remaining_percentage,
        'form': CommissionSplitConfigForm(),
        'pagetitle': "🔗 Global Commission Split Config",
        'breadcrumbs': [{'label': 'Commission Settings'}, {'label': 'Split Config'}]
    })


def commission_split_add(request):
    if request.method == 'POST':
        form = CommissionSplitConfigForm(request.POST)
        if form.is_valid():
            form.save()
            return redirect('commission_split_list')
    else:
        form = CommissionSplitConfigForm()
    return render(request, 'commissions/commission_split_form.html', {
        'form': form,
        'pagetitle': "➕ Add Split Config"
    })


from django.shortcuts import render, get_object_or_404, redirect
from django.db.models import Sum
from .models import CommissionSplitConfig
from .forms import CommissionSplitConfigForm

def commission_split_edit(request, pk):
    split = get_object_or_404(CommissionSplitConfig, pk=pk)

    if request.method == 'POST':
        form = CommissionSplitConfigForm(request.POST, instance=split)
        if form.is_valid():
            form.save()
            return redirect('commission_split_list')
        else:
            print(form.errors)  # Debug

        # else:
            # Re-render the list view with errors and open modal
            splits = CommissionSplitConfig.objects.all()
            total_percentage = splits.aggregate(Sum('percentage'))['percentage__sum'] or 0
            remaining_percentage = 100 - (total_percentage - split.percentage)  # exclude current from total

            return render(request, 'commissions/commission_split_list.html', {
                'splits': splits,
                'form': form,
                'edit_id': split.pk,  # Pass to auto-trigger modal
                'edit_split': split,
                'total_percentage': total_percentage,
                'remaining_percentage': remaining_percentage,
                'pagetitle': "🔗 Global Commission Split Config",
                'breadcrumbs': [{'label': 'Commission Settings'}, {'label': 'Split Config'}]
            })



def commission_split_delete(request, pk):
    split = get_object_or_404(CommissionSplitConfig, pk=pk)
    if request.method == 'POST':
        split.delete()
        return redirect('commission_split_list')
    return render(request, 'commissions/commission_split_confirm_delete.html', {
        'split': split,
        'pagetitle': "🗑️ Confirm Delete"
    })


from payments.models import GeoRoleAssignment

def geo_role_assignment_list(request):
    roles = GeoRoleAssignment.objects.select_related('user').order_by('state', 'district', 'pincode', 'role')
    return render(request, 'commissions/geo_role_assignment_list.html', {
        'roles': roles,
        'pagetitle': '📍 Geo Role Assignments',
        'breadcrumbs': [
            {'label': 'Dashboard', 'url': reverse('dashboard')},
            {'label': 'Geo Role Assignments'}
        ]
    })


from django.shortcuts import render, get_object_or_404, redirect
from payments.models import GeoRoleAssignment
from payments.forms import GeoRoleAssignmentForm

def geo_role_assignment_create(request):
    if request.method == "POST":
        form = GeoRoleAssignmentForm(request.POST)
        if form.is_valid():
            form.save()
            return redirect('geo_role_assignment_list')
    else:
        form = GeoRoleAssignmentForm()
    return render(request, 'commissions/geo_role_assignment_form.html', {
        'form': form,
        'pagetitle': '➕ Add Geo Role Assignment'
    })

def geo_role_assignment_edit(request, pk):
    instance = get_object_or_404(GeoRoleAssignment, pk=pk)
    if request.method == "POST":
        form = GeoRoleAssignmentForm(request.POST, instance=instance)
        if form.is_valid():
            form.save()
            return redirect('geo_role_assignment_list')
    else:
        form = GeoRoleAssignmentForm(instance=instance)
    return render(request, 'commissions/geo_role_assignment_form.html', {
        'form': form,
        'pagetitle': '✏️ Edit Geo Role Assignment'
    })

def geo_role_assignment_delete(request, pk):
    instance = get_object_or_404(GeoRoleAssignment, pk=pk)
    if request.method == "POST":
        instance.delete()
        return redirect('geo_role_assignment_list')
    return render(request, 'confirm_delete.html', {
        'object': instance,
        'pagetitle': '❌ Delete Geo Role Assignment',
        'cancel_url': 'geo_role_assignment_list'
    })

from django.shortcuts import render
from payments.models import CommissionLog

def commission_logs(request):
    logs = CommissionLog.objects.select_related('user').order_by('-timestamp')
    return render(request, 'commissions/commission_logs.html', {
        'logs': logs,
        'pagetitle': '📄 Commission Logs',
        'breadcrumbs': [
            {'label': 'Dashboard', 'url': 'dashboard'},
            {'label': 'Commission Logs'},
        ]
    })



from payments.models import CommissionPayoutHistory

def commission_payouts(request):
    payouts = CommissionPayoutHistory.objects.select_related('user').order_by('-paid_on')
    return render(request, 'commissions/commission_payouts.html', {
        'payouts': payouts,
        'pagetitle': '💸 Commission Payouts',
        'breadcrumbs': [
            {'label': 'Dashboard', 'url': 'dashboard'},
            {'label': 'Payout History'},
        ]
    })

from payments.models import GeoCommissionWallet, ViralPeWalletUsage
from django.db.models import Sum, Value, F, DecimalField
from django.db.models.functions import Coalesce
from django.db.models import ExpressionWrapper
from django.contrib.auth import get_user_model

User = get_user_model()

def user_commission_report(request):
    users = User.objects.annotate(
        total_earned=Coalesce(Sum('commission_logs__amount'), Value(0.0), output_field=DecimalField()),
        total_used=Coalesce(Sum('wallet_usages__amount_used'), Value(0.0), output_field=DecimalField()),
    ).annotate(
        net_commission=ExpressionWrapper(
            F('total_earned') - F('total_used'),
            output_field=DecimalField()
        )
    ).order_by('-net_commission')
        
    return render(request, 'commissions/user_commission_report.html', {
        'users': users,
        'pagetitle': '📊 User Commission Report',
        'breadcrumbs': [
            {'label': 'Dashboard', 'url': 'dashboard'},
            {'label': 'Commission Wallet Report'},
        ]
    })


import razorpay
import uuid
from django.conf import settings
from django.utils import timezone
from .models import ExternalWalletUsage,PaymentTransaction
import json
from django.views.decorators.csrf import csrf_exempt
from django.http import JsonResponse
from payments.models import ExternalWallet, ExternalWalletTransaction, ViralPeWallet, ViralPeWalletUsage
from decimal import Decimal, InvalidOperation
from django.db import transaction
from django.db.models import F

def _to_dec(x) -> Decimal:
    if isinstance(x, Decimal):
        return x
    try:
        return Decimal(str(x))
    except (InvalidOperation, TypeError):
        raise ValueError("Invalid amount")

@transaction.atomic
def deduct_wallets(request, amount, ext_used, int_used, order_id, client_txnid=None):
    """
    Deducts from External + ViralPe wallets atomically.
    Idempotent by (user, order_id, 'debit') – if records already exist, no second debit is made.
    Raises ValueError on any failure.
    Returns a dict summary.
    """
    user = request.user
    amount  = _to_dec(amount)
    ext_used = _to_dec(ext_used or 0)
    int_used = _to_dec(int_used or 0)

    if ext_used < 0 or int_used < 0:
        raise ValueError("Invalid wallet usage values")
    if (ext_used + int_used) > amount:
        raise ValueError("Wallet usage cannot exceed order amount")

    summary = {"external_debited": Decimal("0"), "viralpe_debited": Decimal("0")}

    # ----- External Wallet (optional) -----
    if ext_used > 0:
        # idempotency: was external txn already created?
        exists = ExternalWalletTransaction.objects.filter(
            user=user, order_id=order_id, transaction_type='debit'
        ).exists()
        if not exists:
            # lock the wallet row
            ext_wallet = ExternalWallet.objects.select_for_update().filter(user=user).first()
            if not ext_wallet:
                raise ValueError("External wallet not found")
            if ext_wallet.balance < ext_used:
                raise ValueError("Insufficient External Wallet Balance")

            # atomic in-DB decrement
            ExternalWallet.objects.filter(pk=ext_wallet.pk).update(balance=F('balance') - ext_used)

            ExternalWalletTransaction.objects.create(
                user=user,
                amount=ext_used,
                transaction_type='debit',
                purpose=f"Recharge {order_id}",
                order_id=order_id,
                reference_user=None,
            )
            summary["external_debited"] = ext_used

    # ----- ViralPe Wallet (optional) -----
    if int_used > 0:
        # idempotency: was VP usage already created?
        exists = ViralPeWalletUsage.objects.filter(
            user=user, order_id=order_id, transaction_type='debit'
        ).exists()
        if not exists:
            vp_wallet = ViralPeWallet.objects.select_for_update().filter(user=user).first()
            if not vp_wallet:
                raise ValueError("ViralPe wallet not found")
            if vp_wallet.balance < int_used:
                raise ValueError("Insufficient ViralPe Wallet Balance")

            ViralPeWallet.objects.filter(pk=vp_wallet.pk).update(balance=F('balance') - int_used)

            ViralPeWalletUsage.objects.create(
                user=user,
                amount_used=int_used,
                transaction_type='debit',
                order_id=order_id,
                purpose=f"Recharge {order_id}",
                reference_user=None,
            )
            summary["viralpe_debited"] = int_used

    # Optional sanity: total debited should match sum requested (when both used)
    if (summary["external_debited"] + summary["viralpe_debited"]) != (ext_used + int_used):
        raise ValueError("Wallet deduction mismatch")

    return summary

def deduct_wallets_old(request, amount, ext_used, int_used, order_id, client_txnid):
    user = request.user

    # ✅ External Wallet Deduction
    if ext_used > 0:
        ext_wallet = ExternalWallet.objects.filter(user=user).first()
        if not ext_wallet or ext_wallet.balance < Decimal(ext_used):
            raise ValueError("Insufficient External Wallet Balance")

        ext_wallet.decrease(ext_used)
        ExternalWalletTransaction.objects.create(
            user=user,
            amount=Decimal(ext_used),
            transaction_type='debit',
            purpose=f"Recharge {order_id}",
            order_id=order_id,
            reference_user=None  # not an admin top-up
        )

    # ✅ ViralPe Wallet Deduction
    if int_used > 0:
        vp_wallet = ViralPeWallet.objects.filter(user=user).first()
        if not vp_wallet or vp_wallet.balance < Decimal(int_used):
            raise ValueError("Insufficient ViralPe Wallet Balance")

        vp_wallet.balance -= Decimal(int_used)
        vp_wallet.save()

        ViralPeWalletUsage.objects.create(
            user=user,
            transaction_type='debit',
            amount_used=Decimal(int_used),
            order_id=order_id,
            purpose=f"Recharge {order_id}"
        )

from recharge.utils import initiate_recharge  # Or wherever your logic is
from payments.models import PaymentTransaction
from django.utils import timezone

from decimal import Decimal, InvalidOperation, ROUND_HALF_UP

TWOPL = Decimal("0.01")

def _d(x) -> Decimal:
    # Safe Decimal from any primitive (str/float/int/Decimal/None)
    if x is None:
        return Decimal("0")
    try:
        return Decimal(str(x))
    except (InvalidOperation, ValueError, TypeError):
        return Decimal("0")

def q2(x: Decimal) -> Decimal:
    return x.quantize(TWOPL, rounding=ROUND_HALF_UP)

def _to_paise(x: Decimal) -> int:
    # Always integer paise
    return int((x * 100).quantize(Decimal("1"), rounding=ROUND_HALF_UP))

def _as_int(x) -> int:
    try:
        return int(Decimal(str(x)))
    except Exception:
        return 0

def perform_wallet_recharge(request, data, order_id, client_txnid):
    amount_rupees = data.get("amount_rupees", data.get("amount"))
    amount_rupees = q2(_d(amount_rupees))

    razorpay_amt_rupees = data.get("razorpay_amount_rupees", data.get("razorpay_amount"))
    razorpay_amt_rupees = q2(_d(razorpay_amt_rupees))

    # Paise (prefer explicit paise if present)
    amount_paise = data.get("amount_paise")
    if amount_paise is None:
        amount_paise = _to_paise(amount_rupees)
    else:
        amount_paise = _as_int(amount_paise)  # ensure int

    razorpay_amt_paise = data.get("razorpay_amount_paise")
    if razorpay_amt_paise is None:
        razorpay_amt_paise = _to_paise(razorpay_amt_rupees)
    else:
        razorpay_amt_paise = _as_int(razorpay_amt_paise)

    # Wallet splits (rupees)
    use_ext_rupees = q2(_d(data.get("use_ext_wallet", 0)))
    use_int_rupees = q2(_d(data.get("use_viralpe_wallet", 0)))

    # ---- Build source label safely ----
    wallet_sources = []
    if use_ext_rupees > 0:
        wallet_sources.append("External Wallet")
    if use_int_rupees > 0:
        wallet_sources.append("ViralPe Wallet")

    if use_ext_rupees == 0 and use_int_rupees == 0 and razorpay_amt_rupees > 0:
        gateway_ref = "Razorpay Only"
    else:
        gateway_ref = " + ".join(wallet_sources) if wallet_sources else "Wallet Only"
        if razorpay_amt_rupees > 0:
            gateway_ref += " + Razorpay"

    # ---- Debug: verify conservation before calling provider ----
    # (This should match what you enforced in the view.)
    total_rupees = q2(use_ext_rupees + use_int_rupees + razorpay_amt_rupees)
    if total_rupees != amount_rupees:
        print(f"[WARN] Amount mismatch before provider call: "
              f"{use_ext_rupees}+{use_int_rupees}+{razorpay_amt_rupees} != {amount_rupees}")

    print({
        "amount_rupees": str(amount_rupees),
        "amount_paise": amount_paise,
        "use_ext_rupees": str(use_ext_rupees),
        "use_int_rupees": str(use_int_rupees),
        "razorpay_amt_rupees": str(razorpay_amt_rupees),
        "razorpay_amt_paise": razorpay_amt_paise,
        "gateway_ref": gateway_ref,
    })

    # ---- Call provider adapter ----
    # IMPORTANT:
    # - If your provider expects *paise* as integer, pass amount_paise instead.
    # - If it expects rupees (decimal), pass str(amount_rupees) or Decimal.
    result = initiate_recharge(
        user=request.user,
        number=data['number'],
        operator=data['operator'],
        circle=data['circle'],

        # Option A (provider expects rupees with 2dp)
        # amount=str(amount_rupees),
        amount=amount_rupees,  # Decimal(2dp)

        # Option B (provider expects paise)
        # amount_paise=amount_paise,

        order_id=order_id,
        client_txn_id=client_txnid,
        use_ext=use_ext_rupees,
        use_int=use_int_rupees,
        gateway_ref=gateway_ref,  # label only
        razorpay_order_id=data.get("razorpay_order_id"),
        razorpay_payment_id=data.get("razorpay_payment_id"),

    )

    print('RESULT')
    print(result)
    print('---------- initiate recharge completes ----------')

    return result


from django.views.decorators.csrf import csrf_protect
from .ids import generate_unique_provider_txnid
import uuid

@require_POST
@login_required
@csrf_protect  # or remove completely since you’re already sending token
def make_payment(request):
    if request.method != "POST" or not request.user.is_authenticated:
        return JsonResponse({"success": False, "message": "Unauthorized"}, status=403)

    try:
        data = json.loads(request.body)
        number = data.get("number")
        operator = data.get("operator")
        circle = data.get("circle")
        amount = Decimal(data.get("amount", "0"))
        use_ext = Decimal(data.get("use_ext_wallet", "0"))
        use_int = Decimal(data.get("use_viralpe_wallet", "0"))


        # Internal long ID for your tracking
        order_id = f"VP-{request.user.id}-{number[-4:]}-{uuid.uuid4().hex[:6].upper()}"
        # print(order_id)
        # print(data)
        # Short unique ID for provider 
        client_txnid = generate_unique_provider_txnid(prefix="VP", length=10)

        razorpay_due = amount - use_ext - use_int

        if razorpay_due <= 0:
            try:
                # Deduct wallets
                print("[DEBUG] Deducting wallets...")
                deduct_wallets(request, amount, use_ext, use_int, order_id,client_txnid)
                print("[DEBUG] Wallet deduction done.")

                # Log recharge intent
                print("[DEBUG] Creating RechargePaymentSummary...")
                RechargePaymentSummary.objects.create(
                    user=request.user,
                    recharge_amount=float(amount),
                    used_external_wallet=float(use_ext),
                    used_internal_wallet=float(use_int),
                    paid_via_gateway=0,
                    order_id=order_id,
                )
                print("[DEBUG] Created RechargePaymentSummary.")

                # Save transaction log
                print("[DEBUG] Creating PaymentTransaction...")
                PaymentTransaction.objects.create(
                    user=request.user,
                    amount=float(amount),
                    order_id=order_id,
                    status="success"
                )
                print("[DEBUG] Created PaymentTransaction.")

                # Trigger recharge
                print("[DEBUG] Initiating recharge...")
                result = perform_wallet_recharge(request, data, order_id,client_txnid)
                print("[DEBUG] Recharge performed.")
                print("returning JSON response now to front end")

                return JsonResponse({
                    "success": True,
                    "order_id": order_id,
                    "client_txnid": client_txnid,
                    "razorpay_due": 0,
                    "recharge_status": result.get("status"),
                    "status_message": result.get("message"),
                    "response_data": result.get("raw")
                })

            except Exception as e:
                import traceback
                traceback.print_exc()
                return JsonResponse({"success": False, "message": str(e)}, status=500)


        # Razorpay flow
        print('# Razorpay flow')

        client = razorpay.Client(auth=(settings.RAZORPAY_API_KEY, settings.RAZORPAY_API_SECRET))
        razorpay_order = client.order.create({
            "amount": int(razorpay_due * 100),
            "currency": "INR",
            "receipt": order_id,
            "payment_capture": 1,
        })

        razorpay_order_id = razorpay_order['id']
        PaymentTransaction.objects.create(
            user=request.user,
            order_id=order_id,
            amount=float(amount),
            razorpay_order_id=razorpay_order_id,
            status="initiated"
        )

        return JsonResponse({
            "success": True,
            "order_id": order_id,
            "client_txnid": client_txnid,
            "razorpay_order_id": razorpay_order_id,
            "razorpay_due": float(razorpay_due),
            "use_ext_wallet": float(use_ext),
            "use_viralpe_wallet": float(use_int)
        })

    except Exception as e:
        return JsonResponse({"success": False, "message": str(e)}, status=500)


@csrf_exempt
def verify_razorpay_payment(request):
    if request.method != "POST" or not request.user.is_authenticated:
        return JsonResponse({"success": False, "message": "Unauthorized"}, status=403)

    try:
        data = json.loads(request.body)
        order_id = data.get("order_id")
        amount = Decimal(data.get("amount", "0"))
        razorpay_payment_id = data.get("razorpay_payment_id")
        razorpay_order_id = data.get("razorpay_order_id")
        razorpay_signature = data.get("razorpay_signature")
        use_ext = Decimal(data.get("use_ext_wallet", "0"))
        use_int = Decimal(data.get("use_viralpe_wallet", "0"))

        # Razorpay signature verification
        client = razorpay.Client(auth=(settings.RAZORPAY_API_KEY, settings.RAZORPAY_API_SECRET))
        params_dict = {
            "razorpay_order_id": razorpay_order_id,
            "razorpay_payment_id": razorpay_payment_id,
            "razorpay_signature": razorpay_signature,
        }
        client.utility.verify_payment_signature(params_dict)

        # Update payment transaction
        tx = PaymentTransaction.objects.get(razorpay_order_id=razorpay_order_id)
        tx.status = "success"
        # tx.razorpay_payment_id = razorpay_payment_id
        tx.razorpay_signature = razorpay_signature 
        # Log wallet + gateway split
        RechargePaymentSummary.objects.update_or_create(
            order_id=order_id,
            defaults={
                "user": request.user,
                "recharge_amount": float(amount),
                "used_external_wallet": float(use_ext),
                "used_internal_wallet": float(use_int),
                "paid_via_gateway": float(amount - use_ext - use_int),
                "gateway_reference": razorpay_payment_id
            }
        )

        # Deduct wallets
        deduct_wallets(request, amount, use_ext, use_int, order_id)
        # gateway_ref = razorpay_payment_id

        # Trigger recharge
        result = perform_wallet_recharge(request, data, order_id, )

        return JsonResponse({
            "success": True,
            "order_id": order_id,
            "recharge_status": result.get("status"),
            "response_data": result.get("response_data")
        })

    except razorpay.errors.SignatureVerificationError:
        return JsonResponse({"success": False, "message": "Invalid payment signature"}, status=400)

    except Exception as e:
        return JsonResponse({"success": False, "message": str(e)}, status=400)


def refresh_pending_recharge_statuses():
    pending_recharges = RechargePaymentSummary.objects.filter(recharge_status="Pending")
    a1_api = A1TopupAPI(settings.A1TOPUP_USERNAME, settings.A1TOPUP_PASSWORD)

    for summary in pending_recharges:
        result = a1_api.check_status(orderid=summary.order_id)
        new_status = result.get("status", "").lower()

        status_map = {
            "success": "Success",
            "failure": "Failure",
            "failed": "Failure",
            "pending": "Pending"
        }
        normalized = status_map.get(new_status, "Pending")

        if normalized != summary.recharge_status:
            summary.recharge_status = normalized
            summary.gateway_reference = result.get("payment_id") or summary.gateway_reference
            summary.full_response = result
            summary.updated_at = timezone.now()
            summary.save()

            # Send notification once
            if normalized == "Success":
                send_notification(
                    user=summary.user,
                    type_key="recharge_success",
                    context={"number": "...", "amount": summary.recharge_amount, "order_id": summary.order_id},
                    message=f"Recharge of INR {summary.recharge_amount} was successful."
                )
            elif normalized == "Failure":
                send_notification(
                    user=summary.user,
                    type_key="recharge_failed",
                    context={"number": "...", "amount": summary.recharge_amount, "order_id": summary.order_id},
                    message=f"Recharge of INR {summary.recharge_amount} failed."
                )


from .models import RechargePaymentSummary, ViralPeWallet, ViralPeWalletUsage
from decimal import Decimal
from django.utils.timezone import now

from .models import RechargePaymentSummary, ViralPeWallet, ViralPeWalletUsage
from decimal import Decimal
from django.utils.timezone import now
from .models import ExternalWallet,ExternalWalletTransaction

from decimal import Decimal
from django.utils.timezone import now
from payments.models import ExternalWallet, ExternalWalletTransaction, ViralPeWallet, ViralPeWalletUsage
from django.db import transaction
from payments.models import (
    ExternalWallet, ExternalWalletTransaction,
    ViralPeWallet, ViralPeWalletUsage, RechargePaymentSummary
)
from recharge.models import RechargeTransaction
import logging

REFUND_REASON_DEFAULT = "Recharge Failed"

def _as_dec(x) -> Decimal:
    return Decimal(str(x or "0")).quantize(Decimal("0.01"))

def _D(x) -> Decimal:
    return Decimal(str(x or "0")).quantize(Decimal("0.01"))



def process_recharge_refund(summary: RechargePaymentSummary) -> Decimal:
    """
    Refunds ALL components (external, internal, gateway) into ViralPe Wallet ONLY.
    Atomic & idempotent: safe to call multiple times.
    Returns total refunded (Decimal).
    """
    log = logging.getLogger(__name__)

    with transaction.atomic():
        # Lock the summary row to prevent concurrent refunds
        summary = (
            RechargePaymentSummary.objects
            .select_for_update()
            .get(pk=summary.pk)
        )
        log.info("Inside proceess recharge refund")
        log.info(summary)
        log.info(summary.pk)
        # Idempotency guard
        log.info(summary.is_refunded)
        log.info(summary.recharge_status)
        status = (summary.recharge_status or "").strip().lower()
        # Refund only when status is failure/error and not already refunded
        if summary.is_refunded or status not in {"failure", "error"}:
        # if summary.is_refunded or summary.recharge_status.lower() != "failed":
            return Decimal("0.00")
        log.info("Proceeding for refund")
        user = summary.user
        order_id = summary.order_id

        # Compute precise amounts
        ext_amt = _as_dec(summary.used_external_wallet)
        int_amt  = _as_dec(summary.used_internal_wallet)
        gw_amt  = _as_dec(summary.paid_via_gateway)

        # total_refund = Decimal("0.00")

        # --- ViralPe Wallet refund (internal wallet) ---
        total = Decimal("0.00")
        vp_wallet, _ = ViralPeWallet.objects.select_for_update().get_or_create(user=user)
        log.info("entering credit once")
        log.info(vp_wallet)
        
        def credit_once(purpose: str, amount: Decimal):
            nonlocal total, vp_wallet
            if amount <= 0:
                return
            # Idempotent line: if it already exists, don't double-credit
            line, created = ViralPeWalletUsage.objects.get_or_create(
                user=user,
                order_id=order_id,
                transaction_type="credit",
                purpose=purpose,    # distinct per source
                purpose_code = "payment_auto_refund",
                purpose_note = summary.status_message,
                defaults={"amount_used": amount},
            )
            if created:
                vp_wallet.balance = _D(vp_wallet.balance) + amount
                vp_wallet.save(update_fields=["balance"])
                total += amount

        # Create clearly-audited lines, all crediting VP wallet
        credit_once(f"Refund (1App Wallet → VP) - {order_id}", ext_amt)
        credit_once(f"Refund (VP → VP) - {order_id}", int_amt)
        credit_once(f"Refund (RazorPay → VP) - {order_id}",  gw_amt)
        log.info(ext_amt)
        log.info(int_amt)
        log.info(gw_amt)
        # Mark summary as refunded
        summary.is_refunded = True
        summary.refunded_on = now()
        if not summary.refund_reason:
            summary.refund_reason = "Recharge Failed"
        summary.save(update_fields=["is_refunded", "refunded_on", "refund_reason"])
        log.info(summary)
        return total

from django.contrib.auth.decorators import login_required
from django.shortcuts import render
from .models import PaymentTransaction
from collections import defaultdict
from django.utils import timezone
from collections import defaultdict
from payments.models import RechargePaymentSummary
from collections import defaultdict
from django.contrib.auth.decorators import login_required
from django.shortcuts import render
from payments.models import RechargePaymentSummary

@login_required
def payment_history_view(request):
    transactions = RechargePaymentSummary.objects.filter(user=request.user).order_by('-updated_at')

    # Grouping by Month-Year
    history_by_month = defaultdict(list)
    for txn in transactions:
        month = txn.updated_at.strftime("%b'%y")  # e.g. "Aug'25"
        history_by_month[month].append(txn)

    context = {
        'pagetitle': '💰 Payment History',
        'breadcrumbs': [
            {'label': 'Dashboard', 'url': 'dashboard'},
            {'label': 'Payment History'}
        ],
        'history_by_month': dict(history_by_month),
    }
    return render(request, 'payments/payment_history.html', context)




# from .models import RefundTransaction  # assuming you have a RefundTransaction model
from collections import defaultdict
from django.contrib.auth.decorators import login_required
from django.shortcuts import render
from payments.models import RechargePaymentSummary  # adjust path as needed

@login_required
def refund_history_view(request):
    refunds = RechargePaymentSummary.objects.filter(user=request.user, is_refunded=True).order_by('-refunded_on')

    # Group by Month-Year
    refund_by_month = defaultdict(list)
    for refund in refunds:
        month = refund.refunded_on.strftime("%b'%y") if refund.refunded_on else "Unknown"
        refund_by_month[month].append(refund)
        print(refund)

    context = {
        'pagetitle': '💸 Refund History',
        'breadcrumbs': [
            {'label': 'Dashboard', 'url': 'dashboard'},
            {'label': 'Refund History'}
        ],
        'refund_by_month': dict(refund_by_month),
    }
    return render(request, 'payments/refund_history.html', context)


from .models import ViralPeWalletUsage

from collections import defaultdict
from django.contrib.auth.decorators import login_required
from django.shortcuts import render
from payments.models import ViralPeWalletUsage, ExternalWalletTransaction, ViralPeWallet, ExternalWallet
from collections import defaultdict
from django.contrib.auth.decorators import login_required
from django.shortcuts import render
from payments.models import ViralPeWalletUsage, ExternalWalletTransaction, ViralPeWallet, ExternalWallet

@login_required
def wallet_history_view(request):
    # Fetch wallet balances
    internal_wallet = ViralPeWallet.objects.filter(user=request.user).first()
    external_wallet = ExternalWallet.objects.filter(user=request.user).first()

    # Fetch recent 10 transactions for both
    latest_internal_txns = ViralPeWalletUsage.objects.filter(user=request.user).order_by('-used_on')[:10]
    latest_external_txns = ExternalWalletTransaction.objects.filter(user=request.user).order_by('-created_at')[:10]

    context = {
        'pagetitle': '👛 Wallets',
        'breadcrumbs': [
            {'label': 'Dashboard', 'url': 'dashboard'},
            {'label': 'Wallet History'}
        ],
        'external_balance': external_wallet.balance if external_wallet else 0,
        'internal_balance': internal_wallet.balance if internal_wallet else 0,
        'external_wallet_id': "1Apportunity Wallet" if external_wallet else 'N/A',
        'internal_wallet_id': "ViralPe Wallet" if external_wallet else 'N/A',
        'internal_txns': latest_internal_txns,
        'external_txns': latest_external_txns,
    }
    return render(request, 'payments/wallet_history.html', context)



# payments/views.py
import hmac, hashlib
from django.conf import settings
from django.http import HttpResponseBadRequest, HttpResponse
from django.shortcuts import redirect
from django.views.decorators.csrf import csrf_exempt

from payments.models import PaymentTransaction  # adjust import
# from payments.services import perform_final_for_order  # your existing finalize step

WEBAPP_BASE = "https://webapp.viralpe.com"  # your React app
SUCCESS_ROUTE = f"{WEBAPP_BASE}/#/recharge/prepaid"
FAIL_ROUTE    = f"{WEBAPP_BASE}/#/recharge/prepaid"

def _verify_signature(order_id: str, payment_id: str, signature: str) -> bool:
    key_secret = settings.RAZORPAY_API_SECRET.encode()
    msg = f"{order_id}|{payment_id}".encode()
    expected = hmac.new(key_secret, msg, hashlib.sha256).hexdigest()
    return hmac.compare_digest(expected, signature or "")

@csrf_exempt
def razorpay_callback(request):
    if request.method != "POST":
        return HttpResponseBadRequest("Invalid method")

    r_order = request.POST.get("razorpay_order_id")
    r_payment = request.POST.get("razorpay_payment_id")
    r_sign = request.POST.get("razorpay_signature")

    # Your own client order id passed as ?order=... when opening Razorpay
    client_order = request.GET.get("order")

    if not (r_order and r_payment and r_sign and client_order):
        # Treat as failure
        return redirect(f"{FAIL_ROUTE}?order={client_order or ''}&status=FAILED&reason=missing_params")

    if not _verify_signature(r_order, r_payment, r_sign):
        return redirect(f"{FAIL_ROUTE}?order={client_order}&status=FAILED&reason=bad_signature")

    # Idempotency: if already finalized, just redirect success
    txn = PaymentTransaction.objects.filter(order_id=client_order).first()
    if txn and str(txn.status).lower() in {"paid", "success", "completed"}:
        return redirect(f"{SUCCESS_ROUTE}?txn={txn.id}&order={client_order}&status=SUCCESS")

    # TODO: call your existing "perform" step that you already run after verify in JS.
    # perform_final_for_order(client_order, r_order, r_payment)  # implement using your existing services

    # Optionally update PaymentTransaction quickly here (minimal):
    if txn:
        txn.status = "paid"
        txn.razorpay_payment_id = r_payment
        txn.save(update_fields=["status", "razorpay_payment_id"])

    # Redirect user back to your React app (it will poll /status using ?order or ?txn)
    return redirect(f"{SUCCESS_ROUTE}?order={client_order}&status=SUCCESS")
