
# prompt.py
# Tkinter modal prompt: 1 or 2 buttons, optional timeout.
# Thread-free (Tkinter-safe). Good for PyInstaller.

from __future__ import annotations

from typing import Optional, Literal

Result = Literal["yes", "no", "timeout"]


def prompt_yes_no(
    title: str,
    message: str,
    yes_label: str = "Yes",
    no_label: str = "No",   # if empty/whitespace => single-button mode
    default: Literal["yes", "no"] = "yes",
    timeout_seconds: Optional[int] = None,
    show_countdown: bool = True,
    topmost: bool = True,
    wrap_width: int = 420,
) -> Result:
    import tkinter as tk
    from tkinter import ttk

    single_button = (no_label.strip() == "")

    # Default result if user closes window (X) or ESC
    result_value: Result = "no"

    root = tk.Tk()
    root.title(title)
    root.resizable(False, False)
    if topmost:
        root.attributes("-topmost", True)

    frame = ttk.Frame(root, padding=16)
    frame.grid(row=0, column=0)

    lbl = ttk.Label(frame, text=message, justify="left", wraplength=wrap_width)
    lbl.grid(row=0, column=0, columnspan=2, sticky="w")

    countdown_var = tk.StringVar(value="")
    countdown_lbl = ttk.Label(frame, textvariable=countdown_var)
    countdown_lbl.grid(row=1, column=0, columnspan=2, sticky="w", pady=(8, 0))

    after_id = None
    cancelled = False

    def cancel_timer():
        nonlocal after_id
        if after_id is not None:
            try:
                root.after_cancel(after_id)
            except Exception:
                pass
            after_id = None

    def finish(value: Result):
        nonlocal cancelled, result_value
        cancelled = True
        result_value = value
        cancel_timer()
        try:
            root.destroy()
        except Exception:
            pass

    def on_yes():
        finish("yes")

    def on_no():
        finish("no")

    # Buttons row
    btn_row = 2

    btn_yes = ttk.Button(frame, text=yes_label, command=on_yes)
    btn_yes.grid(row=btn_row, column=0, padx=6, pady=(16, 0))

    btn_no = None
    if not single_button:
        btn_no = ttk.Button(frame, text=no_label, command=on_no)
        btn_no.grid(row=btn_row, column=1, padx=6, pady=(16, 0))
    else:
        # In single-button mode, span across
        btn_yes.grid_configure(column=0, columnspan=2)

    # Default focus
    if default == "yes" or single_button:
        btn_yes.focus_set()
    else:
        if btn_no is not None:
            btn_no.focus_set()

    # Window close acts like "no" (safe default)
    root.protocol("WM_DELETE_WINDOW", on_no)

    # Keyboard shortcuts:
    # ESC => No
    root.bind("<Escape>", lambda _evt: on_no())

    # Enter => default (or the only button)
    if single_button or default == "yes":
        root.bind("<Return>", lambda _evt: on_yes())
    else:
        root.bind("<Return>", lambda _evt: on_no())

    # Center window
    root.update_idletasks()
    w, h = root.winfo_width(), root.winfo_height()
    sw, sh = root.winfo_screenwidth(), root.winfo_screenheight()
    root.geometry(f"+{(sw - w)//2}+{(sh - h)//3}")

    # Timeout (thread-free)
    if timeout_seconds and timeout_seconds > 0:
        remaining = int(timeout_seconds)

        def tick():
            nonlocal remaining, after_id
            if cancelled or not root.winfo_exists():
                return

            if remaining <= 0:
                finish("timeout")
                return

            if show_countdown:
                countdown_var.set(f"Auto close in {remaining} seconds…")

            remaining -= 1
            after_id = root.after(1000, tick)

        after_id = root.after(1000, tick)
    else:
        # If no timeout, hide countdown line (optional)
        if not show_countdown:
            countdown_var.set("")

    root.mainloop()
    return result_value


if __name__ == "__main__":
    # Demo
    r = prompt_yes_no(
        title="VM expiring",
        message="A VM 5 percen belul suspend lesz.\n\nSzeretned meghosszabbitani?",
        yes_label="Renew",
        no_label="Cancel",
        timeout_seconds=20,
    )
    print("Result:", r)

    r2 = prompt_yes_no(
        title="Info",
        message="This is a single-button message.",
        yes_label="OK",
        no_label="",
        timeout_seconds=10,
    )
    print("Result2:", r2)




