"""
Populate BPM and key in sample_metadata.db from filenames.

Uses bpm_key_parser to extract BPM and key from filenames,
then updates the SQLite database for all 511+ samples.

Usage:
    python populate_bpm_from_filenames.py
"""

import sqlite3
import os
import sys
from pathlib import Path

DB_PATH = Path(r"C:\ProgramData\Ableton\Live 12 Suite\Resources\MIDI Remote Scripts\libreria\reggaeton\sample_metadata.db")
LIBRERIA = Path(r"C:\ProgramData\Ableton\Live 12 Suite\Resources\MIDI Remote Scripts\libreria\reggaeton")

sys.path.insert(0, str(Path(__file__).parent))
from bpm_key_parser import parse_bpm, parse_key


def update_existing_samples():
    conn = sqlite3.connect(str(DB_PATH))
    conn.row_factory = sqlite3.Row
    c = conn.cursor()
    
    c.execute("SELECT path, bpm, key FROM samples")
    rows = c.fetchall()
    
    updated_bpm = 0
    updated_key = 0
    skipped = 0
    
    for row in rows:
        path = row["path"]
        current_bpm = row["bpm"]
        current_key = row["key"]
        
        filename = os.path.basename(path)
        
        parsed_bpm = parse_bpm(filename)
        parsed_key = parse_key(filename)
        
        updates = {}
        if parsed_bpm and (current_bpm is None or current_bpm == 0.0):
            updates["bpm"] = parsed_bpm
            updated_bpm += 1
        if parsed_key and (current_key is None or current_key == "" or current_key == "C"):
            updates["key"] = parsed_key
            updated_key += 1
        
        if updates:
            set_clause = ", ".join(f"{k} = ?" for k in updates)
            values = list(updates.values()) + [path]
            c.execute(f"UPDATE samples SET {set_clause} WHERE path = ?", values)
        else:
            skipped += 1
    
    conn.commit()
    conn.close()
    
    print(f"Updated BPM: {updated_bpm}")
    print(f"Updated key: {updated_key}")
    print(f"Skipped (no parseable data): {skipped}")


def scan_and_add_new_samples():
    conn = sqlite3.connect(str(DB_PATH))
    conn.row_factory = sqlite3.Row
    c = conn.cursor()
    c.execute("SELECT path FROM samples")
    existing = {row["path"] for row in c.fetchall()}
    
    added = 0
    for root, dirs, files in os.walk(str(LIBRERIA)):
        for f in files:
            if not f.lower().endswith(('.wav', '.aif', '.aiff', '.mp3')):
                continue
            
            full_path = os.path.join(root, f)
            rel_path = os.path.relpath(full_path, str(LIBRERIA))
            
            if rel_path in existing:
                continue
            
            parsed_bpm = parse_bpm(f)
            parsed_key = parse_key(f)
            
            c.execute(
                "INSERT OR IGNORE INTO samples (path, bpm, key, analyzed_at) VALUES (?, ?, ?, datetime('now'))",
                (rel_path, parsed_bpm, parsed_key)
            )
            
            subfolder = os.path.dirname(rel_path).lower()
            category = _infer_category(subfolder, f)
            if category:
                c.execute(
                    "INSERT OR IGNORE INTO sample_categories (path, category) VALUES (?, ?)",
                    (rel_path, category)
                )
            
            added += 1
            existing.add(rel_path)
    
    conn.commit()
    conn.close()
    
    print(f"Added new samples: {added}")


def _infer_category(subfolder: str, filename: str) -> str:
    subfolder_lower = subfolder.lower()
    filename_lower = filename.lower()
    
    if "kick" in subfolder_lower or "kick" in filename_lower:
        return "kick"
    if "snare" in subfolder_lower or "snare" in filename_lower:
        return "snare"
    if "hi-hat" in subfolder_lower or "hihat" in subfolder_lower or "hi hat" in subfolder_lower:
        return "hihat"
    if "clap" in subfolder_lower or "clap" in filename_lower:
        return "clap"
    if "bass" in subfolder_lower or "bass" in filename_lower:
        return "bass"
    if "perc" in subfolder_lower or "perc" in filename_lower:
        return "perc"
    if "drum" in subfolder_lower or "drumloop" in filename_lower or "loop" in filename_lower:
        return "drumloops"
    if "fx" in subfolder_lower or "effect" in subfolder_lower or "riser" in filename_lower or "impact" in filename_lower:
        return "fx"
    if "synth" in subfolder_lower or "synth" in filename_lower or "lead" in filename_lower:
        return "synths"
    if "melod" in subfolder_lower or "melody" in filename_lower:
        return "melody"
    if "one shot" in subfolder_lower or "oneshot" in subfolder_lower:
        return "oneshots"
    if "chord" in subfolder_lower or "chord" in filename_lower or "progres" in filename_lower:
        return "chords"
    if "pad" in subfolder_lower or "pad" in filename_lower:
        return "pads"
    if "guitar" in subfolder_lower or "guitar" in filename_lower:
        return "guitar"
    if "brass" in subfolder_lower or "brass" in filename_lower:
        return "brass"
    if "bell" in subfolder_lower or "bell" in filename_lower:
        return "bells"
    if "key" in subfolder_lower or "piano" in subfolder_lower:
        return "keys"
    if "voc" in subfolder_lower or "voc" in filename_lower:
        return "vocals"
    if "fill" in filename_lower:
        return "drumloops"
    
    return "other"


def verify_results():
    conn = sqlite3.connect(str(DB_PATH))
    c = conn.cursor()
    
    c.execute("SELECT COUNT(*) FROM samples WHERE bpm > 0")
    with_bpm = c.fetchone()[0]
    c.execute("SELECT COUNT(*) FROM samples")
    total = c.fetchone()[0]
    c.execute("SELECT COUNT(*) FROM samples WHERE key IS NOT NULL AND key != '' AND key != 'C'")
    with_key = c.fetchone()[0]
    
    print(f"\n--- DB Summary ---")
    print(f"Total samples: {total}")
    print(f"With BPM > 0: {with_bpm}")
    print(f"With meaningful key: {with_key}")
    
    c.execute("SELECT path, bpm, key FROM samples WHERE bpm > 0 ORDER BY bpm")
    print("\nSamples with BPM:")
    for row in c.fetchall():
        print(f"  {row[0]}: {row[1]} BPM, key={row[2]}")
    
    c.execute("SELECT COUNT(DISTINCT category) FROM sample_categories")
    print(f"\nDistinct categories: {c.fetchone()[0]}")
    
    c.execute("SELECT category, COUNT(*) FROM sample_categories GROUP BY category ORDER BY COUNT(*) DESC")
    print("\nCategory counts:")
    for row in c.fetchall():
        print(f"  {row[0]}: {row[1]}")
    
    conn.close()


if __name__ == "__main__":
    print("Phase 1: Update existing samples with parsed BPM/key from filenames...")
    update_existing_samples()
    
    print("\nPhase 2: Scan for new samples not yet in DB...")
    scan_and_add_new_samples()
    
    print("\nPhase 3: Verify results...")
    verify_results()
    
    print("\nDone!")