#!/usr/bin/env python
"""
Debug script to create a test user and diagnose why clients aren't appearing on the site
Checks all filtering conditions that client_list view uses
"""
import os
import sys
import django
from pathlib import Path

# Setup Django
def setup_django():
    """Try to find and setup Django with different settings module names"""
    # Try to find manage.py
    current_dir = Path.cwd()
    manage_py = current_dir / 'manage.py'
    
    if not manage_py.exists():
        # Try parent directory
        parent = current_dir.parent
        manage_py = parent / 'manage.py'
        if manage_py.exists():
            os.chdir(parent)
            current_dir = parent
    
    if not manage_py.exists():
        print(f"Error: manage.py not found in {current_dir}")
        print("Please run this script from your Django project directory")
        sys.exit(1)
    
    # Try common settings module names
    settings_modules = [
        'config.settings',
        'settings',
        'project.settings',
        'branchsystem.settings',
        'branch_system.settings',
    ]
    
    # Also try to detect from manage.py
    try:
        with open(manage_py, 'r') as f:
            content = f.read()
            # Look for DJANGO_SETTINGS_MODULE in manage.py
            import re
            match = re.search(r"DJANGO_SETTINGS_MODULE['\"]\s*[:=]\s*['\"]([^'\"]+)['\"]", content)
            if match:
                detected_settings = match.group(1)
                if detected_settings not in settings_modules:
                    settings_modules.insert(0, detected_settings)
    except:
        pass
    
    # Try each settings module
    last_error = None
    for settings_module in settings_modules:
        try:
            os.environ.setdefault('DJANGO_SETTINGS_MODULE', settings_module)
            django.setup()
            print(f"✓ Successfully loaded Django with settings: {settings_module}")
            return
        except Exception as e:
            last_error = e
            continue
    
    # If all failed, show error
    print(f"Error setting up Django: {last_error}")
    print(f"\nTried settings modules: {', '.join(settings_modules)}")
    print("\nPlease specify the correct settings module:")
    print("  export DJANGO_SETTINGS_MODULE=your_project.settings")
    print("  python3 debug_client_visibility.py")
    sys.exit(1)

# Setup Django
setup_django()

from django.utils import timezone
from datetime import datetime, timedelta
from users.models import CustomUser, Branch
from django.db import transaction

# Color codes
class Colors:
    RED = '\033[91m'
    GREEN = '\033[92m'
    YELLOW = '\033[93m'
    BLUE = '\033[94m'
    RESET = '\033[0m'
    BOLD = '\033[1m'

def print_header(text):
    print(f"\n{Colors.BOLD}{Colors.BLUE}{'='*70}")
    print(f"  {text}")
    print(f"{'='*70}{Colors.RESET}\n")

def print_success(text):
    print(f"{Colors.GREEN}✓ {text}{Colors.RESET}")

def print_error(text):
    print(f"{Colors.RED}✗ {text}{Colors.RESET}")

def print_warning(text):
    print(f"{Colors.YELLOW}⚠ {text}{Colors.RESET}")

def print_info(text):
    print(f"{Colors.BLUE}→ {text}{Colors.RESET}")

def check_branches():
    """Check available branches"""
    print_header("Checking Available Branches")
    
    branches = Branch.objects.filter(is_active=True)
    print_info(f"Found {branches.count()} active branch(es):")
    
    for branch in branches:
        print(f"  - {branch.name} (ID: {branch.id}, Code: {branch.code}, Main: {branch.is_main_branch})")
    
    main_branch = branches.filter(is_main_branch=True).first()
    juja_branch = branches.filter(name__icontains='juja').first()
    
    return main_branch, juja_branch, branches

def check_existing_test_users():
    """Check for existing test users"""
    print_header("Checking for Existing Test Users")
    
    test_users = CustomUser.objects.filter(
        email__icontains='test_debug',
        role='borrower'
    )
    
    count = test_users.count()
    print_info(f"Found {count} existing test user(s)")
    
    if count > 0:
        print_warning("Cleaning up existing test users...")
        for user in test_users:
            print(f"  - Deleting: {user.get_full_name()} ({user.email})")
            user.delete()
        print_success("Test users cleaned up")
    
    return count

