#pragma once

#include <SDL3/SDL_stdinc.h>

#include "crArray.h"

class crApp;

struct ImGuiInputTextCallbackData;

typedef void ( *crConsoleCommandFn )( void* context, int32_t argc, const char** argv );

// dev command console — a name -> handler registry behind an ImGui panel. the framework registers
// built-ins; the game module registers its own and must UnregisterByContext on teardown (the
// registry keeps raw context pointers)
class crDevConsole
{
public:
    bool enabled = false;

    static constexpr int32_t MAX_ARGS = 8;

private:
    static constexpr float DROP_HEIGHT = 0.45f;   // fraction of the viewport height

    static constexpr int32_t NAME_LEN      = 24;
    static constexpr int32_t HELP_LEN      = 64;
    static constexpr int32_t LINE_LEN      = 128;
    static constexpr int32_t HISTORY_LINES = 32;

    struct Command
    {
        char               name[ NAME_LEN ];
        char               help[ HELP_LEN ];
        crConsoleCommandFn fn;
        void*              context;
    };

    crApp* _app = nullptr;

    crArray<Command> _commands;

    bool    _focusInput = false;
    char    _input[ LINE_LEN ]                    = {};
    char    _history[ HISTORY_LINES ][ LINE_LEN ] = {};
    int32_t _historyNext  = 0;
    int32_t _historyCount = 0;

public:
    void Init( crApp* app );
    void Cleanup();

    void Register( const char* name, const char* help, crConsoleCommandFn fn, void* context );
    void UnregisterByContext( void* context );

    void Execute( const char* line );
    void Print( const char* fmt, ... );

    void TryRenderPanel();

private:
    static int InputFilter( ImGuiInputTextCallbackData* data );

    static void CmdHelp( void* context, int32_t argc, const char** argv );
    static void CmdTimescale( void* context, int32_t argc, const char** argv );
    static void CmdHash( void* context, int32_t argc, const char** argv );
    static void CmdRunBg( void* context, int32_t argc, const char** argv );
    static void CmdFullscreen( void* context, int32_t argc, const char** argv );
    static void CmdVSync( void* context, int32_t argc, const char** argv );
};
