"""
Migration script from MongoDB/SQLite to PostgreSQL
This script migrates all data to the new PostgreSQL database
"""
import os
import json
from datetime import datetime
from dotenv import load_dotenv

load_dotenv()

# Import PostgreSQL models
from postgresql_models import (
    get_db, init_db,
    Song, Profile, Plan, ProfileSong, PlanSong
)

def migrate_from_json(json_path='data.json'):
    """Migrate data from data.json backup file"""
    print(f"📁 Looking for {json_path}...")
    
    if not os.path.exists(json_path):
        backend_path = os.path.join('backend', json_path)
        if os.path.exists(backend_path):
            json_path = backend_path
        else:
            print(f"❌ {json_path} not found")
            return False
    
    print(f"✅ Found {json_path}")
    
    # Initialize database
    print("🔧 Initializing PostgreSQL database...")
    init_db()
    db = get_db()
    
    try:
        with open(json_path, 'r', encoding='utf-8') as f:
            data = json.load(f)
        
        print(f"📊 Loaded data from {json_path}")
        
        # Migrate profiles
        profiles = data.get('profiles', [])
        print(f"\n👥 Migrating {len(profiles)} profiles...")
        
        profile_id_map = {}  # Old ID -> New ID mapping
        for p in profiles:
            name = p.get('name', '').strip()
            if not name:
                fname = p.get('first_name', '').strip()
                lname = p.get('last_name', '').strip()
                name = f"{fname} {lname}".strip()
            
            if not name:
                continue
            
            # Check if profile already exists
            existing = db.query(Profile).filter(Profile.name == name).first()
            if existing:
                print(f"  ⏭️  Profile '{name}' already exists (ID: {existing.id})")
                profile_id_map[str(p.get('id', name))] = existing.id
                continue
            
            profile = Profile(
                name=name,
                email=p.get('email', ''),
                phone=p.get('contact_number', ''),
                role=p.get('role', 'Worship Leader'),
                notes=p.get('notes', '')
            )
            db.add(profile)
            db.flush()  # Get the ID without committing
            
            old_id = str(p.get('id', name))
            profile_id_map[old_id] = profile.id
            print(f"  ✅ Created profile: {name} (ID: {profile.id})")
        
        db.commit()
        print(f"✅ Migrated {len(profile_id_map)} profiles")
        
        # Migrate songs
        songs = data.get('songs', [])
        print(f"\n🎵 Migrating {len(songs)} songs...")
        
        song_id_map = {}  # Old ID -> New ID mapping
        for s in songs:
            title = s.get('title', '').strip()
            if not title:
                continue
            
            # Check if song already exists
            existing = db.query(Song).filter(Song.title == title).first()
            if existing:
                print(f"  ⏭️  Song '{title}' already exists (ID: {existing.id})")
                song_id_map[str(s.get('id', title))] = existing.id
                continue
            
            song = Song(
                title=title,
                artist=s.get('artist') or s.get('singer') or s.get('band') or 'Unknown',
                source=s.get('source', 'Manual'),
                lyrics=s.get('lyrics') or s.get('content') or '',
                chords=s.get('chords', ''),
                key=s.get('key', ''),
                tempo=s.get('tempo', ''),
                time_signature=s.get('time_signature', ''),
                notes=s.get('notes', ''),
                tags=s.get('tags', '')
            )
            db.add(song)
            db.flush()
            
            old_id = str(s.get('id', title))
            song_id_map[old_id] = song.id
            print(f"  ✅ Created song: {title} (ID: {song.id})")
        
        db.commit()
        print(f"✅ Migrated {len(song_id_map)} songs")
        
        # Migrate profile songs (if they exist in data)
        profile_songs = data.get('profile_songs', [])
        if profile_songs:
            print(f"\n⭐ Migrating {len(profile_songs)} profile-song links...")
            for ps in profile_songs:
                old_profile_id = str(ps.get('profile_id'))
                old_song_id = str(ps.get('song_id'))
                
                if old_profile_id in profile_id_map and old_song_id in song_id_map:
                    profile_song = ProfileSong(
                        profile_id=profile_id_map[old_profile_id],
                        song_id=song_id_map[old_song_id]
                    )
                    db.add(profile_song)
            db.commit()
            print(f"✅ Migrated {len(profile_songs)} profile-song links")
        
        print("\n" + "="*50)
        print("✅ Migration completed successfully!")
        print("="*50)
        print(f"  Profiles: {len(profile_id_map)}")
        print(f"  Songs: {len(song_id_map)}")
        print("="*50)
        
        return True
        
    except Exception as e:
        print(f"\n❌ Migration failed: {e}")
        import traceback
        traceback.print_exc()
        db.rollback()
        return False
    finally:
        db.close()

def migrate_from_mongodb():
    """Migrate data from existing MongoDB database"""
    try:
        from mongodb_models import get_db as get_mongo_db
        print("🔄 Attempting to migrate from MongoDB...")
        
        mongo_db = get_mongo_db()
        pg_db = get_db()
        
        # Migrate profiles
        mongo_profiles = list(mongo_db.profiles.find())
        print(f"\n👥 Migrating {len(mongo_profiles)} profiles from MongoDB...")
        
        profile_id_map = {}
        for mp in mongo_profiles:
            existing = pg_db.query(Profile).filter(Profile.name == mp.get('name')).first()
            if existing:
                profile_id_map[mp['_id']] = existing.id
                continue
            
            profile = Profile(
                name=mp.get('name', 'Unknown'),
                email=mp.get('email', ''),
                phone=mp.get('contact_number', ''),
                notes=mp.get('notes', '')
            )
            pg_db.add(profile)
            pg_db.flush()
            profile_id_map[mp['_id']] = profile.id
            print(f"  ✅ {profile.name}")
        
        pg_db.commit()
        
        # Migrate songs
        mongo_songs = list(mongo_db.songs.find())
        print(f"\n🎵 Migrating {len(mongo_songs)} songs from MongoDB...")
        
        song_id_map = {}
        for ms in mongo_songs:
            existing = pg_db.query(Song).filter(Song.title == ms.get('title')).first()
            if existing:
                song_id_map[ms['_id']] = existing.id
                continue
            
            song = Song(
                title=ms.get('title', 'Untitled'),
                artist=ms.get('artist') or ms.get('singer') or ms.get('band') or 'Unknown',
                lyrics=ms.get('lyrics', ''),
                chords=ms.get('chords', '')
            )
            pg_db.add(song)
            pg_db.flush()
            song_id_map[ms['_id']] = song.id
            print(f"  ✅ {song.title}")
        
        pg_db.commit()
        
        print("\n✅ MongoDB migration completed!")
        pg_db.close()
        return True
        
    except ImportError:
        print("⚠️  MongoDB not available, skipping MongoDB migration")
        return False
    except Exception as e:
        print(f"❌ MongoDB migration failed: {e}")
        return False

if __name__ == '__main__':
    print("="*50)
    print("PostgreSQL Migration Script")
    print("="*50)
    print()
    
    # Try JSON migration first
    if migrate_from_json():
        print("\n✅ Migration from JSON successful!")
    else:
        print("\n⚠️  JSON migration skipped or failed")
        
        # Try MongoDB migration
        if migrate_from_mongodb():
            print("\n✅ Migration from MongoDB successful!")
        else:
            print("\n⚠️  No data sources available for migration")
    
    print("\n💡 Next steps:")
    print("  1. Verify data in PostgreSQL")
    print("  2. Update backend/.env with PostgreSQL connection string")
    print("  3. Start the Flask app with: python app.py")
