"""System tray icon for LED Grab (Windows)."""

import os
import sys
import webbrowser
from pathlib import Path
from tkinter import messagebox
from typing import Callable

try:
    import pystray
    from PIL import Image

    PYSTRAY_AVAILABLE = True
except ImportError:
    PYSTRAY_AVAILABLE = False


def _load_icon(icon_path: Path) -> "Image.Image":
    """Load tray icon from PNG, with a solid-color fallback."""
    if icon_path.exists():
        return Image.open(icon_path)
    # Fallback: blue square
    return Image.new("RGB", (64, 64), (0, 120, 255))


class TrayManager:
    """Manages the system tray icon and its context menu.

    Call ``run()`` on the **main thread** — it blocks until ``stop()``
    is called (from any thread) or the user picks *Exit* from the menu.
    """

    def __init__(self, icon_path: Path, port: int, on_exit: Callable[[], None]) -> None:
        if not PYSTRAY_AVAILABLE:
            raise ImportError("pystray is required for system tray support")

        self._port = port
        self._on_exit = on_exit

        image = _load_icon(icon_path)

        menu = pystray.Menu(
            pystray.MenuItem("Show UI", self._show_ui, default=True),
            pystray.Menu.SEPARATOR,
            pystray.MenuItem("Restart", self._restart),
            pystray.MenuItem("Shutdown", self._shutdown),
        )

        self._icon = pystray.Icon(
            name="ledgrab",
            icon=image,
            title="LED Grab",
            menu=menu,
        )

    # -- menu callbacks ------------------------------------------------

    def _show_ui(self, icon: "pystray.Icon", item: "pystray.MenuItem") -> None:
        webbrowser.open(f"http://localhost:{self._port}")

    def _restart(self, icon: "pystray.Icon", item: "pystray.MenuItem") -> None:
        if not messagebox.askyesno("LED Grab", "Restart the server?"):
            return
        from wled_controller.server_ref import _broadcast_restarting
        _broadcast_restarting()
        self._icon.stop()
        self._on_exit()
        os.environ["WLED_RESTART"] = "1"
        os.execv(sys.executable, [sys.executable, "-m", "wled_controller"])

    def _shutdown(self, icon: "pystray.Icon", item: "pystray.MenuItem") -> None:
        if not messagebox.askyesno("LED Grab", "Shut down the server?"):
            return
        self._on_exit()
        self._icon.stop()

    # -- public API ----------------------------------------------------

    def run(self) -> None:
        """Block the calling thread running the tray message loop."""
        self._icon.run()

    def stop(self) -> None:
        """Stop the tray icon from any thread."""
        self._icon.stop()
