#ifdef WITH_RIVE_SCRIPTING
#include "rive/lua/rive_lua_libs.hpp"
#include "rive/data_bind/data_values/data_value_number.hpp"

#include <math.h>
#include <stdio.h>

using namespace rive;

ScriptedDataValue::~ScriptedDataValue()
{
    if (m_dataValue)
    {
        delete m_dataValue;
    }
}

static int property_namecall_atom(lua_State* L,
                                  ScriptedDataValue* scriptedDataValue,
                                  uint8_t tag,
                                  int atom,
                                  bool& error)
{
    switch (atom)
    {
        case (int)LuaAtoms::value:
        {
            assert(scriptedDataValue->state() == L);
            switch (tag)
            {
                case ScriptedDataValueNumber::luaTag:
                {
                    auto dataValue =
                        scriptedDataValue->dataValue()->as<DataValueNumber>();
                    lua_pushnumber(L, dataValue->value());
                    return 1;
                }
                case ScriptedDataValueString::luaTag:
                {
                    auto dataValue =
                        scriptedDataValue->dataValue()->as<DataValueString>();
                    lua_pushstring(L, dataValue->value().c_str());
                    return 1;
                }
                case ScriptedDataValueBoolean::luaTag:
                {
                    auto dataValue =
                        scriptedDataValue->dataValue()->as<DataValueBoolean>();
                    lua_pushboolean(L, dataValue->value() ? 1 : 0);
                    return 1;
                }
                case ScriptedDataValueColor::luaTag:
                {
                    auto dataValue =
                        scriptedDataValue->dataValue()->as<DataValueColor>();
                    lua_pushinteger(L, dataValue->value());
                    return 1;
                }
            }
        }
        case (int)LuaAtoms::red:
        {
            assert(scriptedDataValue->state() == L);
            switch (tag)
            {
                case ScriptedDataValueColor::luaTag:
                {
                    auto dataValue =
                        scriptedDataValue->dataValue()->as<DataValueColor>();
                    lua_pushinteger(L, dataValue->red());
                    return 1;
                }
            }
        }
        case (int)LuaAtoms::green:
        {
            assert(scriptedDataValue->state() == L);
            switch (tag)
            {
                case ScriptedDataValueColor::luaTag:
                {
                    auto dataValue =
                        scriptedDataValue->dataValue()->as<DataValueColor>();
                    lua_pushinteger(L, dataValue->green());
                    return 1;
                }
            }
        }
        case (int)LuaAtoms::blue:
        {
            assert(scriptedDataValue->state() == L);
            switch (tag)
            {
                case ScriptedDataValueColor::luaTag:
                {
                    auto dataValue =
                        scriptedDataValue->dataValue()->as<DataValueColor>();
                    lua_pushinteger(L, dataValue->blue());
                    return 1;
                }
            }
        }
        case (int)LuaAtoms::alpha:
        {
            assert(scriptedDataValue->state() == L);
            switch (tag)
            {
                case ScriptedDataValueColor::luaTag:
                {
                    auto dataValue =
                        scriptedDataValue->dataValue()->as<DataValueColor>();
                    lua_pushinteger(L, dataValue->alpha());
                    return 1;
                }
            }
        }
    }
    error = true;
    return 0;
}

// Direct field getters dispatched per-tag. Each ScriptedDataValue subtype has
// its own luaTag, so we can register without needing the inner tag switch the
// slow path uses.

static void data_value_number_direct_value(void* udata, void* result)
{
    auto* self = (ScriptedDataValue*)udata;
    lua_userdatadirectfield_setnumber(
        result,
        self->dataValue()->as<DataValueNumber>()->value());
}

static void data_value_boolean_direct_value(void* udata, void* result)
{
    auto* self = (ScriptedDataValue*)udata;
    lua_userdatadirectfield_setboolean(
        result,
        self->dataValue()->as<DataValueBoolean>()->value() ? 1 : 0);
}

static void data_value_color_direct_value(void* udata, void* result)
{
    auto* self = (ScriptedDataValue*)udata;
    lua_userdatadirectfield_setnumber(
        result,
        (double)self->dataValue()->as<DataValueColor>()->value());
}

static void data_value_color_direct_red(void* udata, void* result)
{
    auto* self = (ScriptedDataValue*)udata;
    lua_userdatadirectfield_setnumber(
        result,
        (double)self->dataValue()->as<DataValueColor>()->red());
}

static void data_value_color_direct_green(void* udata, void* result)
{
    auto* self = (ScriptedDataValue*)udata;
    lua_userdatadirectfield_setnumber(
        result,
        (double)self->dataValue()->as<DataValueColor>()->green());
}

