#!/usr/bin/env python3
"""
Comprehensive test script to verify all branch filtering fixes including:
- Loan subpages (completed, deleted)
- Payment Receipts and Notifications 
- Reports dashboard with registration fees
"""

import os
import sys
import django
from datetime import datetime

# Setup Django environment
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'branch_system.settings')
django.setup()

from django.test import RequestFactory
from django.contrib.sessions.middleware import SessionMiddleware
from users.models import Branch, CustomUser
from loans.views import completed_loans, deleted_loans
from utils.views import payment_receipts, notifications
from reports.views import reports_dashboard
from reports.comprehensive_reports import reports_service

def log_message(message, level='INFO'):
    """Log messages with timestamp"""
    timestamp = datetime.now().strftime('%Y-%m-%d %H:%M:%S')
    print(f"[{timestamp}] {level}: {message}")

def test_loan_subpages_filtering():
    """Test branch filtering for loan subpages"""
    log_message("Testing loan subpages branch filtering...")
    
    try:
        # Get existing branches and users
        branches = Branch.objects.filter(is_active=True)[:2]
        if len(branches) < 2:
            log_message("❌ Need at least 2 active branches for testing", 'ERROR')
            return False
        
        admin_users = CustomUser.objects.filter(is_staff=True, is_active=True)[:1]
        if not admin_users:
            log_message("❌ Need at least 1 active admin user for testing", 'ERROR')
            return False
        
        admin_user = admin_users[0]
        branch1, branch2 = branches[0], branches[1]
        
        factory = RequestFactory()
        
        # Test 1: Completed Loans
        log_message("Testing completed loans branch filtering...")
        request = factory.get('/loans/completed/')
        request.user = admin_user
        
        middleware = SessionMiddleware(lambda req: None)
        middleware.process_request(request)
        request.session.save()
        request.session['selected_branch_id'] = str(branch1.id)
        
        try:
            response = completed_loans(request)
            if response.status_code == 200:
                log_message("✅ Completed loans view works with branch filtering")
            else:
                log_message(f"❌ Completed loans failed with status {response.status_code}", 'ERROR')
        except Exception as e:
            log_message(f"❌ Completed loans error: {e}", 'ERROR')
        
        # Test 2: Deleted Loans (admin only)
        log_message("Testing deleted loans branch filtering...")
        request = factory.get('/loans/deleted/')
        request.user = admin_user
        
        middleware = SessionMiddleware(lambda req: None)
        middleware.process_request(request)
        request.session.save()
        request.session['selected_branch_id'] = str(branch1.id)
        
        try:
            response = deleted_loans(request)
            if response.status_code == 200:
                log_message("✅ Deleted loans view works with branch filtering")
            else:
                log_message(f"❌ Deleted loans failed with status {response.status_code}", 'ERROR')
        except Exception as e:
            log_message(f"❌ Deleted loans error: {e}", 'ERROR')
        
        return True
        
    except Exception as e:
        log_message(f"❌ Loan subpages test error: {e}", 'ERROR')
        return False

def test_payment_receipts_notifications():
    """Test Payment Receipts and Notifications branch filtering"""
    log_message("Testing Payment Receipts and Notifications branch filtering...")
    
    try:
        branches = Branch.objects.filter(is_active=True)[:2]
        admin_users = CustomUser.objects.filter(is_staff=True, is_active=True)[:1]
        
        if len(branches) < 2 or not admin_users:
            log_message("❌ Insufficient test data", 'ERROR')
            return False
        
        admin_user = admin_users[0]
        branch1 = branches[0]
        
        factory = RequestFactory()
        
        # Test Payment Receipts
        log_message("Testing Payment Receipts with branch filtering...")
        request = factory.get('/utils/payment-receipts/')
        request.user = admin_user
        
        middleware = SessionMiddleware(lambda req: None)
        middleware.process_request(request)
        request.session.save()
        request.session['selected_branch_id'] = str(branch1.id)
        
        try:
            response = payment_receipts(request)
            if response.status_code == 200:
                log_message("✅ Payment Receipts view works with branch filtering")
            else:
                log_message(f"❌ Payment Receipts failed with status {response.status_code}", 'ERROR')
        except Exception as e:
            log_message(f"❌ Payment Receipts error: {e}", 'ERROR')
        
        # Test Notifications
        log_message("Testing Notifications with branch filtering...")
        request = factory.get('/utils/notifications/')
        request.user = admin_user
        
        middleware = SessionMiddleware(lambda req: None)
        middleware.process_request(request)
        request.session.save()
        request.session['selected_branch_id'] = str(branch1.id)
        
        try:
            response = notifications(request)
            if response.status_code == 200:
                log_message("✅ Notifications view works with branch filtering")
            else:
                log_message(f"❌ Notifications failed with status {response.status_code}", 'ERROR')
        except Exception as e:
            log_message(f"❌ Notifications error: {e}", 'ERROR')
        
        return True
        
    except Exception as e:
        log_message(f"❌ Payment Receipts/Notifications test error: {e}", 'ERROR')
        return False

