#!/usr/bin/env python3
import subprocess, threading, urllib.request
import dbus, dbus.service, dbus.mainloop.glib
from gi.repository import GLib

class MusicNotifier:
    def __init__(self):
        dbus.mainloop.glib.DBusGMainLoop(set_as_default=True)
        bus = dbus.SessionBus()
        obj = bus.get_object("org.freedesktop.Notifications", "/org/freedesktop/Notifications")
        self.iface = dbus.Interface(obj, "org.freedesktop.Notifications")
        self.notif_id = dbus.UInt32(0)

        bus.add_signal_receiver(
            self.on_action,
            dbus_interface="org.freedesktop.Notifications",
            signal_name="ActionInvoked"
        )

    def get_art(self, url):
        if not url:
            return ""
        try:
            if url.startswith("file://"):
                return url[7:]
            path = "/tmp/music_art.jpg"
            urllib.request.urlretrieve(url, path)
            return path
        except:
            return ""

    def notify(self, artist, title, art_url, status):
        art = self.get_art(art_url)
        play_label = "⏸  Pause" if status == "Playing" else "▶  Play"
        actions = ["prev", "⏮  Zurück", "toggle", play_label, "next", "⏭  Weiter"]
        hints = {"image-path": dbus.String(art)} if art else {}

        self.notif_id = self.iface.Notify(
            "music", self.notif_id, art,
            title, artist,
            actions, hints, 0
        )

    def on_action(self, notif_id, action):
        if notif_id != self.notif_id:
            return
        cmds = {"prev": "previous", "toggle": "play-pause", "next": "next"}
        if action in cmds:
            subprocess.run(["playerctl", cmds[action]])

    def monitor(self):
        proc = subprocess.Popen(
            ["playerctl", "--follow", "metadata", "--format",
             "{{artist}}||{{title}}||{{mpris:artUrl}}||{{status}}"],
            stdout=subprocess.PIPE, text=True
        )
        prev = ""
        for line in proc.stdout:
            parts = line.strip().split("||")
            if len(parts) != 4:
                continue
            artist, title, art_url, status = parts
            if title != prev:
                prev = title
                self.notify(artist, title, art_url, status)

    def run(self):
        threading.Thread(target=self.monitor, daemon=True).start()
        GLib.MainLoop().run()

if __name__ == "__main__":
    MusicNotifier().run()
