#!/usr/bin/env python
"""
Comprehensive Migration Fix Script
This script resolves all migration conflicts by:
1. Checking migration status
2. Marking all migrations as fake
3. Creating fresh migrations
4. Applying them safely
"""
import os
import sys
import django
import subprocess

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

from django.core.management import call_command
from django.db import connection

def run_command(command, description, ignore_errors=False):
    """Run a command and handle errors"""
    print(f"\n🔄 {description}...")
    try:
        result = subprocess.run(command, shell=True, capture_output=True, text=True)
        if result.returncode == 0:
            print(f"✅ {description} completed successfully")
            if result.stdout:
                print(f"Output: {result.stdout}")
            return True
        else:
            if ignore_errors:
                print(f"⚠️ {description} failed but continuing...")
                print(f"Error: {result.stderr}")
                return True
            else:
                print(f"❌ {description} failed")
                print(f"Error: {result.stderr}")
                return False
    except Exception as e:
        if ignore_errors:
            print(f"⚠️ {description} failed with exception but continuing: {str(e)}")
            return True
        else:
            print(f"❌ {description} failed with exception: {str(e)}")
            return False

def check_migration_status():
    """Check current migration status"""
    print("\n🔍 Checking migration status...")
    try:
        result = subprocess.run("python manage.py showmigrations", 
                              shell=True, capture_output=True, text=True)
        if result.returncode == 0:
            print("Migration status:")
            print(result.stdout)
            return True
        else:
            print(f"❌ Failed to check migration status: {result.stderr}")
            return False
    except Exception as e:
        print(f"❌ Failed to check migration status: {str(e)}")
        return False

def fake_all_migrations():
    """Mark all migrations as fake (already applied)"""
    print("\n🔄 Marking all migrations as fake...")
    try:
        call_command('migrate', '--fake')
        print("✅ All migrations marked as fake")
        return True
    except Exception as e:
        print(f"❌ Failed to fake migrations: {str(e)}")
        return False

def create_fresh_migrations():
    """Create fresh migrations for current state"""
    print("\n🔄 Creating fresh migrations...")
    try:
        call_command('makemigrations')
        print("✅ Fresh migrations created")
        return True
    except Exception as e:
        print(f"❌ Failed to create fresh migrations: {str(e)}")
        return False

def apply_migrations_safely():
    """Apply migrations with error handling"""
    print("\n🔄 Applying migrations safely...")
    try:
        # Try to apply migrations normally
        call_command('migrate')
        print("✅ Migrations applied successfully")
        return True
    except Exception as e:
        print(f"⚠️ Normal migration failed: {str(e)}")
        
        # Try with fake flag
        try:
            print("🔄 Trying with fake flag...")
            call_command('migrate', '--fake')
            print("✅ Migrations marked as fake")
            return True
        except Exception as e2:
            print(f"❌ Fake migration also failed: {str(e2)}")
            return False

def reset_migration_state():
    """Reset migration state completely"""
    print("\n🔄 Resetting migration state...")
    try:
        # Get all apps
        from django.apps import apps
        app_configs = apps.get_app_configs()
        
        for app_config in app_configs:
            app_name = app_config.name
            if app_name in ['users', 'loans', 'payments']:
                print(f"🔄 Resetting {app_name} migrations...")
                # Mark all migrations as unapplied
                call_command('migrate', app_name, 'zero', '--fake')
                print(f"✅ {app_name} migrations reset")
        
        return True
    except Exception as e:
        print(f"❌ Failed to reset migration state: {str(e)}")
        return False

def fix_all_migrations():
    """Main function to fix all migration issues"""
    print("🔧 Comprehensive Migration Fix")
    print("=" * 50)
    
    # Step 1: Check current status
    check_migration_status()
    
    # Step 2: Reset migration state
    print("\n🔄 Step 1: Resetting migration state...")
    reset_migration_state()
    
    # Step 3: Create fresh migrations
    print("\n🔄 Step 2: Creating fresh migrations...")
    create_fresh_migrations()
    
    # Step 4: Apply migrations safely
    print("\n🔄 Step 3: Applying migrations safely...")
    if apply_migrations_safely():
        print("✅ Migration fix completed successfully!")
        return True
    else:
        print("❌ Migration fix failed!")
        return False

if __name__ == "__main__":
    print("Comprehensive Migration Fix Script")
    print("This script will resolve all migration conflicts")
    
    # Run fix
    success = fix_all_migrations()
    
    if success:
        print("\n🎉 All migration conflicts resolved!")
        print("\n📋 Next Steps:")
        print("1. Run the deployment script again")
        print("2. Check that all migrations are applied")
        print("3. Test the system functionality")
    else:
        print("\n❌ Failed to resolve migration conflicts!")
        print("\n📋 Manual Steps:")
        print("1. Check your database schema manually")
        print("2. Consider manual database fixes")
        print("3. Contact support for assistance")
        sys.exit(1)