def test_registration_fees_report():
    """Test Registration Fees reporting with branch filtering"""
    log_message("Testing Registration Fees report with branch filtering...")
    
    try:
        branches = Branch.objects.filter(is_active=True)[:2]
        if len(branches) < 2:
            log_message("❌ Need at least 2 active branches for testing", 'ERROR')
            return False
        
        branch1, branch2 = branches[0], branches[1]
        
        # Test registration fees report without branch filtering
        log_message("Testing registration fees report (all branches)...")
        reg_fees_all = reports_service.get_registration_fees_report()
        log_message(f"Registration fees (all branches): KES {reg_fees_all['summary']['total_registration_income']}")
        
        # Test registration fees report with branch filtering
        log_message(f"Testing registration fees report (branch: {branch1.name})...")
        reg_fees_branch1 = reports_service.get_registration_fees_report(branch_id=branch1.id)
        log_message(f"Registration fees (branch {branch1.name}): KES {reg_fees_branch1['summary']['total_registration_income']}")
        
        log_message(f"Testing registration fees report (branch: {branch2.name})...")
        reg_fees_branch2 = reports_service.get_registration_fees_report(branch_id=branch2.id)
        log_message(f"Registration fees (branch {branch2.name}): KES {reg_fees_branch2['summary']['total_registration_income']}")
        
        # Check if we have any registration fees data
        total_all = reg_fees_all['summary']['total_registration_income']
        total_branch1 = reg_fees_branch1['summary']['total_registration_income']
        total_branch2 = reg_fees_branch2['summary']['total_registration_income']
        
        log_message(f"Registration fees summary:")
        log_message(f"  All branches: KES {total_all}")
        log_message(f"  {branch1.name}: KES {total_branch1}")
        log_message(f"  {branch2.name}: KES {total_branch2}")
        
        if total_all > 0 or total_branch1 > 0 or total_branch2 > 0:
            log_message("✅ Registration fees report working (found some data)")
        else:
            log_message("⚠️  Registration fees report working but no data found")
        
        return True
        
    except Exception as e:
        log_message(f"❌ Registration fees test error: {e}", 'ERROR')
        return False

def test_reports_dashboard_comprehensive():
    """Test Reports Dashboard with comprehensive branch filtering"""
    log_message("Testing Reports Dashboard comprehensive branch filtering...")
    
    try:
        branches = Branch.objects.filter(is_active=True)[:2]
        admin_users = CustomUser.objects.filter(is_staff=True, is_active=True)[:1]
        
        if len(branches) < 2 or not admin_users:
            log_message("❌ Insufficient test data", 'ERROR')
            return False
        
        admin_user = admin_users[0]
        branch1, branch2 = branches[0], branches[1]
        
        factory = RequestFactory()
        
        # Test Reports Dashboard with branch filtering
        log_message(f"Testing Reports Dashboard with branch filtering ({branch1.name})...")
        request = factory.get('/reports/dashboard/')
        request.user = admin_user
        
        middleware = SessionMiddleware(lambda req: None)
        middleware.process_request(request)
        request.session.save()
        request.session['selected_branch_id'] = str(branch1.id)
        
        try:
            response = reports_dashboard(request)
            if response.status_code == 200:
                log_message("✅ Reports Dashboard works with branch filtering")
            else:
                log_message(f"❌ Reports Dashboard failed with status {response.status_code}", 'ERROR')
        except Exception as e:
            log_message(f"❌ Reports Dashboard error: {e}", 'ERROR')
        
        # Test comprehensive dashboard data generation
        log_message("Testing comprehensive dashboard data generation...")
        try:
            dashboard_data_all = reports_service.generate_comprehensive_dashboard_data()
            dashboard_data_branch1 = reports_service.generate_comprehensive_dashboard_data(branch_id=branch1.id)
            dashboard_data_branch2 = reports_service.generate_comprehensive_dashboard_data(branch_id=branch2.id)
            
            log_message("✅ Dashboard data generation works with and without branch filtering")
            
            # Check registration fees specifically
            reg_fees_all = dashboard_data_all.get('registration_fees_current_month', {}).get('summary', {})
            reg_fees_b1 = dashboard_data_branch1.get('registration_fees_current_month', {}).get('summary', {})
            reg_fees_b2 = dashboard_data_branch2.get('registration_fees_current_month', {}).get('summary', {})
            
            log_message(f"Registration fees in dashboard:")
            log_message(f"  All branches: KES {reg_fees_all.get('total_registration_income', 0)}")
            log_message(f"  {branch1.name}: KES {reg_fees_b1.get('total_registration_income', 0)}")
            log_message(f"  {branch2.name}: KES {reg_fees_b2.get('total_registration_income', 0)}")
            
        except Exception as e:
            log_message(f"❌ Dashboard data generation error: {e}", 'ERROR')
        
        return True
        
    except Exception as e:
        log_message(f"❌ Reports Dashboard test error: {e}", 'ERROR')
        return False

def main():
    """Run all comprehensive tests"""
    log_message("Starting comprehensive branch filtering tests...")
    
    tests = [
        ("Loan Subpages Filtering", test_loan_subpages_filtering),
        ("Payment Receipts & Notifications", test_payment_receipts_notifications),
        ("Registration Fees Report", test_registration_fees_report),
        ("Reports Dashboard Comprehensive", test_reports_dashboard_comprehensive)
    ]
    
    results = {}
    
    for test_name, test_func in tests:
        log_message(f"\n--- Running {test_name} Test ---")
        try:
            results[test_name] = test_func()
        except Exception as e:
            log_message(f"❌ {test_name} test failed with exception: {e}", 'ERROR')
            results[test_name] = False
    
    # Summary
    log_message("\n" + "="*60)
    log_message("COMPREHENSIVE TEST RESULTS SUMMARY")
    log_message("="*60)
    
    passed = 0
    total = len(results)
    
    for test_name, result in results.items():
        status = "✅ PASSED" if result else "❌ FAILED"
        log_message(f"{test_name}: {status}")
        if result:
            passed += 1
    
    log_message(f"\nOverall: {passed}/{total} tests passed")
    
    if passed == total:
        log_message("🎉 All comprehensive tests passed! Branch filtering is working correctly across all pages.")
    else:
        log_message("⚠️  Some tests failed. Please review the errors above.")
    
    return passed == total

if __name__ == '__main__':
    success = main()
    sys.exit(0 if success else 1)