#ifdef WITH_RIVE_SCRIPTING
#include "rive/lua/rive_lua_libs.hpp"
#endif
#include "rive/assets/script_asset.hpp"
#include "rive/artboard.hpp"
#include "rive/file.hpp"
#include "rive/script_input_artboard.hpp"
#include "rive/scripted/scripted_data_converter.hpp"
#include "rive/scripted/scripted_drawable.hpp"
#include "rive/scripted/scripted_layout.hpp"
#include "rive/scripted/scripted_path_effect.hpp"
#include "rive/scripted/scripted_object.hpp"

using namespace rive;

ScriptedObject* ScriptedObject::from(Core* object)
{
    switch (object->coreType())
    {
        case ScriptedDataConverter::typeKey:
            return object->as<ScriptedDataConverter>();
        case ScriptedDrawable::typeKey:
            return object->as<ScriptedDrawable>();
        case ScriptedLayout::typeKey:
            return object->as<ScriptedLayout>();
        case ScriptedPathEffect::typeKey:
            return object->as<ScriptedPathEffect>();
    }
    return nullptr;
}

#ifdef WITH_RIVE_SCRIPTING
void ScriptedObject::setArtboardInput(std::string name, Artboard* artboard)
{
    if (m_state == nullptr || scriptAsset() == nullptr)
    {
        return;
    }

    auto state = m_state->state;
    rive_lua_pushRef(state, m_self);
    lua_newrive<ScriptedArtboard>(state,
                                  state,
                                  ref_rcp(scriptAsset()->file()),
                                  artboard->instance());
    lua_setfield(state, -2, name.c_str());
    rive_lua_pop(state, 1);
    addScriptedDirt(ComponentDirt::ScriptUpdate);
}

void ScriptedObject::setBooleanInput(std::string name, bool value)
{
    if (m_state == nullptr)
    {
        return;
    }
    auto state = m_state->state;
    rive_lua_pushRef(state, m_self);
    lua_pushboolean(state, value);
    lua_setfield(state, -2, name.c_str());
    rive_lua_pop(state, 1);
    addScriptedDirt(ComponentDirt::ScriptUpdate);
}

void ScriptedObject::setNumberInput(std::string name, float value)
{
    if (m_state == nullptr)
    {
        return;
    }
    auto state = m_state->state;
    rive_lua_pushRef(state, m_self);
    lua_pushnumber(state, value);
    lua_setfield(state, -2, name.c_str());
    rive_lua_pop(state, 1);
    addScriptedDirt(ComponentDirt::ScriptUpdate);
}

void ScriptedObject::setIntegerInput(std::string name, int value)
{
    if (m_state == nullptr)
    {
        return;
    }
    auto state = m_state->state;
    rive_lua_pushRef(state, m_self);
    lua_pushunsigned(state, value);
    lua_setfield(state, -2, name.c_str());
    rive_lua_pop(state, 1);
    addScriptedDirt(ComponentDirt::ScriptUpdate);
}

void ScriptedObject::setStringInput(std::string name, std::string value)
{
    if (m_state == nullptr)
    {
        return;
    }
    auto state = m_state->state;
    rive_lua_pushRef(state, m_self);
    lua_pushstring(state, value.c_str());
    lua_setfield(state, -2, name.c_str());
    rive_lua_pop(state, 1);
    addScriptedDirt(ComponentDirt::ScriptUpdate);
}

void ScriptedObject::setViewModelInput(std::string name,
                                       ViewModelInstanceValue* value)
{
    if (m_state == nullptr)
    {
        return;
    }
    auto state = m_state->state;
    rive_lua_pushRef(state, m_self);
    switch (value->coreType())
    {
        case ViewModelInstanceViewModelBase::typeKey:
        {
            auto vm = value->as<ViewModelInstanceViewModel>();
            auto vmi = vm->referenceViewModelInstance();
            if (vmi == nullptr)
            {
                fprintf(stderr,
                        "riveLuaPushViewModelInstanceValue - passed in a "
                        "ViewModelInstanceViewModel with no associated "
                        "ViewModelInstance.\n");
                return;
            }

            lua_newrive<ScriptedViewModel>(state,
                                           state,
                                           ref_rcp(vmi->viewModel()),
                                           vmi);
            break;
        }
        default:
            break;
    }
    lua_setfield(state, -2, name.c_str());
    rive_lua_pop(state, 1);
    addScriptedDirt(ComponentDirt::ScriptUpdate);
}

void ScriptedObject::trigger(std::string name)
{
    if (m_state == nullptr)
    {
        return;
    }
    auto state = m_state->state;
    rive_lua_pushRef(state, m_self);
    if (static_cast<lua_Type>(lua_getfield(state, -1, name.c_str())) !=
        LUA_TFUNCTION)
    {
        rive_lua_pop(state, 2);
        return;
    }
    lua_pushvalue(state, -2);
    rive_lua_pcall(state, 1, 0);
    rive_lua_pop(state, 1);
    addScriptedDirt(ComponentDirt::ScriptUpdate);
}

bool ScriptedObject::scriptAdvance(float elapsedSeconds)
{
    if (!advances() || m_state == nullptr)
    {
        return false;
    }
    auto state = m_state->state;
    rive_lua_pushRef(state, m_self);
    if (static_cast<lua_Type>(lua_getfield(state, -1, "advance")) !=
        LUA_TFUNCTION)
    {
        rive_lua_pop(state, 2);
        return false;
    }
    lua_pushvalue(state, -2);
    lua_pushnumber(state, elapsedSeconds);
    if (static_cast<lua_Status>(rive_lua_pcall(state, 2, 1)) != LUA_OK)
    {
        rive_lua_pop(state, 2);
        return false;
    }
    bool result = lua_toboolean(state, -1);
    rive_lua_pop(state, 2);
    return result;
}

