from ..models import RechargePlan, Operator, Circle, RechargeTransaction
from recharge.models import RechargePlan, Operator, Circle, RechargeTransaction
from ..services.a1topup_api import A1TopupAPI
from recharge.services.a1topup_api import A1TopupAPI
from collections import defaultdict
from datetime import datetime
from django.conf import settings
from django.contrib import messages
from django.contrib.admin.views.decorators import staff_member_required
from django.contrib.auth.decorators import login_required
from django.db.models import Q
from django.http import JsonResponse, HttpResponse
from django.shortcuts import render,redirect
from django.template.loader import render_to_string
from django.urls import reverse
from django.utils import timezone
from notifications.services import send_notification
from payments.models import PaymentTransaction, RechargePaymentSummary
import random
import uuid

def generate_transaction_id():
    now = datetime.now().strftime('%Y%m%d%H%M%S')
    rand = random.randint(1000, 9999)
    return f"VP{now}{rand}"

# use this like 
# order_id = generate_transaction_id()
# order_id = f"VP-{uuid.uuid4().hex[:12].upper()}"

from django.conf import settings

def recharge_form(request):
    if not request.user.is_authenticated:
        return redirect("/")  # Optional safeguard

    provider_key = settings.RECHARGE_PROVIDER.lower()
    provider_source = settings.PROVIDER_SOURCE_MAP.get(provider_key, provider_key)
    
    return render(request, 'recharge/recharge_form_final.html', {
        'operators': Operator.objects.filter(
            service_type__iexact="Mobile",
            source__iexact=provider_source
        ),
        'circles': Circle.objects.filter(
            source__iexact=provider_source
        ),
        'razorpay_key_id': settings.RAZORPAY_API_KEY,
        'user_name': f"{request.user.first_name} {request.user.last_name}".strip(),
        'user_email': request.user.email or ""
    })


from django.http import JsonResponse
from recharge.services.provider_factory import get_recharge_client
from recharge.services.plan_cache import load_cached_plans
from django.conf import settings

def get_recharge_plans(request):
    op = request.GET.get("operator")
    circle = request.GET.get("circle")
    provider_key = settings.RECHARGE_PROVIDER.lower()

    cached = load_cached_plans(provider_key, op, circle)
    if cached and cached.get("count", 0) > 0:
        return JsonResponse({"ok": True, "source": "cache", **cached})

    client = get_recharge_client()
    resp = client.recharge_plan(op, circle)
    return JsonResponse({"ok": True, "source": "live", "raw": resp.get("Data") or []})



def fetch_plans(request):
    operator_code = request.GET.get('operator')
    circle_code   = request.GET.get('circle')

    if not operator_code or not circle_code:
        return JsonResponse({"error": "operator & circle are required"}, status=400)

    qs = (RechargePlan.objects
          .filter(operator__code=operator_code, circle__code=circle_code)
          .order_by('price', 'group_name'))

    groups = defaultdict(list)
    flat   = []   # if you still want the old “flat” rendering/tabs

    for p in qs:
        item = {
            "amount": float(p.price),
            "description": p.description,
            "type": p.plan_type or "",
            "validity": p.validity or "",
            "data": p.data or "",
        }
        groups[p.group_name].append(item)
        flat.append({**item, "group": p.group_name})

    return JsonResponse({
        "groups": groups,   # <- use this for grouped UI
        "plans": flat       # <- (optional) still available for your old grid/swiper flow
    })


def check_recharge_status(request):
    print(' --------- check_recharge_status ----------')
    order_id = request.GET.get('order_id')
    if not order_id:
        return JsonResponse({"status": "Invalid", "message": "Missing order ID"}, status=400)

    try:
        summary = RechargePaymentSummary.objects.get(order_id=order_id)

        return JsonResponse({
            "status": summary.recharge_status or "Pending",
            "opid": summary.gateway_reference,
            "amount": summary.recharge_amount,
            "timestamp": summary.updated_at.isoformat()
        })

    except RechargePaymentSummary.DoesNotExist:
        return JsonResponse({
            "status": "Invalid",
            "message": f"Recharge summary not found for order_id {order_id}"
        }, status=404)

