#pragma once

#include <SDL3/SDL.h>

class crApp;

struct crUserDataBlob
{
    void*  data = nullptr;      // caller frees with Free()
    size_t size = 0;

    void Free()
    {
        SDL_free( data );
        data = nullptr;
        size = 0;
    }
};

struct crUserData_UserSettings
{
    int64_t myInt    = 0;
    float   myFloat  = 0.0f;
    char*   myString = nullptr;   // caller frees with Free()

    void Free()
    {
        SDL_free( myString );
        myString = nullptr;
    }

    bool           FromBlob( crUserDataBlob blob );   // consumes the blob (frees it); fills this
    crUserDataBlob ToBlob() const;                     // serialize to JSON (SDL-allocated; data == nullptr on failure)
};

// completion callbacks — the load callback takes ownership of the blob (call blob.Free())
typedef void ( *crUserData_OnLoaded )( bool success, crUserDataBlob blob, void* context );
typedef void ( *crUserData_OnSaved )( bool success, void* context );

class crUserData
{
private:
    enum class EOp : uint8_t
    {
        NONE = 0,
        LOAD,
        SAVE
    };

    static constexpr const char* FILENAME_USERSETTINGS = "usersettings.json";

    EOp    _op       = EOp::NONE;
    bool   _pending  = false;
    bool   _success  = false;
    bool   _started  = false;               // SAVE: write/flush has been kicked off
    char   _filename[ 256 ] = {};

    crUserDataBlob _saveBlob;     // serialized payload awaiting write (owned)
    crUserDataBlob _loadedBlob;   // LOAD result, handed to the callback (owned until then)

    crUserData_OnLoaded _onLoaded        = nullptr;
    crUserData_OnSaved  _onSaved         = nullptr;
    void*               _callbackContext = nullptr;

    crApp* _app = nullptr;

public:
    void Init( crApp* app );
    void Cleanup();
    void UpdateEarly();     // pump — call while FILE_IO_PENDING

    bool IsStorageReady();  // initial readiness (wasm IDBFS populate)
    bool IsPending() const
    {
        return _pending;
    }

    bool RequestLoadUserSettings( crUserData_OnLoaded callbackOnLoaded, void* context );
    bool RequestSaveUserSettings( crUserData_OnSaved callbackOnSaved, crUserData_UserSettings setting, void* context );

private:
    crUserDataBlob LoadRaw( const char* filename );
    bool           SaveRaw( const char* filename, const void* data, size_t size );
    void           FinishOp();
};
