"""
Poe2VisualTool System Tray Manager (Windows Shell_NotifyIcon)
Thu nhỏ ứng dụng xuống khay hệ thống (System Tray) không chiếm thanh tác vụ.
Tích hợp:
  - Khởi tạo icon khay hệ thống (Shell_NotifyIconW qua Win32 API / ctypes).
  - Bắt sự kiện click chuột khôi phục cửa sổ chính.
  - Hỗ trợ chạy ngầm hoàn hảo khi người dùng đóng cửa sổ chính (Minimize to Tray).
100% Zero-Dependency (Thuần Windows API, không bắt buộc pystray).
Bản quyền 2026 Poe2VisualTool.
"""

from __future__ import annotations

import ctypes
from ctypes import wintypes
import os
import threading
from typing import Callable, Optional

# Win32 Constants
NIM_ADD = 0x00000000
NIM_MODIFY = 0x00000001
NIM_DELETE = 0x00000002

NIF_MESSAGE = 0x00000001
NIF_ICON = 0x00000002
NIF_TIP = 0x00000004

WM_USER = 0x0400
WM_TRAYICON = WM_USER + 101

WM_LBUTTONDBLCLK = 0x0203
WM_LBUTTONUP = 0x0202
WM_RBUTTONUP = 0x0205

IMAGE_ICON = 1
LR_LOADFROMFILE = 0x00000010
LR_DEFAULTSIZE = 0x00000040

IDI_APPLICATION = 32512


class NOTIFYICONDATAW(ctypes.Structure):
    _fields_ = [
        ("cbSize", wintypes.DWORD),
        ("hWnd", wintypes.HWND),
        ("uID", wintypes.UINT),
        ("uFlags", wintypes.UINT),
        ("uCallbackMessage", wintypes.UINT),
        ("hIcon", wintypes.HICON),
        ("szTip", wintypes.WCHAR * 128),
        ("dwState", wintypes.DWORD),
        ("dwStateMask", wintypes.DWORD),
        ("szInfo", wintypes.WCHAR * 256),
        ("uTimeoutOrVersion", wintypes.UINT),
        ("szInfoTitle", wintypes.WCHAR * 64),
        ("dwInfoFlags", wintypes.DWORD),
    ]


class SystemTrayIcon:
    """
    Quản lý biểu tượng khay hệ thống cho Poe2VisualTool trên Windows.
    """

    def __init__(
        self,
        tooltip: str = "Poe2VisualTool — Path of Exile 2 Visual QoL",
        on_double_click: Optional[Callable[[], None]] = None,
        on_right_click: Optional[Callable[[], None]] = None,
    ):
        self.tooltip = tooltip[:127]
        self.on_double_click = on_double_click
        self.on_right_click = on_right_click

        self._nid: Optional[NOTIFYICONDATAW] = None
        self._hwnd: Optional[int] = None
        self._is_visible = False

    def attach_to_window(self, hwnd: int) -> bool:
        """Gắn biểu tượng khay vào HWND của cửa sổ chính."""
        if os.name != "nt" or not hwnd:
            return False

        self._hwnd = hwnd

        try:
            # Lấy icon mặc định của ứng dụng
            h_icon = ctypes.windll.user32.LoadIconW(None, wintypes.LPCWSTR(IDI_APPLICATION))

            nid = NOTIFYICONDATAW()
            nid.cbSize = ctypes.sizeof(NOTIFYICONDATAW)
            nid.hWnd = wintypes.HWND(hwnd)
            nid.uID = 1
            nid.uFlags = NIF_MESSAGE | NIF_ICON | NIF_TIP
            nid.uCallbackMessage = WM_TRAYICON
            nid.hIcon = h_icon
            nid.szTip = self.tooltip

            ret = ctypes.windll.shell32.Shell_NotifyIconW(NIM_ADD, ctypes.byref(nid))
            if ret:
                self._nid = nid
                self._is_visible = True
                return True
        except Exception:
            pass
        return False

    def remove(self) -> None:
        """Gỡ biểu tượng khay khi thoát ứng dụng."""
        if self._nid is not None and self._is_visible:
            try:
                ctypes.windll.shell32.Shell_NotifyIconW(NIM_DELETE, ctypes.byref(self._nid))
            except Exception:
                pass
            self._is_visible = False
            self._nid = None

    def update_tooltip(self, text: str) -> None:
        """Cập nhật nội dung hiển thị khi rê chuột vào khay."""
        if self._nid is not None and self._is_visible:
            try:
                self._nid.szTip = text[:127]
                ctypes.windll.shell32.Shell_NotifyIconW(NIM_MODIFY, ctypes.byref(self._nid))
            except Exception:
                pass
