"""
bpm_worker.py — QThread til BPM-analyse i baggrunden.
Ny v0.9 arkitektur: sange er i songs, filer i files, libraries i libraries.
"""
import sqlite3
from PyQt6.QtCore import QThread, pyqtSignal


class BpmScanWorker(QThread):
    progress = pyqtSignal(int, int)   # done, total
    finished = pyqtSignal(int)        # antal analyseret

    def __init__(self, library_id: int, db_path: str,
                 scan_all: bool = False):
        super().__init__()
        self._library_id = library_id
        self._db_path    = db_path
        self._scan_all   = scan_all
        self._cancelled  = False

    def cancel(self):
        self.requestInterruption()
        self._cancelled = True

    def run(self):
        import time
        self._cancelled = False
        try:
            from local.tag_reader import analyze_bpm
            conn = sqlite3.connect(self._db_path)
            conn.row_factory = sqlite3.Row
            conn.execute("PRAGMA journal_mode=WAL")

            # Ny arkitektur: JOIN songs + files + libraries
            lib_row = conn.execute(
                "SELECT path FROM libraries WHERE id=?", (self._library_id,)
            ).fetchone()
            if not lib_row:
                self.finished.emit(0)
                conn.close()
                return

            lib_path = lib_row["path"]

            if self._scan_all:
                songs = conn.execute("""
                    SELECT s.id, f.local_path
                    FROM songs s
                    JOIN files f ON f.song_id = s.id AND f.file_missing = 0
                    WHERE f.local_path LIKE ?
                """, (lib_path + "%",)).fetchall()
            else:
                songs = conn.execute("""
                    SELECT s.id, f.local_path
                    FROM songs s
                    JOIN files f ON f.song_id = s.id AND f.file_missing = 0
                    WHERE f.local_path LIKE ?
                    AND (s.bpm IS NULL OR s.bpm = 0)
                """, (lib_path + "%",)).fetchall()

            total = len(songs)
            done  = 0

            for song in songs:
                if self._cancelled or self.isInterruptionRequested():
                    break
                try:
                    bpm = analyze_bpm(song["local_path"])
                    if bpm and bpm > 0:
                        conn.execute(
                            "UPDATE songs SET bpm=? WHERE id=?",
                            (int(round(bpm)), song["id"])
                        )
                        conn.commit()
                except Exception:
                    pass
                done += 1
                self.progress.emit(done, total)
                time.sleep(0.01)

            conn.close()
            self.finished.emit(done)
        except Exception:
            self.finished.emit(0)