"""
SpotifyBridge — Communicate with Spotify via AppleScript
"""

import subprocess
import threading


class SpotifyState:
    """Represents the current Spotify playback state."""

    __slots__ = ('track_name', 'artist_name', 'album_name',
                 'player_position', 'duration', 'is_playing')

    def __init__(self, track_name, artist_name, album_name,
                 player_position, duration, is_playing):
        self.track_name = track_name
        self.artist_name = artist_name
        self.album_name = album_name
        self.player_position = player_position  # seconds
        self.duration = duration  # seconds
        self.is_playing = is_playing

    @property
    def track_key(self):
        return f"{self.track_name}|{self.artist_name}"

    @property
    def display_info(self):
        return f"{self.track_name} — {self.artist_name}"


class SpotifyBridge:
    """Bridge to communicate with Spotify via AppleScript."""

    SCRIPT = '''
    tell application "System Events"
        if not (exists process "Spotify") then
            return "NOT_RUNNING"
        end if
    end tell
    tell application "Spotify"
        set pState to player state as string
        if pState is "stopped" then
            return "STOPPED"
        end if
        set trackName to name of current track
        set artistName to artist of current track
        set albumName to album of current track
        set trackPos to player position
        set trackDur to duration of current track
        return trackName & "|||" & artistName & "|||" & albumName & "|||" & (trackPos as string) & "|||" & (trackDur as string) & "|||" & pState
    end tell
    '''

    @staticmethod
    def get_current_state():
        """
        Fetch the current playback state from Spotify.
        Returns a SpotifyState or None if Spotify is not running/stopped.
        """
        try:
            result = subprocess.run(
                ['osascript', '-e', SpotifyBridge.SCRIPT],
                capture_output=True, text=True, timeout=5
            )

            output = result.stdout.strip()
            if not output or output in ('NOT_RUNNING', 'STOPPED'):
                return None

            parts = output.split('|||')
            if len(parts) < 6:
                return None

            track_name = parts[0]
            artist_name = parts[1]
            album_name = parts[2]
            player_position = float(parts[3])
            duration_ms = float(parts[4])
            player_state = parts[5]

            return SpotifyState(
                track_name=track_name,
                artist_name=artist_name,
                album_name=album_name,
                player_position=player_position,
                duration=duration_ms / 1000.0,
                is_playing=(player_state == 'playing')
            )

        except (subprocess.TimeoutExpired, Exception):
            return None

    @staticmethod
    def get_current_state_async(callback):
        """Fetch state on a background thread and call back on completion."""
        def _worker():
            state = SpotifyBridge.get_current_state()
            callback(state)
        thread = threading.Thread(target=_worker, daemon=True)
        thread.start()
