#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/animation/scripted_listener_action.hpp"
#include "rive/animation/scripted_transition_condition.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"
#include "rive/data_bind/data_bind.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>();
        case ScriptedListenerAction::typeKey:
            return object->as<ScriptedListenerAction>();
        case ScriptedTransitionCondition::typeKey:
            return object->as<ScriptedTransitionCondition>();
    }
    return nullptr;
}

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

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

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

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

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

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

void ScriptedObject::setViewModelInput(std::string name,
                                       ViewModelInstanceValue* value)
{
    if (m_state == nullptr)
    {
        return;
    }
    rive_lua_pushRef(m_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>(m_state,
                                           m_state,
                                           ref_rcp(vmi->viewModel()),
                                           vmi);
            break;
        }
        default:
            break;
    }
    lua_setfield(m_state, -2, name.c_str());
    rive_lua_pop(m_state, 1);
    addScriptedDirt(ComponentDirt::ScriptUpdate);
}

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

#ifdef WITH_RIVE_TOOLS
bool ScriptedObject::hasValidVM()
{
#ifdef WITH_RIVE_SCRIPTING
    if (!m_state)
    {
        return false;
    }
    if (asset())
    {
        auto scriptAsset = asset()->as<ScriptAsset>();
        if (!scriptAsset->file() || !scriptAsset->file()->hasVM())
        {
            m_state = nullptr;
            return false;
        }
    }
#endif
    return true;
}
#endif

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

void ScriptedObject::scriptUpdate()
{
    if (!updates() || m_state == nullptr)
    {
        return;
    }

#ifdef WITH_RIVE_TOOLS
    if (!hasValidVM())
    {
        return;
    }
#endif
    // Stack: []
    rive_lua_pushRef(m_state, m_self);
    // Stack: [self]
    lua_getfield(m_state, -1, "update");
    // Stack: [self, field] Swap self and field
    lua_insert(m_state, -2);
    // Stack: [field, self]
    if (static_cast<lua_Status>(rive_lua_pcall(m_state, 1, 0)) != LUA_OK)
    {
        rive_lua_pop(m_state, 1);
    }
}

bool ScriptedObject::scriptInit(lua_State* state)
{
    // Clean up old references if reinitializing
    if (m_state != nullptr && (m_self != 0 || m_context != 0))
    {
        if (m_self != 0)
        {
            lua_unref(m_state, m_self);
            m_self = 0;
        }
        if (m_context != 0)
        {
            lua_unref(m_state, m_context);
            m_context = 0;
        }
    }
    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
    {
        // Stack: [self]
        lua_newrive<ScriptedContext>(state, this);
        // Stack: [self, ScriptedContext]
        m_context = lua_ref(state, -1);
        rive_lua_pop(state, 1);
        // Stack: [self]
        m_self = lua_ref(state, -1);
        m_state = state;
        for (auto prop : m_customProperties)
        {
            auto scriptInput = ScriptInput::from(prop);
            if (scriptInput)
            {
                scriptInput->initScriptedValue();
            }
        }
        if (inits())
        {
            // Stack: [self]
            lua_getfield(state, -1, "init");
            // Stack: [self, field]
            lua_pushvalue(state, -2);
            // Stack: [self, field, self]
            rive_lua_pushRef(state, m_context);
            // Stack: [self, field, self, ScriptedContext]
            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);
                // Stack: [self, status]
                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
                // Stack: [self, result]
                rive_lua_pop(state, 2);
                m_state = nullptr;
                m_self = 0;
                m_context = 0;
                return false;
            }
            else
            {
                // Stack: [self, result]
                rive_lua_pop(state, 1);
                assert(static_cast<lua_Type>(lua_type(state, -1)) ==
                       LUA_TTABLE);
                // Stack: [self]
                rive_lua_pop(state, 1);
            }
        }
        else
        {
            // Init function doesn't exist, just pop the self table
            // Stack: [self]
            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, m_self);
        lua_unref(m_state, m_context);
#ifdef TESTING
        // Force GC to collect any ScriptedArtboard instances created via
        // instance()
        lua_gc(m_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() {}

void ScriptedObject::cloneProperties(CustomPropertyContainer* twin,
                                     DataBindContainer* dataBindContainer) const
{

    for (auto prop : m_customProperties)
    {
        auto clonedValue = prop->clone()->as<CustomProperty>();
        twin->addProperty(clonedValue);
        auto input = ScriptInput::from(prop);
        if (input != nullptr)
        {
            auto dataBind = input->dataBind();
            if (dataBind)
            {
                auto dataBindClone = static_cast<DataBind*>(dataBind->clone());
                dataBindClone->file(dataBind->file());
                if (dataBind->converter() != nullptr)
                {
                    dataBindClone->converter(
                        dataBind->converter()->clone()->as<DataConverter>());
                }
                dataBindClone->target(clonedValue);
                dataBindContainer->addDataBind(dataBindClone);
            }
        }
    }
}