#include "Popup.h"
#include <windows.h>
#include <string>
#include <vector>

struct PopupContext
{
    std::string message;
    std::vector<Popup::Option> options;
    int result = -1;
};

static PopupContext *g_ctx = nullptr;
static const char *CLASS_NAME = "PopupWindowClass";

LRESULT CALLBACK PopupWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
    switch (msg)
    {
    case WM_CREATE:
    {

        RECT textRect = {20, 20, 360 + 20, 200};
        HFONT font = (HFONT)GetStockObject(DEFAULT_GUI_FONT);
        HDC hdc = GetDC(hwnd);
        SelectObject(hdc, font);
        DrawTextA(hdc, g_ctx->message.c_str(), -1, &textRect, DT_WORDBREAK | DT_CALCRECT);
        ReleaseDC(hwnd, hdc);

        // Add padding
        int textHeight = textRect.bottom - textRect.top + 8;

        HWND label = CreateWindowA("STATIC", g_ctx->message.c_str(),
                                   WS_CHILD | WS_VISIBLE | SS_LEFT | SS_NOPREFIX,
                                   20, 20, 360, textHeight,
                                   hwnd, nullptr, nullptr, nullptr);
        SendMessage(label, WM_SETFONT, (WPARAM)font, TRUE);

        int btnW = 120, btnH = 28, spacing = 10;
        int totalW = (int)g_ctx->options.size() * btnW + ((int)g_ctx->options.size() - 1) * spacing;
        int x = (400 - totalW) / 2;

        for (int i = 0; i < (int)g_ctx->options.size(); ++i)
        {
            HWND btn = CreateWindowA("BUTTON", g_ctx->options[i].label.c_str(),
                                     WS_CHILD | WS_VISIBLE | BS_DEFPUSHBUTTON,
                                     x + i * (btnW + spacing), 100, btnW, btnH,
                                     hwnd, (HMENU)(1000 + i), GetModuleHandle(nullptr), nullptr);
            SendMessage(btn, WM_SETFONT, (WPARAM)font, TRUE);
        }

        break;
    }

    case WM_COMMAND:
    {
        int id = LOWORD(wParam);
        if (id >= 1000)
        {
            int index = id - 1000;
            if (index >= 0 && index < (int)g_ctx->options.size())
            {
                g_ctx->result = g_ctx->options[index].returnValue;
                DestroyWindow(hwnd);
            }
        }
        break;
    }

    case WM_CLOSE:
        DestroyWindow(hwnd);
        break;

    case WM_DESTROY:
        PostQuitMessage(0);
        break;
    }

    return DefWindowProc(hwnd, msg, wParam, lParam);
}

int Popup::Show(const std::string &title,
                const std::string &message,
                const std::vector<Option> &options)
{
    if (options.size() <= 2)
    {
        if (options.size() == 1 && options[0].label == "OK")
        {
            MessageBoxA(nullptr, message.c_str(), title.c_str(), MB_OK | MB_ICONINFORMATION);
            return options[0].returnValue;
        }
        if ((options[0].label == "Yes" && options[1].label == "No") ||
            (options[0].label == "No" && options[1].label == "Yes"))
        {
            int result = MessageBoxA(nullptr, message.c_str(), title.c_str(), MB_YESNO | MB_ICONQUESTION);
            return (result == IDYES) ? (options[0].label == "Yes" ? options[0].returnValue : options[1].returnValue)
                                     : (options[0].label == "No" ? options[0].returnValue : options[1].returnValue);
        }
    }

    // For 3+ options, use custom window
    static bool registered = false;
    if (!registered)
    {
        WNDCLASSA wc = {};
        wc.lpfnWndProc = PopupWndProc;
        wc.hInstance = GetModuleHandle(nullptr);
        wc.lpszClassName = CLASS_NAME;
        wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
        RegisterClassA(&wc);
        registered = true;
    }

    PopupContext context = {message, options, -1};
    g_ctx = &context;

    HWND hwnd = CreateWindowExA(
        WS_EX_DLGMODALFRAME,
        CLASS_NAME,
        title.c_str(),
        WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU,
        CW_USEDEFAULT, CW_USEDEFAULT, 400, 180,
        nullptr, nullptr, GetModuleHandle(nullptr), nullptr);

    ShowWindow(hwnd, SW_SHOW);
    UpdateWindow(hwnd);

    MSG msg;
    while (IsWindow(hwnd) && GetMessage(&msg, nullptr, 0, 0))
    {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }

    return context.result;
}
