#!/usr/bin/env python3
"""
Direct database test - connect to MusicBrainz database and process songs from songs_20.json
"""

import json
import psycopg2
import psycopg2.extras
from fuzzywuzzy import fuzz

# Database configuration
DB_HOST = "172.18.0.2"  # Docker container IP that works
DB_PORT = 5432
DB_NAME = "musicbrainz_db"
DB_USER = "musicbrainz"
DB_PASSWORD = "musicbrainz"

def connect_to_database():
    """Connect to the MusicBrainz database."""
    try:
        connection = psycopg2.connect(
            host=DB_HOST,
            port=DB_PORT,
            database=DB_NAME,
            user=DB_USER,
            password=DB_PASSWORD,
            connect_timeout=10
        )
        cursor = connection.cursor(cursor_factory=psycopg2.extras.RealDictCursor)
        print("✅ Connected to MusicBrainz database")
        return connection, cursor
    except Exception as e:
        print(f"❌ Database connection failed: {e}")
        return None, None

def find_artist(artist_name, cursor):
    """Find artist by name in the database."""
    # Clean artist name
    clean_name = artist_name.strip()
    
    # Handle collaborations - extract main artist
    if 'ft.' in clean_name.lower():
        main_artist = clean_name.split('ft.')[0].strip()
    elif 'feat.' in clean_name.lower():
        main_artist = clean_name.split('feat.')[0].strip()
    else:
        main_artist = clean_name
    
    # Try exact match first
    cursor.execute("SELECT name, gid FROM artist WHERE name = %s LIMIT 1", (main_artist,))
    result = cursor.fetchone()
    if result:
        return result['name'], result['gid']
    
    # Try case-insensitive match
    cursor.execute("SELECT name, gid FROM artist WHERE LOWER(name) = LOWER(%s) LIMIT 1", (main_artist,))
    result = cursor.fetchone()
    if result:
        return result['name'], result['gid']
    
    # Try fuzzy search
    cursor.execute("SELECT name, gid FROM artist WHERE name ILIKE %s LIMIT 50", (f"%{main_artist}%",))
    artists = cursor.fetchall()
    
    best_match = None
    best_score = 0
    
    for artist in artists:
        score = fuzz.ratio(main_artist.lower(), artist['name'].lower())
        if score > best_score:
            best_score = score
            best_match = artist
    
    if best_score >= 80:
        return best_match['name'], best_match['gid']
    
    return None, None

def find_recording(title, artist_mbid, cursor):
    """Find recording by title and artist MBID."""
    clean_title = title.strip()
    
    # Remove karaoke patterns
    karaoke_patterns = [
        r'\s*\(Karaoke Version\)',
        r'\s*\(Karaoke\)',
        r'\s*\(Instrumental\)',
        r'\s*\(Backing Track\)',
    ]
    import re
    for pattern in karaoke_patterns:
        clean_title = re.sub(pattern, '', clean_title, flags=re.IGNORECASE)
    clean_title = clean_title.strip()
    
    # Try to find recording by artist and title
    query = """
        SELECT r.name, r.gid
        FROM recording r
        JOIN artist_credit_name acn ON r.artist_credit = acn.artist_credit
        JOIN artist a ON acn.artist = a.id
        WHERE a.gid = %s AND r.name ILIKE %s
        LIMIT 1
    """
    cursor.execute(query, (artist_mbid, f"%{clean_title}%"))
    result = cursor.fetchone()
    
    if result:
        return result['name'], result['gid']
    
    # Try fuzzy search
    query = """
        SELECT r.name, r.gid
        FROM recording r
        JOIN artist_credit_name acn ON r.artist_credit = acn.artist_credit
        JOIN artist a ON acn.artist = a.id
        WHERE a.gid = %s
        LIMIT 100
    """
    cursor.execute(query, (artist_mbid,))
    recordings = cursor.fetchall()
    
    best_match = None
    best_score = 0
    
    for recording in recordings:
        score = fuzz.ratio(clean_title.lower(), recording['name'].lower())
        if score > best_score:
            best_score = score
            best_match = recording
    
    if best_score >= 80:
        return best_match['name'], best_match['gid']
    
    return None, None

def process_songs():
    """Process songs from songs_20.json using direct database access."""
    print("🎵 Processing songs with direct database access")
    print("=" * 60)
    
    # Connect to database
    connection, cursor = connect_to_database()
    if not connection:
        return
    
    try:
        # Load songs
        with open('data/songs_20.json', 'r') as f:
            songs = json.load(f)
        
        print(f"📁 Loaded {len(songs)} songs from songs_20.json")
        print()
        
        # Process each song
        for i, song in enumerate(songs, 1):
            artist_name = song.get('artist', '')
            title = song.get('title', '')
            
            print(f"[{i:2d}/{len(songs)}] {artist_name} - {title}")
            
            # Find artist
            found_artist, artist_mbid = find_artist(artist_name, cursor)
            if found_artist:
                print(f"    ✅ Artist: {found_artist} (MBID: {artist_mbid})")
                
                # Find recording
                found_recording, recording_mbid = find_recording(title, artist_mbid, cursor)
                if found_recording:
                    print(f"    ✅ Recording: {found_recording} (MBID: {recording_mbid})")
                else:
                    print(f"    ❌ Recording not found for: {title}")
            else:
                print(f"    ❌ Artist not found for: {artist_name}")
            
            print()
        
        print("🎉 Processing complete!")
        
    except Exception as e:
        print(f"❌ Error processing songs: {e}")
    finally:
        cursor.close()
        connection.close()

if __name__ == "__main__":
    process_songs() 