#!/usr/bin/env python
"""
fix_pending_and_nancy.py
────────────────────────
1. Reprocesses all IPNs stuck in 'pending' status
2. Diagnoses Nancy Nyambura's loan active_objects issue and fixes it
3. Updates ADMIN_ALERT_PHONES placeholder

Run: python fix_pending_and_nancy.py
"""
import os, sys, django, json
os.environ['DJANGO_SETTINGS_MODULE'] = 'branch_system.settings_production'
sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
django.setup()

from django.db import connection
from decimal import Decimal

SEP = '─' * 68

# ── 1. Diagnose Nancy's loan ──────────────────────────────────────────────
print(f"\n{SEP}\n  1. NANCY NYAMBURA — LOAN DIAGNOSIS\n{SEP}")

from users.models import CustomUser
from loans.models import Loan

try:
    nancy = CustomUser.objects.get(phone_number='+254723950526', role='borrower')
    print(f"  Borrower : {nancy.get_full_name()}")
    print(f"  Active   : {nancy.is_active}")

    # Check via all objects
    all_loans = Loan.objects.filter(borrower=nancy)
    active_manager = Loan.active_objects.filter(borrower=nancy)

    print(f"\n  All loans ({all_loans.count()}):")
    for l in all_loans.order_by('-created_at')[:5]:
        print(f"    {l.loan_number}  status={l.status}  is_deleted={l.is_deleted}")

    print(f"\n  Via active_objects ({active_manager.count()}):")
    for l in active_manager.order_by('-created_at')[:5]:
        print(f"    {l.loan_number}  status={l.status}  is_deleted={l.is_deleted}")

    # The IPN processor filters: active_objects + status='active'
    final = Loan.active_objects.filter(borrower=nancy, status='active')
    print(f"\n  active_objects + status='active': {final.count()}")

    if final.count() == 0:
        # Find the actual loan and check what's wrong
        loan = all_loans.filter(loan_number='BSH/202510/00136').first()
        if loan:
            print(f"\n  Loan BSH/202510/00136:")
            print(f"    status     = {loan.status}")
            print(f"    is_deleted = {loan.is_deleted}")
            print(f"    outstanding= ", end='')
            try:
                print(f"KES {loan.outstanding_amount:,.2f}")
            except Exception as e:
                print(f"ERROR: {e}")

            if loan.is_deleted:
                print("\n  ⚠️  CAUSE: loan.is_deleted=True")
                print("  active_objects excludes is_deleted=True loans")
                print("  Fix: the loan was soft-deleted — either undelete it")
                print("       or manually record the payment against it")
            elif loan.status != 'active':
                print(f"\n  ⚠️  CAUSE: loan.status='{loan.status}' not 'active'")
                print("  Fix: change status back to 'active' in admin panel")
        else:
            print("\n  ❌  Loan BSH/202510/00136 not found at all")
    else:
        print("  ✅ Loan found — the IPN failure may have been transient")

except CustomUser.DoesNotExist:
    print("  ❌ Borrower not found with phone +254723950526")

# ── 2. Reprocess pending IPNs ─────────────────────────────────────────────
print(f"\n{SEP}\n  2. REPROCESSING STUCK PENDING IPNs\n{SEP}")

from payments.sasapay_models import SasaPayIPNLog
from payments.sasapay_service import process_ipn_callback

pending_logs = SasaPayIPNLog.objects.filter(processing_status='pending')
print(f"  Found {pending_logs.count()} pending IPN(s)")

for log in pending_logs:
    raw = log.raw_data
    trans_id = log.trans_id or (raw.get('TransID', '') if isinstance(raw, dict) else '')
    amount = raw.get('TransAmount', '?') if isinstance(raw, dict) else '?'
    bill_ref = raw.get('BillRefNumber', '') if isinstance(raw, dict) else ''
    print(f"\n  Reprocessing: TransID={trans_id}  KES {amount}  BillRef={bill_ref!r}")

    # Check not already recorded (safety)
    from loans.models import Repayment
    if trans_id and Repayment.objects.filter(mpesa_transaction_id=trans_id).exists():
        print("  ✅ Repayment already exists — marking as processed")
        rep = Repayment.objects.filter(mpesa_transaction_id=trans_id).first()
        log.mark(SasaPayIPNLog.STATUS_PROCESSED,
                 note='Repayment found on reprocess',
                 receipt=rep.receipt_number)
        continue

    # Delete this log first so process_ipn_callback creates a fresh one
    # (avoids duplicate guard blocking reprocessing)
    log_data = log.raw_data
    log.delete()

    try:
        result = process_ipn_callback(log_data)
        print(f"  Result: {result}")
        if result.get('success') and result.get('receipt_number'):
            print(f"  ✅ Payment recorded: {result['receipt_number']}")
        elif result.get('message') == 'Already processed':
            print("  ✅ Already processed")
        else:
            print(f"  ❌ Failed: {result.get('message', 'unknown')}")
    except Exception as e:
        print(f"  ❌ Exception during reprocess: {e}")
        import traceback
        traceback.print_exc()

# ── 3. Fix ADMIN_ALERT_PHONES placeholder ────────────────────────────────
print(f"\n{SEP}\n  3. ADMIN_ALERT_PHONES\n{SEP}")
print("  Currently set to placeholder: +254700000000")
print("  Update ADMIN_ALERT_PHONES in settings_production.py or .env")
print("  to your real admin phone number(s) so alerts actually reach you.")
print("  Example in .env:")
print("    ADMIN_ALERT_PHONES=+254712345678,+254712345679")

print(f"\n{SEP}\n  Done.\n{SEP}")
