#include "ui/ui_popups.h"

static PopupWindow g_popups[MAX_POPUP_WINDOWS];

static void popup_frame_callback(void *user_data) {
    PopupWindow *popup = (PopupWindow *)user_data;
    if (popup && popup->alive)
        popup_do_frame(popup, 1.0f / 60.0f);
}

PopupWindow *popup_find_by_flag(B32 *flag) {
    for (S32 i = 0; i < MAX_POPUP_WINDOWS; i++)
        if (g_popups[i].alive && g_popups[i].open_flag == flag)
            return &g_popups[i];
    return NULL;
}

PopupWindow *popup_open(PlatformWindow *parent_window, Renderer *parent_renderer,
                        const char *title, B32 *open_flag,
                        S32 width, S32 height,
                        UI_WindowContentFn content_fn, void *user_data,
                        PlatformWindowStyle style, B32 independent) {
    // Find free slot
    PopupWindow *popup = NULL;
    for (S32 i = 0; i < MAX_POPUP_WINDOWS; i++) {
        if (!g_popups[i].alive) { popup = &g_popups[i]; break; }
    }
    if (!popup) return NULL;

    memset(popup, 0, sizeof(*popup));

    // Create native popup window
    PlatformWindowDesc desc = {0};
    desc.title  = title;
    desc.width  = width;
    desc.height = height;
    desc.style       = style;
    desc.parent      = parent_window;
    desc.independent = independent;
    popup->platform_window = platform_create_window(&desc);
    if (!popup->platform_window) return NULL;

    // Create shared renderer
    S32 pw, ph;
    platform_get_size(popup->platform_window, &pw, &ph);

    RendererDesc rdesc = {0};
    rdesc.window_handle = platform_get_native_handle(popup->platform_window);
    rdesc.width         = pw;
    rdesc.height        = ph;
    popup->renderer = renderer_create_shared(parent_renderer, &rdesc);
    if (!popup->renderer) {
        platform_destroy_window(popup->platform_window);
        return NULL;
    }

    // Create UI context
    popup->ui_ctx = ui_create((F32)pw, (F32)ph);
    ui_set_measure_text_fn(popup->ui_ctx, renderer_measure_text, popup->renderer);

    popup->alive          = 1;
    popup->open_flag      = open_flag;
    popup->content_fn     = content_fn;
    popup->content_user_data = user_data;
    popup->width          = width;
    popup->height         = height;
    popup->last_w         = pw;
    popup->last_h         = ph;
    popup->title          = title;
    memset(&popup->wstate, 0, sizeof(popup->wstate));

    platform_set_frame_callback(popup->platform_window, popup_frame_callback, popup);

    return popup;
}

void popup_close(PopupWindow *popup) {
    if (!popup || !popup->alive) return;

    if (popup->open_flag)
        *popup->open_flag = 0;

    popup->alive = 0;
    platform_set_frame_callback(popup->platform_window, NULL, NULL);

    ui_destroy(popup->ui_ctx);
    renderer_destroy(popup->renderer);
    platform_destroy_window(popup->platform_window);
}

void popup_do_frame(PopupWindow *popup, F32 dt) {
    if (!popup->alive) return;

    // Check window size
    S32 w, h;
    platform_get_size(popup->platform_window, &w, &h);
    if (w != popup->last_w || h != popup->last_h) {
        renderer_resize(popup->renderer, w, h);
        popup->last_w = w;
        popup->last_h = h;
    }

    if (!renderer_begin_frame(popup->renderer))
        return;

    // Gather input from popup window
    PlatformInput input = platform_get_input(popup->platform_window);

    // Handle Cmd+/- zoom (propagate to global scale)
    for (S32 k = 0; k < input.key_count; k++) {
        if (input.ctrl_held) {
            if (input.keys[k] == PKEY_EQUAL) g_ui_scale *= 1.1f;
            if (input.keys[k] == PKEY_MINUS) g_ui_scale /= 1.1f;
            if (input.keys[k] == PKEY_0)     g_ui_scale = 1.0f;
        }
    }
    g_ui_scale = Clamp(0.5f, g_ui_scale, 3.0f);

    // Sync shared font atlas from parent renderer (picks up zoom changes)
    renderer_sync_from_parent(popup->renderer);

    // Swap widget state
    UI_WidgetState saved_wstate = g_wstate;
    g_wstate = popup->wstate;

    ui_widgets_begin_frame(input);

    // Build UI
    ui_begin_frame(popup->ui_ctx, (F32)w, (F32)h, input.mouse_pos, input.mouse_down,
                   input.scroll_delta, dt);

    // Background fill
    CLAY(CLAY_ID("PopupBg"),
        .layout = {
            .sizing = { .width = CLAY_SIZING_GROW(), .height = CLAY_SIZING_GROW() },
            .padding = { uip(12), uip(12), uip(10), uip(10) },
            .childGap = uip(8),
            .layoutDirection = CLAY_TOP_TO_BOTTOM,
        },
        .backgroundColor = g_theme.bg_medium,
    ) {
        if (popup->content_fn) {
            popup->content_fn(popup->content_user_data);
        }
    }

    Clay_RenderCommandArray render_commands = ui_end_frame(popup->ui_ctx);

    // Save widget state back
    popup->wstate = g_wstate;
    g_wstate = saved_wstate;

    // Render
    renderer_end_frame(popup->renderer, &render_commands);
}

void popup_close_all(void) {
    for (S32 i = 0; i < MAX_POPUP_WINDOWS; i++)
        if (g_popups[i].alive) popup_close(&g_popups[i]);
}

void popup_close_check(void) {
    for (S32 i = 0; i < MAX_POPUP_WINDOWS; i++) {
        if (g_popups[i].alive && platform_window_should_close(g_popups[i].platform_window))
            popup_close(&g_popups[i]);
    }
}