static void data_value_color_direct_blue(void* udata, void* result)
{
    auto* self = (ScriptedDataValue*)udata;
    lua_userdatadirectfield_setnumber(
        result,
        (double)self->dataValue()->as<DataValueColor>()->blue());
}

static void data_value_color_direct_alpha(void* udata, void* result)
{
    auto* self = (ScriptedDataValue*)udata;
    lua_userdatadirectfield_setnumber(
        result,
        (double)self->dataValue()->as<DataValueColor>()->alpha());
}

static int data_value_index(lua_State* L)
{
    int atom;
    lua_tostringatom(L, 2, &atom);

    size_t namelen = 0;
    const char* name = luaL_checklstring(L, 2, &namelen);

    auto tag = lua_userdatatag(L, 1);
    auto scriptedDataValue = (ScriptedDataValue*)lua_touserdata(L, 1);

    bool error = false;
    int stackChange =
        property_namecall_atom(L, scriptedDataValue, tag, atom, error);
    if (!error)
    {
        return stackChange;
    }

    luaL_error(L, "'%s' is not a valid index of DataValue", name);
    return 0;
}

static int data_value_newindex(lua_State* L)
{
    int atom;
    const char* key = lua_tostringatom(L, 2, &atom);
    if (!key)
    {
        luaL_typeerrorL(L, 2, lua_typename(L, LUA_TSTRING));
        return 0;
    }

    auto tag = lua_userdatatag(L, 1);
    auto scriptedDataValue = (ScriptedDataValue*)lua_touserdata(L, 1);
    switch (atom)
    {
        case (int)LuaAtoms::value:
        {
            switch (tag)
            {
                case ScriptedDataValueNumber::luaTag:
                {
                    auto val = float(luaL_checknumber(L, 3));
                    scriptedDataValue->dataValue()
                        ->as<DataValueNumber>()
                        ->value(val);
                    return 1;
                }
                case ScriptedDataValueString::luaTag:
                {
                    auto val = luaL_checkstring(L, 3);
                    scriptedDataValue->dataValue()
                        ->as<DataValueString>()
                        ->value(val);
                    return 1;
                }
                case ScriptedDataValueBoolean::luaTag:
                {
                    auto val = luaL_checkboolean(L, 3);
                    scriptedDataValue->dataValue()
                        ->as<DataValueBoolean>()
                        ->value(val != 0);
                    return 1;
                }
                case ScriptedDataValueColor::luaTag:
                {
                    auto val = luaL_checkunsigned(L, 3);
                    scriptedDataValue->dataValue()->as<DataValueColor>()->value(
                        val);
                    return 1;
                }
            }
        }
        case (int)LuaAtoms::red:
        {
            switch (tag)
            {
                case ScriptedDataValueColor::luaTag:
                {
                    auto val = luaL_checkinteger(L, 3);
                    scriptedDataValue->dataValue()->as<DataValueColor>()->red(
                        val);
                    return 1;
                }
                default:
                    return 1;
            }
        }
        case (int)LuaAtoms::green:
        {
            switch (tag)
            {
                case ScriptedDataValueColor::luaTag:
                {
                    auto val = luaL_checkinteger(L, 3);
                    scriptedDataValue->dataValue()->as<DataValueColor>()->green(
                        val);
                    return 1;
                }
                default:
                    return 1;
            }
        }
        case (int)LuaAtoms::blue:
        {
            switch (tag)
            {
                case ScriptedDataValueColor::luaTag:
                {
                    auto val = luaL_checkinteger(L, 3);
                    scriptedDataValue->dataValue()->as<DataValueColor>()->blue(
                        val);
                    return 1;
                }
                default:
                    return 1;
            }
        }
        case (int)LuaAtoms::alpha:
        {
            switch (tag)
            {
                case ScriptedDataValueColor::luaTag:
                {
                    auto val = luaL_checkinteger(L, 3);
                    scriptedDataValue->dataValue()->as<DataValueColor>()->alpha(
                        val);
                    return 1;
                }
                default:
                    return 1;
            }
        }
        default:
            return 0;
    }

    return 0;
}

static int dataValue_number(lua_State* L)
{
    lua_newrive<ScriptedDataValueNumber>(L, L, 0);

    return 1;
}

static int dataValue_string(lua_State* L)
{
    lua_newrive<ScriptedDataValueString>(L, L, "");

    return 1;
}

static int dataValue_boolean(lua_State* L)
{
    lua_newrive<ScriptedDataValueBoolean>(L, L, false);

    return 1;
}

static int dataValue_color(lua_State* L)
{
    lua_newrive<ScriptedDataValueColor>(L, L, 0);

    return 1;
}