def create_test_user(branch):
    """Create a test user with proper attributes"""
    print_header("Creating Test User")
    
    timestamp = datetime.now().strftime('%Y%m%d_%H%M%S')
    test_email = f'test_debug_{timestamp}@example.com'
    test_phone = f'+254712{timestamp[-6:]}'  # Use last 6 digits of timestamp
    
    print_info(f"Creating user with:")
    print(f"  Email: {test_email}")
    print(f"  Phone: {test_phone}")
    print(f"  Branch: {branch.name if branch else 'None'}")
    
    try:
        with transaction.atomic():
            user = CustomUser.objects.create_user(
                username=test_phone,
                email=test_email,
                phone_number=test_phone,
                first_name='Test',
                last_name='Debug User',
                role='borrower',
                status='active',  # IMPORTANT: Set to active
                is_active=True,
                branch=branch,
                date_joined=timezone.now(),
            )
            
            print_success(f"User created successfully!")
            print(f"  ID: {user.id}")
            print(f"  Full Name: {user.get_full_name()}")
            print(f"  Status: {user.status}")
            print(f"  Is Active: {user.is_active}")
            print(f"  Branch: {user.branch.name if user.branch else 'None'}")
            print(f"  Date Joined: {user.date_joined}")
            print(f"  Rejected At: {user.rejected_at}")
            print(f"  Rejected By: {user.rejected_by}")
            
            return user
    except Exception as e:
        print_error(f"Failed to create user: {e}")
        import traceback
        traceback.print_exc()
        return None

def check_client_list_filters(user):
    """Check all conditions that client_list uses to filter clients"""
    print_header("Checking client_list Filter Conditions")
    
    checks = []
    
    # Check 1: Role
    is_borrower = user.role == 'borrower'
    checks.append(('Role is borrower', is_borrower, 'Required'))
    print(f"  {'✓' if is_borrower else '✗'} Role: {user.role} {'(CORRECT)' if is_borrower else '(SHOULD BE borrower)'}")
    
    # Check 2: Status exclusions
    is_rejected = user.rejected_at is not None or user.rejected_by is not None
    is_pending = user.status == 'pending_approval'
    is_inactive_status = user.status == 'inactive'
    should_exclude = is_rejected or is_pending or is_inactive_status
    checks.append(('Not rejected/pending/inactive', not should_exclude, 'Required'))
    print(f"  {'✓' if not is_rejected else '✗'} Rejected: {is_rejected}")
    print(f"  {'✓' if not is_pending else '✗'} Status pending: {is_pending} (status: {user.status})")
    print(f"  {'✓' if not is_inactive_status else '✗'} Status inactive: {is_inactive_status}")
    
    # Check 3: Status must be active
    is_active_status = user.status == 'active'
    checks.append(('Status is active', is_active_status, 'Required'))
    print(f"  {'✓' if is_active_status else '✗'} Status: {user.status} {'(CORRECT)' if is_active_status else '(SHOULD BE active)'}")
    
    # Check 4: Is active flag
    is_active_flag = user.is_active
    checks.append(('is_active flag is True', is_active_flag, 'Required'))
    print(f"  {'✓' if is_active_flag else '✗'} Is Active: {is_active_flag} {'(CORRECT)' if is_active_flag else '(SHOULD BE True)'}")
    
    # Check 5: Branch assignment
    has_branch = user.branch is not None
    checks.append(('Has branch assigned', has_branch, 'Required'))
    print(f"  {'✓' if has_branch else '✗'} Branch: {user.branch.name if user.branch else 'None'} {'(OK)' if has_branch else '(ASSIGN A BRANCH)'}")
    
    # Check 6: Portfolio manager (for staff filtering)
    has_portfolio_manager = user.portfolio_manager is not None
    checks.append(('Has portfolio manager', has_portfolio_manager, 'Optional'))
    print(f"  {'✓' if has_portfolio_manager else '○'} Portfolio Manager: {user.portfolio_manager.get_full_name() if user.portfolio_manager else 'None'} (Optional)")
    
    print("\n" + "="*70)
    print("FILTER CHECK RESULTS:")
    print("="*70)
    
    all_passed = True
    for check_name, passed, required in checks:
        status = "✓ PASS" if passed else ("✗ FAIL" if required == 'Required' else "○ SKIP")
        print(f"  {status}: {check_name} ({required})")
        if not passed and required == 'Required':
            all_passed = False
    
    return all_passed, checks