void ScriptedObject::scriptUpdate()
{
    if (!updates() || m_state == nullptr)
    {
        return;
    }
    auto state = m_state->state;
    rive_lua_pushRef(state, m_self);
    if (static_cast<lua_Type>(lua_getfield(state, -1, "update")) !=
        LUA_TFUNCTION)
    {
        rive_lua_pop(state, 2);
        return;
    }
    lua_pushvalue(state, -2);
    if (static_cast<lua_Status>(rive_lua_pcall(state, 1, 0)) != LUA_OK)
    {
        rive_lua_pop(state, 1);
    }
    rive_lua_pop(state, 1);
}

bool ScriptedObject::scriptInit(LuaState* luaState)
{
    auto state = luaState->state;
    for (auto prop : m_customProperties)
    {
        auto scriptInput = ScriptInput::from(prop);
        if (scriptInput && !scriptInput->validateForScriptInit())
        {
            rive_lua_pop(state, 1);
            return false;
        }
    }
    if (static_cast<lua_Status>(rive_lua_pcall(state, 0, 1)) != LUA_OK)
    {
        rive_lua_pop(state, 1);
        return false;
    }
    if (static_cast<lua_Type>(lua_type(state, -1)) != LUA_TTABLE)
    {
        rive_lua_pop(state, 1);
        return false;
    }
    else
    {
        lua_newrive<ScriptedContext>(state, this);
        m_context = lua_ref(state, -1);
        rive_lua_pop(state, 1);
        m_self = lua_ref(state, -1);
        m_state = luaState;
        for (auto prop : m_customProperties)
        {
            auto scriptInput = ScriptInput::from(prop);
            if (scriptInput)
            {
                scriptInput->initScriptedValue();
            }
        }
        if (inits())
        {
            if (static_cast<lua_Type>(lua_getfield(state, -1, "init")) !=
                LUA_TFUNCTION)
            {
                lua_unref(state, m_self);
                lua_unref(state, m_context);
                rive_lua_pop(state, 2);
                m_state = nullptr;
                m_self = 0;
                m_context = 0;
                return false;
            }
            lua_pushvalue(state, -2);
            rive_lua_pushRef(state, m_context);
            auto pCallResult = rive_lua_pcall(state, 2, 1);
            if (static_cast<lua_Status>(pCallResult) != LUA_OK)
            {
                lua_unref(state, m_self);
                lua_unref(state, m_context);
                rive_lua_pop(state, 2);
                m_state = nullptr;
                m_self = 0;
                m_context = 0;
                return false;
            }
            if (!lua_toboolean(state, -1))
            {
                lua_unref(state, m_self);
                lua_unref(state, m_context);
                // Pop boolean and self table
                rive_lua_pop(state, 2);
                m_state = nullptr;
                m_self = 0;
                m_context = 0;
                return false;
            }
            else
            {
                rive_lua_pop(state, 1);
                assert(static_cast<lua_Type>(lua_type(state, -1)) ==
                       LUA_TTABLE);
                rive_lua_pop(state, 1);
            }
        }
        else
        {
            // Init function doesn't exist, just pop the self table
            rive_lua_pop(state, 1);
        }
    }
    return true;
}

void ScriptedObject::disposeScriptInputs()
{
    for (auto prop : m_customProperties)
    {
        auto scriptInput = ScriptInput::from(prop);
        if (scriptInput != nullptr)
        {
            scriptInput->scriptedObject(nullptr);
        }
    }
    m_customProperties.clear();
}

void ScriptedObject::scriptDispose()
{
    disposeScriptInputs();

    if (m_state != nullptr)
    {
        lua_unref(m_state->state, m_self);
        lua_unref(m_state->state, m_context);
#ifdef TESTING
        // Force GC to collect any ScriptedArtboard instances created via
        // instance()
        lua_gc(m_state->state, LUA_GCCOLLECT, 0);
#endif
    }
    m_state = nullptr;
    m_self = 0;
}
#else
void ScriptedObject::setArtboardInput(std::string name, Artboard* artboard) {}

void ScriptedObject::setBooleanInput(std::string name, bool value) {}

void ScriptedObject::setIntegerInput(std::string name, int value) {}

void ScriptedObject::setNumberInput(std::string name, float value) {}

void ScriptedObject::setStringInput(std::string name, std::string value) {}

void ScriptedObject::setViewModelInput(std::string name,
                                       ViewModelInstanceValue* value)
{}

void ScriptedObject::trigger(std::string name) {}

bool ScriptedObject::scriptAdvance(float elapsedSeconds) { return false; }

void ScriptedObject::scriptUpdate() {}

void ScriptedObject::scriptDispose() {}

void ScriptedObject::disposeScriptInputs() {}
#endif

void ScriptedObject::reinit()
{
    if (scriptAsset() != nullptr)
    {
        scriptAsset()->initScriptedObject(this);
    }
}

ScriptAsset* ScriptedObject::scriptAsset() const
{
    return (ScriptAsset*)m_fileAsset.get();
}

void ScriptedObject::setAsset(rcp<FileAsset> asset)
{
    if (asset != nullptr && asset->is<ScriptAsset>())
    {
        FileAssetReferencer::setAsset(asset);
    }
}

void ScriptedObject::markNeedsUpdate() {}