#!/usr/bin/env python3
"""Standalone timer alert — launched by WIVEXX, runs independently.

Usage:
    python _timer_alert.py <seconds> [label]

The process sleeps for <seconds>, then shows a tkinter popup with a looping
beep until the user clicks OK.  Designed to be launched as a fully detached
subprocess so it survives WIVEXX closing.
"""
import sys
import time
import threading


def main() -> None:
    if len(sys.argv) < 2:
        print("Usage: _timer_alert.py <seconds> [label]", file=sys.stderr)
        sys.exit(1)
    seconds = int(sys.argv[1])
    label   = sys.argv[2] if len(sys.argv) > 2 else "Timer"
    time.sleep(seconds)
    _show_alert(label, seconds)


def _play_loop(stop_event: threading.Event) -> None:
    """Loop a system beep every 1.2 s until stop_event is set."""
    try:
        import winsound
        while not stop_event.is_set():
            winsound.MessageBeep(winsound.MB_ICONEXCLAMATION)
            time.sleep(1.2)
    except Exception:
        pass


def _round_corners(root) -> None:
    """Best-effort Win11 rounded corners for the borderless alert."""
    try:
        import ctypes
        hwnd = ctypes.windll.user32.GetAncestor(root.winfo_id(), 2) or root.winfo_id()
        val = ctypes.c_int(2)   # DWMWCP_ROUND
        ctypes.windll.dwmapi.DwmSetWindowAttribute(
            hwnd, 33, ctypes.byref(val), ctypes.sizeof(val))
    except Exception:
        pass


def _show_alert(label: str, seconds: int) -> None:
    """Wivexx-styled alert (v1.20): ink card, volt accent, the wivexx. wordmark,
    a pill dismiss button — borderless, topmost, draggable, rounded corners,
    with the volt dot pulsing while the beep loops."""
    import tkinter as tk

    INK      = "#0d0d0d"
    GRAPHITE = "#1c1c1a"
    VOLT     = "#c1f73a"
    VOLT_DIM = "#5e7a1d"
    BONE     = "#f2f0ea"
    STONE    = "#8a8a85"
    LINE     = "#2a2a27"
    FONT     = "Segoe UI"        # clean system font (brand fonts aren't loaded here)

    stop = threading.Event()
    beep_thread = threading.Thread(target=_play_loop, args=(stop,), daemon=True)
    beep_thread.start()

    # Format duration for display
    h, rem = divmod(seconds, 3600)
    m, s   = divmod(rem, 60)
    parts: list[str] = []
    if h:
        parts.append(f"{h}h")
    if m:
        parts.append(f"{m}m")
    if s or not parts:
        parts.append(f"{s}s")
    dur = " ".join(parts)

    root = tk.Tk()
    root.overrideredirect(True)          # borderless
    root.attributes("-topmost", True)
    root.configure(bg=LINE)              # 1px hairline border

    w, hgt = 380, 184
    sw, sh = root.winfo_screenwidth(), root.winfo_screenheight()
    root.geometry(f"{w}x{hgt}+{(sw - w) // 2}+{(sh - hgt) // 3}")

    inner = tk.Frame(root, bg=INK)
    inner.pack(fill=tk.BOTH, expand=True, padx=1, pady=1)

    # the wivexx. wordmark (bone + volt period)
    head = tk.Frame(inner, bg=INK)
    head.pack(pady=(20, 2))
    tk.Label(head, text="wivexx", bg=INK, fg=BONE,
             font=(FONT, 15, "bold")).pack(side=tk.LEFT)
    dot = tk.Label(head, text=".", bg=INK, fg=VOLT, font=(FONT, 15, "bold"))
    dot.pack(side=tk.LEFT)
    tk.Label(inner, text="TIMER", bg=INK, fg=STONE,
             font=("Consolas", 8)).pack()

    tk.Label(inner, text=f"Your {dur} timer has finished, sir.",
             bg=INK, fg=BONE, font=(FONT, 11)).pack(pady=(12, 0))

    if label and label.strip() and label.strip() != dur:
        tk.Label(inner, text=label.strip(), bg=INK, fg=STONE,
                 font=(FONT, 9), wraplength=340).pack(pady=(3, 0))

    def _dismiss(_e=None) -> None:
        stop.set()
        try:
            root.destroy()
        except Exception:
            pass

    # volt-outline pill button (volt is the one CTA element)
    btn = tk.Label(inner, text="dismiss", bg=INK, fg=VOLT,
                   font=("Consolas", 10), cursor="hand2",
                   padx=20, pady=6, borderwidth=1, relief=tk.SOLID)
    btn.configure(highlightbackground=VOLT, highlightcolor=VOLT, highlightthickness=1,
                  bd=0)
    btn.pack(pady=(16, 0))
    btn.bind("<Button-1>", _dismiss)
    btn.bind("<Enter>", lambda _e: btn.config(bg=VOLT, fg=INK))
    btn.bind("<Leave>", lambda _e: btn.config(bg=INK, fg=VOLT))

    root.bind("<Return>", _dismiss)
    root.bind("<Escape>", _dismiss)

    # Draggable (borderless windows can't be moved otherwise)
    drag = {"x": 0, "y": 0}

    def _press(e: tk.Event) -> None:
        drag["x"], drag["y"] = e.x_root - root.winfo_x(), e.y_root - root.winfo_y()

    def _move(e: tk.Event) -> None:
        root.geometry(f"+{e.x_root - drag['x']}+{e.y_root - drag['y']}")

    for _wgt in (inner, head):
        _wgt.bind("<ButtonPress-1>", _press)
        _wgt.bind("<B1-Motion>", _move)

    # Pulse the volt dot + re-assert topmost while the alarm rings
    pulse = {"on": True}

    def _pulse() -> None:
        if stop.is_set():
            return
        pulse["on"] = not pulse["on"]
        try:
            dot.config(fg=VOLT if pulse["on"] else VOLT_DIM)
            root.attributes("-topmost", True)
            root.after(480, _pulse)
        except Exception:
            pass

    root.update_idletasks()
    _round_corners(root)
    root.after(480, _pulse)
    root.focus_force()
    root.mainloop()
    stop.set()


if __name__ == "__main__":
    main()
