"""Tooltip catalog and widget helper utilities."""

from __future__ import annotations

import json
from pathlib import Path
import tkinter as tk

from version_info import module_version

__version__ = module_version(__name__)

_TOOLTIP_FILE = Path(__file__).with_name("tooltip.json")


def load_tooltip_catalog() -> dict:
    """Load the tooltip catalog from JSON, returning a safe default on errors."""

    try:
        return json.loads(_TOOLTIP_FILE.read_text(encoding="utf-8"))
    except Exception:
        return {"default_language": "IT", "IT": {}, "ENG": {}}


def tooltip_text(key: str, *, language: str | None = None, catalog: dict | None = None) -> str:
    """Return the localized tooltip text for ``key``."""

    data = catalog or load_tooltip_catalog()
    lang = str(language or data.get("default_language") or "IT").upper()
    texts = data.get(lang, {}) or {}
    if key in texts:
        return str(texts[key])
    fallback = data.get("IT", {}) or {}
    return str(fallback.get(key, ""))


class WidgetToolTip:
    """Simple delayed tooltip for Tk/customtkinter widgets."""

    def __init__(self, widget: tk.Misc, text: str, *, delay_ms: int = 400, wraplength: int = 320):
        self.widget = widget
        self.text = text.strip()
        self.delay_ms = int(delay_ms)
        self.wraplength = int(wraplength)
        self._after_id: str | None = None
        self._tip: tk.Toplevel | None = None
        if self.text:
            self.widget.bind("<Enter>", self._schedule_show, add="+")
            self.widget.bind("<Leave>", self._hide, add="+")
            self.widget.bind("<ButtonPress>", self._hide, add="+")

    def _schedule_show(self, _event=None):
        self._cancel_schedule()
        self._after_id = self.widget.after(self.delay_ms, self._show)

    def _cancel_schedule(self):
        if self._after_id is not None:
            try:
                self.widget.after_cancel(self._after_id)
            except Exception:
                pass
            self._after_id = None

    def _show(self):
        self._after_id = None
        if self._tip is not None or not self.text:
            return
        try:
            x = self.widget.winfo_rootx() + 18
            y = self.widget.winfo_rooty() + self.widget.winfo_height() + 8
            tip = tk.Toplevel(self.widget)
            tip.withdraw()
            tip.overrideredirect(True)
            tip.attributes("-topmost", True)
            frame = tk.Frame(tip, bg="#fff7c7", bd=1, relief="solid")
            frame.pack(fill="both", expand=True)
            label = tk.Label(
                frame,
                text=self.text,
                justify="left",
                anchor="w",
                wraplength=self.wraplength,
                bg="#fff7c7",
                fg="#1f1f1f",
                font=("Segoe UI", 9),
                padx=8,
                pady=6,
            )
            label.pack(fill="both", expand=True)
            tip.geometry(f"+{x}+{y}")
            tip.deiconify()
            self._tip = tip
        except Exception:
            self._tip = None

    def _hide(self, _event=None):
        self._cancel_schedule()
        tip = self._tip
        self._tip = None
        if tip is not None:
            try:
                tip.destroy()
            except Exception:
                pass
