#!/usr/bin/python3
# cage-kiosk-chooser: between-sessions control menu for a cage kiosk. Shown by
# cage-kiosk-loop when the application exits; prints the chosen action
# ("relaunch", "reboot" or "poweroff") on stdout for the loop to act on.
#
# Runs as the live user inside the session, so wpctl talks to the running
# PipeWire. Shipped by cage-kiosk-aptosid.
import gi, os, subprocess, sys
gi.require_version("Gtk", "3.0")
from gi.repository import Gtk, Gdk

PALETTE = b"""
window { background-color: #181818; }
#title { color: #ff29a8; font-size: 30px; font-weight: bold; }
#subtitle { color: #7a7a7a; font-size: 18px; }
#vol { color: #00eaff; font-size: 18px; }
#hint { color: #5a5a5a; font-size: 13px; }
button { background: #262626; color: #e9e9e9; border: 2px solid #3f3f3f;
         border-radius: 12px; padding: 22px 16px; font-size: 17px; }
button:hover, button:focus { border-color: #00eaff; }
button.power { border-color: #4a2333; }
button.power:hover { border-color: #ff29a8; background: #2a1a22; }
"""

def wpctl(*args):
    try:
        subprocess.run(["wpctl", *args], check=False,
                       stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
    except FileNotFoundError:
        pass

def volume_text():
    try:
        out = subprocess.check_output(
            ["wpctl", "get-volume", "@DEFAULT_AUDIO_SINK@"], text=True)
        pct = int(round(float(out.split()[1]) * 100))
        return "🔇 muted" if "MUTED" in out else f"🔊 volume {pct}%"
    except Exception:
        return "🔊 volume n/a"

def has_backlight():
    try:
        return bool(os.listdir("/sys/class/backlight"))
    except OSError:
        return False

def brightnessctl(*args):
    try:
        subprocess.run(["brightnessctl", "-c", "backlight", *args], check=False,
                       stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
    except FileNotFoundError:
        pass

def brightness_text():
    try:
        out = subprocess.check_output(["brightnessctl", "-c", "backlight", "-m"], text=True)
        return "☀ brightness %s" % out.strip().split(",")[3]
    except Exception:
        return "☀ brightness n/a"

class Chooser(Gtk.Window):
    def __init__(self):
        super().__init__(title="aptosid kiosk")
        self.result = "relaunch"   # default if closed / Esc
        self.fullscreen()

        css = Gtk.CssProvider(); css.load_from_data(PALETTE)
        Gtk.StyleContext.add_provider_for_screen(
            Gdk.Screen.get_default(), css,
            Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION)

        root = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=18)
        root.set_halign(Gtk.Align.CENTER); root.set_valign(Gtk.Align.CENTER)
        self.add(root)

        title = Gtk.Label(label="Kiosk"); title.set_name("title")
        sub = Gtk.Label(label="The application has closed — choose what to do next")
        sub.set_name("subtitle")
        root.pack_start(title, False, False, 0)
        root.pack_start(sub, False, False, 0)

        def mkbtn(label, cb, power=False):
            b = Gtk.Button(label=label); b.connect("clicked", cb)
            b.set_size_request(240, 96)
            if power:
                b.get_style_context().add_class("power")
            return b

        grid = Gtk.Grid(column_spacing=16, row_spacing=16)
        grid.set_halign(Gtk.Align.CENTER)
        grid.attach(mkbtn("↻  Relaunch", self.on_relaunch), 0, 0, 1, 1)
        grid.attach(mkbtn("⭮  Reboot", self.on_reboot, power=True), 1, 0, 1, 1)
        grid.attach(mkbtn("⏻  Shut down", self.on_shutdown, power=True), 2, 0, 1, 1)
        root.pack_start(grid, False, False, 10)

        vol = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL, spacing=12)
        vol.set_halign(Gtk.Align.CENTER)
        self.vol_lbl = Gtk.Label(label=volume_text()); self.vol_lbl.set_name("vol")
        vol.pack_start(mkbtn("🔉  −", self.on_vol_down), False, False, 0)
        vol.pack_start(mkbtn("🔈  Mute", self.on_vol_mute), False, False, 0)
        vol.pack_start(mkbtn("🔊  +", self.on_vol_up), False, False, 0)
        root.pack_start(vol, False, False, 6)
        root.pack_start(self.vol_lbl, False, False, 0)

        if has_backlight():
            bri = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL, spacing=12)
            bri.set_halign(Gtk.Align.CENTER)
            self.bri_lbl = Gtk.Label(label=brightness_text()); self.bri_lbl.set_name("vol")
            bri.pack_start(mkbtn("☀  −", self.on_bri_down), False, False, 0)
            bri.pack_start(mkbtn("☀  +", self.on_bri_up), False, False, 0)
            root.pack_start(bri, False, False, 6)
            root.pack_start(self.bri_lbl, False, False, 0)

        keys = "volume and brightness keys" if has_backlight() else "volume keys"
        hint = Gtk.Label(
            label="Super + Q returns you here anytime    ·    %s work while the app runs" % keys)
        hint.set_name("hint")
        root.pack_start(hint, False, False, 0)

        self.connect("destroy", Gtk.main_quit)
        self.connect("key-press-event", self.on_key)

    def _finish(self, action):
        self.result = action
        self.destroy()

    def on_relaunch(self, _): self._finish("relaunch")
    def on_reboot(self, _):   self._finish("reboot")
    def on_shutdown(self, _): self._finish("poweroff")

    def on_vol_up(self, _):
        wpctl("set-mute", "@DEFAULT_AUDIO_SINK@", "0")   # adjusting unmutes
        wpctl("set-volume", "-l", "1.5", "@DEFAULT_AUDIO_SINK@", "5%+")
        self.vol_lbl.set_label(volume_text())
    def on_vol_down(self, _):
        wpctl("set-mute", "@DEFAULT_AUDIO_SINK@", "0")
        wpctl("set-volume", "@DEFAULT_AUDIO_SINK@", "5%-")
        self.vol_lbl.set_label(volume_text())
    def on_vol_mute(self, _):
        wpctl("set-mute", "@DEFAULT_AUDIO_SINK@", "toggle")
        self.vol_lbl.set_label(volume_text())

    def on_bri_up(self, _):
        brightnessctl("set", "+5%")
        self.bri_lbl.set_label(brightness_text())
    def on_bri_down(self, _):
        brightnessctl("set", "5%-")
        self.bri_lbl.set_label(brightness_text())

    def on_key(self, _w, ev):
        if ev.keyval in (Gdk.KEY_Escape, Gdk.KEY_Return, Gdk.KEY_KP_Enter):
            self._finish("relaunch")

def main():
    w = Chooser(); w.show_all()
    Gtk.main()
    print(w.result, flush=True)
    return 0

if __name__ == "__main__":
    sys.exit(main())
