#pragma once

#include "base/base_core.h"
#include "base/base_math.h"

////////////////////////////////
// Input — accumulated per frame, consumed by the app each tick.

#define PLATFORM_MAX_CHARS_PER_FRAME 64
#define PLATFORM_MAX_KEYS_PER_FRAME  32

// Virtual key codes (subset matching Win32 VK_ codes)
enum {
    PKEY_BACKSPACE = 0x08,
    PKEY_TAB       = 0x09,
    PKEY_RETURN    = 0x0D,
    PKEY_ESCAPE    = 0x1B,
    PKEY_DELETE    = 0x2E,
    PKEY_LEFT      = 0x25,
    PKEY_UP        = 0x26,
    PKEY_RIGHT     = 0x27,
    PKEY_DOWN      = 0x28,
    PKEY_HOME      = 0x24,
    PKEY_END       = 0x23,
    PKEY_A         = 0x41,
    PKEY_C         = 0x43,
    PKEY_V         = 0x56,
    PKEY_X         = 0x58,
    PKEY_0         = 0x30,
    PKEY_EQUAL     = 0xBB,  // '='/'+'  (VK_OEM_PLUS)
    PKEY_MINUS     = 0xBD,  // '-'/'_'  (VK_OEM_MINUS)
};

typedef struct PlatformInput {
    // Typed characters (UTF-16 code units, printable only)
    U16 chars[PLATFORM_MAX_CHARS_PER_FRAME];
    S32  char_count;

    // Key-down events (virtual key codes)
    U8  keys[PLATFORM_MAX_KEYS_PER_FRAME];
    S32  key_count;

    // Modifier state at time of last key event
    B32     ctrl_held;
    B32     shift_held;

    // Mouse state (polled per frame)
    Vec2F32  mouse_pos;
    Vec2F32  scroll_delta;
    B32      mouse_down;
    B32      was_mouse_down;
} PlatformInput;

typedef struct PlatformWindow PlatformWindow;

typedef enum PlatformWindowStyle {
    PLATFORM_WINDOW_STYLE_NORMAL           = 0,
    PLATFORM_WINDOW_STYLE_POPUP            = 1,  // utility panel, owned by parent, fixed size
    PLATFORM_WINDOW_STYLE_POPUP_RESIZABLE  = 2,  // utility panel, owned by parent, resizable
} PlatformWindowStyle;

typedef struct PlatformWindowDesc {
    const char          *title;
    S32                  width;
    S32                  height;
    PlatformWindowStyle  style;
    PlatformWindow      *parent;
    B32                  independent;  // if true, don't attach as child (independent top-level window)
} PlatformWindowDesc;

// Helper to create a default PlatformWindowDesc
static inline PlatformWindowDesc platform_window_desc_default(void) {
    PlatformWindowDesc d = {0};
    d.title = "autosample";
    d.width = 1280;
    d.height = 720;
    return d;
}

typedef enum PlatformMsgBoxType {
    PLATFORM_MSGBOX_OK        = 0,
    PLATFORM_MSGBOX_OK_CANCEL = 1,
    PLATFORM_MSGBOX_YES_NO    = 2,
} PlatformMsgBoxType;

typedef struct PlatformMenuItem {
    const char *label;      // NULL = separator
    S32     id;         // command ID (ignored for separators)
} PlatformMenuItem;

typedef struct PlatformMenu {
    const char        *label;
    PlatformMenuItem  *items;
    S32            item_count;
} PlatformMenu;

// Called by the platform layer when the window needs a frame rendered
// (e.g., during a live resize). user_data is the pointer passed to
// platform_set_frame_callback.
typedef void (*PlatformFrameCallback)(void *user_data);

PlatformWindow *platform_create_window(PlatformWindowDesc *desc);
void            platform_destroy_window(PlatformWindow *window);
B32            platform_poll_events(PlatformWindow *window);
void            platform_get_size(PlatformWindow *window, S32 *w, S32 *h);
void           *platform_get_native_handle(PlatformWindow *window);

void            platform_set_frame_callback(PlatformWindow *window, PlatformFrameCallback cb, void *user_data);
void            platform_set_menu(PlatformWindow *window, PlatformMenu *menus, S32 menu_count);
S32         platform_poll_menu_command(PlatformWindow *window);

// Returns accumulated input since last call (keyboard events + polled mouse state), then clears the buffer.
PlatformInput platform_get_input(PlatformWindow *window);

// Returns true if the window's close button was clicked (for popup windows).
B32 platform_window_should_close(PlatformWindow *window);

// Bring a window to front and give it keyboard focus.
void platform_focus_window(PlatformWindow *window);

// Blocks until user responds. Returns 0=first button, 1=second button, -1=dismissed.
S32 platform_message_box(PlatformWindow *parent, const char *title,
                         const char *message, PlatformMsgBoxType type);

// Cursor shapes for resize handles
typedef enum PlatformCursor {
    PLATFORM_CURSOR_ARROW   = 0,
    PLATFORM_CURSOR_SIZE_WE = 1,  // horizontal resize
    PLATFORM_CURSOR_SIZE_NS = 2,  // vertical resize
} PlatformCursor;

void platform_set_cursor(PlatformCursor cursor);

// DPI scale factor for the window's current monitor.
// Returns 1.0 at 96 DPI (100%), 1.5 at 144 DPI (150%), etc.
F32 platform_get_dpi_scale(PlatformWindow *window);

// Clipboard operations (null-terminated UTF-8 strings).
// platform_clipboard_set copies text to the system clipboard.
// platform_clipboard_get returns a pointer to a static buffer (valid until next call), or NULL.
void        platform_clipboard_set(const char *text);
const char *platform_clipboard_get(void);