def fetch_balance():
    # Replace with actual credentials or load from settings
    a1_api = A1TopupAPI(settings.A1TOPUP_USERNAME, settings.A1TOPUP_PASSWORD)
    balance_response = a1_api.check_balance()
    print("💰 Balance:", balance_response)

    if "error" in balance_response:
        return {"status": "error", "message": balance_response["error"]}

    return {"status": "success", "balance": balance_response}

def get_recharge_plans_(request):
    operator_id = request.GET.get('operator_id')
    circle_id = request.GET.get('circle_id')

    plans = RechargePlan.objects.filter(operator_id=operator_id, circle_id=circle_id)

    grouped_data = {}
    for plan in plans:
        group = plan.group_name or 'Others'
        if group not in grouped_data:
            grouped_data[group] = []
        grouped_data[group].append({
            'plan_type': plan.plan_type,
            'data': plan.data,
            'validity': plan.validity,
            'description': plan.description,
            'price': str(plan.price)
        })

    return JsonResponse({'plans': grouped_data})



@login_required
def upload_recharge_plans(request):
    import pandas as pd
    if request.method == 'POST' and request.FILES.get('excel_file'):
        excel_file = request.FILES['excel_file']

        try:
            df = pd.read_excel(excel_file)

            required_columns = [
                'Operator Code', 'Circle Code', 'Group Name', 'Plan Type',
                'Data', 'Validity', 'Description', 'Price'
            ]

            if not all(col in df.columns for col in required_columns):
                messages.error(request, "Invalid Excel format. Required columns: " + ", ".join(required_columns))
                return redirect('upload_recharge_plans')

            added, updated, skipped = 0, 0, 0

            for _, row in df.iterrows():
                try:
                    operator_code = str(row['Operator Code']).strip()
                    circle_code = str(row['Circle Code']).strip()

                    # ✅ Skip if "All Circles"
                    if circle_code.lower() == 'all circles':
                        skipped += 1
                        continue

                    operator = Operator.objects.get(code=operator_code)
                    # circle = Circle.objects.get(code=circle_code)
                    circle = Circle.objects.filter(code=circle_code).first()
                    if not circle:
                        messages.warning(request, f"❌ Circle '{circle_code}' not found.")
                        continue


                    plan_obj, created = RechargePlan.objects.update_or_create(
                        operator=operator,
                        circle=circle,
                        group_name=str(row['Group Name']).strip(),
                        description=str(row['Description']).strip(),
                        price=row['Price'],
                        defaults={
                            'plan_type': str(row.get('Plan Type', '')).strip(),
                            'data': str(row.get('Data', '')).strip(),
                            'validity': str(row.get('Validity', '')).strip(),
                            'source': 'A1Topup',
                        }
                    )

                    if created:
                        added += 1
                    else:
                        updated += 1

                except Operator.DoesNotExist:
                    messages.warning(request, f"❌ Operator '{operator_code}' not found.")
                except Circle.DoesNotExist:
                    messages.warning(request, f"❌ Circle '{circle_code}' not found.")
                except Exception as e:
                    messages.warning(request, f"❌ Error in row: {row.to_dict()} → {e}")

            messages.success(request, f"✅ {added} plans added, {updated} updated. ⏩ Skipped {skipped} rows with 'All Circles'.")
            return redirect('upload_recharge_plans')

        except Exception as e:
            messages.error(request, f"❌ Error reading file: {e}")
            return redirect('upload_recharge_plans')

    return render(request, 'recharge/upload_plans.html', {
        'pagetitle': '📤 Upload Recharge Plans',
        'breadcrumbs': [
            {'label': 'Dashboard', 'url': reverse('dashboard')},
            {'label': 'Recharge Plans', 'url': reverse('get_recharge_plans')},
            {'label': 'Upload'},
        ]
    })



def recharge_transaction_history_view(request):
    operator_id = request.GET.get('operator')
    circle_id = request.GET.get('circle')
    status = request.GET.get('status')

    filters = Q()
    if operator_id:
        filters &= Q(operator_id=operator_id)
    if circle_id:
        filters &= Q(circle_id=circle_id)
    if status:
        filters &= Q(status=status)

    transactions = RechargeTransaction.objects.select_related('operator', 'circle').filter(filters).order_by('-created_at')
    operators = Operator.objects.all()
    circles = Circle.objects.all()

    return render(request, 'recharge/transaction_history.html', {
        'transactions': transactions,
        'operators': operators,
        'circles': circles,
        'pagetitle': '📄 Recharge Transaction History',
    })

