#include "native_ui/system_tray.hpp"

#include <cmath>
#include <cwchar>

namespace poe2::ui {

SystemTray::~SystemTray() {
    Destroy();
}

SystemTray::SystemTray(SystemTray&& other) noexcept
    : hWnd_(other.hWnd_)
    , hIcon_(other.hIcon_)
    , created_(other.created_)
    , nid_(other.nid_)
    , lastTip_(std::move(other.lastTip_))
{
    other.hWnd_ = nullptr;
    other.hIcon_ = nullptr;
    other.created_ = false;
    other.nid_ = {};
}

SystemTray& SystemTray::operator=(SystemTray&& other) noexcept {
    if (this != &other) {
        Destroy();
        hWnd_ = other.hWnd_;
        hIcon_ = other.hIcon_;
        created_ = other.created_;
        nid_ = other.nid_;
        lastTip_ = std::move(other.lastTip_);

        other.hWnd_ = nullptr;
        other.hIcon_ = nullptr;
        other.created_ = false;
        other.nid_ = {};
    }
    return *this;
}

HICON SystemTray::CreateProgrammaticIcon(HINSTANCE hInstance) {
    if (hInstance) {
        HICON hApp = LoadIconW(hInstance, MAKEINTRESOURCEW(1));
        if (hApp) return hApp;
    }

    const int cx = GetSystemMetrics(SM_CXSMICON);
    const int cy = GetSystemMetrics(SM_CYSMICON);
    const int w = (cx > 0) ? cx : 16;
    const int h = (cy > 0) ? cy : 16;

    BITMAPV5HEADER bi{};
    bi.bV5Size = sizeof(BITMAPV5HEADER);
    bi.bV5Width = w;
    bi.bV5Height = -h; // Top-down
    bi.bV5Planes = 1;
    bi.bV5BitCount = 32;
    bi.bV5Compression = BI_BITFIELDS;
    bi.bV5RedMask   = 0x00FF0000;
    bi.bV5GreenMask = 0x0000FF00;
    bi.bV5BlueMask  = 0x000000FF;
    bi.bV5AlphaMask = 0xFF000000;

    HDC hScreenDC = GetDC(nullptr);
    uint32_t* pixels = nullptr;
    HBITMAP hColorBmp = CreateDIBSection(hScreenDC, reinterpret_cast<BITMAPINFO*>(&bi), DIB_RGB_COLORS, reinterpret_cast<void**>(&pixels), nullptr, 0);
    ReleaseDC(nullptr, hScreenDC);

    if (!hColorBmp || !pixels) {
        return LoadIconW(nullptr, MAKEINTRESOURCEW(32512));
    }

    // Vẽ biểu tượng đá quý (Cyan-Gold PoE2 Gem)
    const float midX = (w - 1) / 2.0f;
    const float midY = (h - 1) / 2.0f;
    const float rx = midX * 0.88f;
    const float ry = midY * 0.88f;

    for (int y = 0; y < h; ++y) {
        for (int x = 0; x < w; ++x) {
            const float dx = std::abs(x - midX) / (rx > 0.1f ? rx : 1.0f);
            const float dy = std::abs(y - midY) / (ry > 0.1f ? ry : 1.0f);
            const float dist = dx + dy; // Khoảng cách hình thoi diamond

            if (dist <= 1.0f) {
                const float t = static_cast<float>(y) / h;
                uint8_t r = static_cast<uint8_t>(56 + t * 180);   // Gradient Sky Blue -> Gold
                uint8_t g = static_cast<uint8_t>(189 - t * 20);
                uint8_t b = static_cast<uint8_t>(248 - t * 180);
                uint8_t a = 255;
                if (dist > 0.82f) {
                    // Viền sáng nổi bật
                    r = 255; g = 255; b = 255;
                }
                pixels[y * w + x] = (static_cast<uint32_t>(a) << 24) |
                                    (static_cast<uint32_t>(r) << 16) |
                                    (static_cast<uint32_t>(g) << 8)  |
                                     static_cast<uint32_t>(b);
            } else {
                pixels[y * w + x] = 0x00000000; // Trong suốt hoàn toàn
            }
        }
    }

    HBITMAP hMaskBmp = CreateBitmap(w, h, 1, 1, nullptr);
    ICONINFO ii{};
    ii.fIcon = TRUE;
    ii.hbmMask = hMaskBmp;
    ii.hbmColor = hColorBmp;

    HICON hResult = CreateIconIndirect(&ii);

    DeleteObject(hColorBmp);
    DeleteObject(hMaskBmp);

    return hResult ? hResult : LoadIconW(nullptr, MAKEINTRESOURCEW(32512));
}

bool SystemTray::Create(HWND hWnd, HINSTANCE hInstance, UINT callbackMsg) {
    if (created_) return true;
    if (!hWnd) return false;

    hWnd_ = hWnd;
    hIcon_ = CreateProgrammaticIcon(hInstance);

    std::memset(&nid_, 0, sizeof(nid_));
    nid_.cbSize = sizeof(NOTIFYICONDATAW);
    nid_.hWnd = hWnd_;
    nid_.uID = 1;
    nid_.uFlags = NIF_ICON | NIF_MESSAGE | NIF_TIP | NIF_SHOWTIP;
    nid_.uCallbackMessage = callbackMsg;
    nid_.hIcon = hIcon_;

    wcscpy_s(nid_.szTip, L"Poe2VisualTool v2.0 Commercial\nStatus: Initializing...");
    lastTip_ = nid_.szTip;

    if (Shell_NotifyIconW(NIM_ADD, &nid_)) {
        nid_.uVersion = NOTIFYICON_VERSION_4;
        Shell_NotifyIconW(NIM_SETVERSION, &nid_);
        created_ = true;
        return true;
    }
    return false;
}

void SystemTray::Destroy() {
    if (created_ && hWnd_) {
        Shell_NotifyIconW(NIM_DELETE, &nid_);
        created_ = false;
    }
    if (hIcon_) {
        DestroyIcon(hIcon_);
        hIcon_ = nullptr;
    }
    hWnd_ = nullptr;
}

void SystemTray::UpdateStatus(bool attached, uint32_t pid, float currentZoom, float maxZoom) {
    if (!created_) return;

    wchar_t tip[128] = {};
    if (attached) {
        swprintf_s(tip, L"Poe2VisualTool v2.0 Commercial\nAttached: PathOfExile.exe (PID %u)\nZoom: %.1fx / %.1fx",
                   pid, currentZoom, maxZoom);
    } else {
        swprintf_s(tip, L"Poe2VisualTool v2.0 Commercial\nStatus: Waiting for Path of Exile 2...\n(Press F10 to select game exe)");
    }

    if (lastTip_ == tip) return; // Tránh gọi Win32 Shell API thừa
    lastTip_ = tip;

    wcsncpy_s(nid_.szTip, tip, _TRUNCATE);
    nid_.uFlags = NIF_TIP;
    Shell_NotifyIconW(NIM_MODIFY, &nid_);
}

void SystemTray::ShowContextMenu(HWND hWnd, bool streamerMode, bool attached) {
    if (!hWnd) return;

    POINT pt{};
    GetCursorPos(&pt);

    HMENU hMenu = CreatePopupMenu();
    if (!hMenu) return;

    // Header Title
    InsertMenuW(hMenu, static_cast<UINT>(-1), MF_BYPOSITION | MF_STRING | MF_DISABLED, ID_TRAY_TITLE,
                L"⚡ Poe2VisualTool v2.0 Pro");

    // Status line
    std::wstring statusStr = attached
        ? L"🟢 Status: Attached (PathOfExile.exe)"
        : L"🟡 Status: Waiting for Game...";
    InsertMenuW(hMenu, static_cast<UINT>(-1), MF_BYPOSITION | MF_STRING | MF_DISABLED, ID_TRAY_STATUS, statusStr.c_str());

    InsertMenuW(hMenu, static_cast<UINT>(-1), MF_BYPOSITION | MF_SEPARATOR, 0, nullptr);

    // Actions
    InsertMenuW(hMenu, static_cast<UINT>(-1), MF_BYPOSITION | MF_STRING, ID_TRAY_SETTINGS,
                L"⚙️ Settings Dashboard (F11)");
    InsertMenuW(hMenu, static_cast<UINT>(-1), MF_BYPOSITION | MF_STRING, ID_TRAY_PANIC,
                L"🛡️ Instant 1-Frame Panic (F12)");

    std::wstring streamStr = streamerMode
        ? L"👁️ Streamer Mode: ON (OBS Safe)"
        : L"👁️ Streamer Mode: OFF";
    InsertMenuW(hMenu, static_cast<UINT>(-1), MF_BYPOSITION | MF_STRING, ID_TRAY_STREAMER, streamStr.c_str());

    InsertMenuW(hMenu, static_cast<UINT>(-1), MF_BYPOSITION | MF_STRING, ID_TRAY_RESET_ZOOM,
                L"📷 Reset Camera Zoom (1.0x)");

    InsertMenuW(hMenu, static_cast<UINT>(-1), MF_BYPOSITION | MF_SEPARATOR, 0, nullptr);

    InsertMenuW(hMenu, static_cast<UINT>(-1), MF_BYPOSITION | MF_STRING, ID_TRAY_EXIT,
                L"❌ Exit (Thoát)");

    // Đảm bảo menu đóng đúng khi người dùng click ra ngoài
    SetForegroundWindow(hWnd);
    TrackPopupMenuEx(hMenu, TPM_RIGHTBUTTON | TPM_BOTTOMALIGN, pt.x, pt.y, hWnd, nullptr);
    PostMessageW(hWnd, WM_NULL, 0, 0);
    DestroyMenu(hMenu);
}

} // namespace poe2::ui