static int data_value_namecall(lua_State* L)
{
    int atom;
    const char* str = lua_namecallatom(L, &atom);
    if (str != nullptr)
    {
        auto dataValue = (ScriptedDataValue*)lua_touserdata(L, 1);
        switch (atom)
        {
            case (int)LuaAtoms::isNumber:
            {
                assert(dataValue->state() == L);
                lua_pushboolean(L, dataValue->isNumber() ? 1 : 0);
                return 1;
            }
            case (int)LuaAtoms::isString:
            {
                assert(dataValue->state() == L);
                lua_pushboolean(L, dataValue->isString() ? 1 : 0);
                return 1;
            }
            case (int)LuaAtoms::isBoolean:
            {
                assert(dataValue->state() == L);
                lua_pushboolean(L, dataValue->isBoolean() ? 1 : 0);
                return 1;
            }
            case (int)LuaAtoms::isColor:
            {
                assert(dataValue->state() == L);
                lua_pushboolean(L, dataValue->isColor() ? 1 : 0);
                return 1;
            }
            default:
                break;
        }
    }

    luaL_error(L,
               "%s is not a valid method of %s",
               str,
               ScriptedPropertyViewModel::luaName);
    return 0;
}

static const luaL_Reg dataValueStaticMethods[] = {
    {"number", dataValue_number},
    {"string", dataValue_string},
    {"boolean", dataValue_boolean},
    {"color", dataValue_color},
    {nullptr, nullptr}};

int luaopen_rive_data_values(lua_State* L)
{
    {

        luaL_register(L, ScriptedDataValue::luaName, dataValueStaticMethods);
    }
    {
        lua_register_rive<ScriptedDataValueNumber>(L);

        lua_pushcfunction(L, data_value_index, nullptr);
        lua_setfield(L, -2, "__index");

        lua_pushcfunction(L, data_value_newindex, nullptr);
        lua_setfield(L, -2, "__newindex");

        lua_pushcfunction(L, data_value_namecall, nullptr);
        lua_setfield(L, -2, "__namecall");

        lua_setreadonly(L, -1, true);
        lua_pop(L, 1); // pop the metatable

        lua_registeruserdatadirectfieldget(L,
                                           ScriptedDataValueNumber::luaTag,
                                           "value",
                                           data_value_number_direct_value);
    }
    {
        lua_register_rive<ScriptedDataValueString>(L);

        lua_pushcfunction(L, data_value_index, nullptr);
        lua_setfield(L, -2, "__index");

        lua_pushcfunction(L, data_value_newindex, nullptr);
        lua_setfield(L, -2, "__newindex");

        lua_pushcfunction(L, data_value_namecall, nullptr);
        lua_setfield(L, -2, "__namecall");

        lua_setreadonly(L, -1, true);
        lua_pop(L, 1); // pop the metatable
    }
    {
        lua_register_rive<ScriptedDataValueBoolean>(L);

        lua_pushcfunction(L, data_value_index, nullptr);
        lua_setfield(L, -2, "__index");

        lua_pushcfunction(L, data_value_newindex, nullptr);
        lua_setfield(L, -2, "__newindex");

        lua_pushcfunction(L, data_value_namecall, nullptr);
        lua_setfield(L, -2, "__namecall");

        lua_setreadonly(L, -1, true);
        lua_pop(L, 1); // pop the metatable

        lua_registeruserdatadirectfieldget(L,
                                           ScriptedDataValueBoolean::luaTag,
                                           "value",
                                           data_value_boolean_direct_value);
    }
    {
        lua_register_rive<ScriptedDataValueColor>(L);

        lua_pushcfunction(L, data_value_index, nullptr);
        lua_setfield(L, -2, "__index");

        lua_pushcfunction(L, data_value_newindex, nullptr);
        lua_setfield(L, -2, "__newindex");

        lua_pushcfunction(L, data_value_namecall, nullptr);
        lua_setfield(L, -2, "__namecall");

        lua_setreadonly(L, -1, true);
        lua_pop(L, 1); // pop the metatable

        lua_registeruserdatadirectfieldget(L,
                                           ScriptedDataValueColor::luaTag,
                                           "value",
                                           data_value_color_direct_value);
        lua_registeruserdatadirectfieldget(L,
                                           ScriptedDataValueColor::luaTag,
                                           "red",
                                           data_value_color_direct_red);
        lua_registeruserdatadirectfieldget(L,
                                           ScriptedDataValueColor::luaTag,
                                           "green",
                                           data_value_color_direct_green);
        lua_registeruserdatadirectfieldget(L,
                                           ScriptedDataValueColor::luaTag,
                                           "blue",
                                           data_value_color_direct_blue);
        lua_registeruserdatadirectfieldget(L,
                                           ScriptedDataValueColor::luaTag,
                                           "alpha",
                                           data_value_color_direct_alpha);
    }

    return 1;
}
#endif