def test_client_list_query(user):
    """Test the actual query used in client_list"""
    print_header("Testing client_list Query")
    
    from django.db.models import Q
    
    # Base queryset - exactly as in client_list view
    clients = CustomUser.objects.filter(
        role='borrower'
    ).exclude(
        Q(rejected_at__isnull=False) | Q(rejected_by__isnull=False) | Q(status='pending_approval') | Q(status='inactive')
    ).filter(
        status='active',
        is_active=True
    ).select_related()
    
    total_count = clients.count()
    print_info(f"Total clients matching base filters: {total_count}")
    
    # Check if our user is in the queryset
    user_in_queryset = clients.filter(id=user.id).exists()
    
    if user_in_queryset:
        print_success(f"User {user.get_full_name()} IS in the base queryset")
    else:
        print_error(f"User {user.get_full_name()} is NOT in the base queryset")
        
        # Debug why
        print("\nDebugging why user is excluded:")
        
        # Check each condition
        if user.role != 'borrower':
            print_error(f"  - Role is '{user.role}', not 'borrower'")
        if user.rejected_at is not None:
            print_error(f"  - Has rejected_at: {user.rejected_at}")
        if user.rejected_by is not None:
            print_error(f"  - Has rejected_by: {user.rejected_by}")
        if user.status == 'pending_approval':
            print_error(f"  - Status is 'pending_approval'")
        if user.status == 'inactive':
            print_error(f"  - Status is 'inactive'")
        if user.status != 'active':
            print_error(f"  - Status is '{user.status}', not 'active'")
        if not user.is_active:
            print_error(f"  - is_active is False")
    
    # Test with branch filtering
    if user.branch:
        branch_clients = clients.filter(branch_id=user.branch.id)
        branch_count = branch_clients.count()
        user_in_branch = branch_clients.filter(id=user.id).exists()
        
        print(f"\nWith branch filter ({user.branch.name}):")
        print(f"  Total clients in branch: {branch_count}")
        
        if user_in_branch:
            print_success(f"  User IS visible when filtering by branch")
        else:
            print_error(f"  User is NOT visible when filtering by branch")
    
    return user_in_queryset

def check_all_branches(user):
    """Check if user appears when filtering by each branch"""
    print_header("Checking User Visibility Across All Branches")
    
    from django.db.models import Q
    
    base_query = CustomUser.objects.filter(
        role='borrower'
    ).exclude(
        Q(rejected_at__isnull=False) | Q(rejected_by__isnull=False) | Q(status='pending_approval') | Q(status='inactive')
    ).filter(
        status='active',
        is_active=True
    )
    
    branches = Branch.objects.filter(is_active=True)
    
    for branch in branches:
        branch_clients = base_query.filter(branch_id=branch.id)
        user_visible = branch_clients.filter(id=user.id).exists()
        total = branch_clients.count()
        
        status = "✓ VISIBLE" if user_visible else "✗ NOT VISIBLE"
        print(f"  {status} in {branch.name}: {total} total clients (User branch: {user.branch.name if user.branch else 'None'})")

def main():
    """Main function"""
    print_header("Client Visibility Debug Script")
    
    print_info("This script will:")
    print("  1. Check available branches")
    print("  2. Create a test user")
    print("  3. Check all filtering conditions")
    print("  4. Test the client_list query")
    print("  5. Show why the user might not be visible\n")
    
    # Step 1: Check branches
    main_branch, juja_branch, all_branches = check_branches()
    
    if all_branches.count() == 0:
        print_error("No active branches found! This is likely the issue.")
        print_info("Please create at least one branch in the Django admin")
        return
    
    # Step 2: Clean up old test users
    check_existing_test_users()
    
    # Step 3: Create test user
    # Try JUJA OFFICE first, then main branch
    target_branch = juja_branch or main_branch or all_branches.first()
    
    if not target_branch:
        print_error("No branch available to assign user!")
        return
    
    print_info(f"Creating test user in branch: {target_branch.name}")
    user = create_test_user(target_branch)
    
    if not user:
        print_error("Failed to create test user")
        return
    
    # Step 4: Check filter conditions
    all_passed, checks = check_client_list_filters(user)
    
    # Step 5: Test actual query
    user_visible = test_client_list_query(user)
    
    # Step 6: Check all branches
    check_all_branches(user)
    
    # Final summary
    print_header("SUMMARY & RECOMMENDATIONS")
    
    if all_passed and user_visible:
        print_success("All checks passed! User should be visible on the site.")
        print_info("If user still doesn't appear, check:")
        print("  - Browser cache (try hard refresh)")
        print("  - User permissions (portfolio manager filtering)")
        print("  - Session branch selection in browser")
    else:
        print_error("Some checks failed. User may not be visible.")
        print("\nFix the following issues:")
        
        for check_name, passed, required in checks:
            if not passed and required == 'Required':
                print(f"  ✗ {check_name}")
        
        print("\nMost common fixes:")
        print("  1. Set status='active' (not 'pending_approval')")
        print("  2. Set is_active=True")
        print("  3. Assign a branch")
        print("  4. Ensure rejected_at and rejected_by are NULL")
    
    print(f"\n{Colors.BOLD}Test User Details:{Colors.RESET}")
    print(f"  Email: {user.email}")
    print(f"  Phone: {user.phone_number}")
    print(f"  ID: {user.id}")
    print(f"  Branch: {user.branch.name if user.branch else 'None'}")
    print(f"\nYou can delete this user from Django admin or phpMyAdmin when done testing.")

if __name__ == '__main__':
    try:
        main()
    except KeyboardInterrupt:
        print(f"\n{Colors.YELLOW}Script cancelled by user{Colors.RESET}")
        sys.exit(1)
    except Exception as e:
        print_error(f"Unexpected error: {e}")
        import traceback
        traceback.print_exc()
        sys.exit(1)

