#ifdef WITH_RIVE_SCRIPTING
#include "rive/lua/rive_lua_libs.hpp"
#endif
#include "rive/component_dirt.hpp"
#include "rive/assets/script_asset.hpp"
#include "rive/scripted/scripted_drawable.hpp"

using namespace rive;

#ifdef WITH_RIVE_SCRIPTING
bool ScriptedDrawable::scriptInit(LuaState* state)
{
    ScriptedObject::scriptInit(state);
    addDirt(ComponentDirt::Paint);
    return true;
}

void ScriptedDrawable::draw(Renderer* renderer)
{
    if (m_state == nullptr || !draws())
    {
        return;
    }
    auto state = m_state->state;
    renderer->save();
    renderer->transform(worldTransform());

    rive_lua_pushRef(state, m_self);
    if (static_cast<lua_Type>(lua_getfield(state, -1, "draw")) != LUA_TFUNCTION)
    {
        fprintf(stderr, "expected draw to be a function\n");
    }
    else
    {
        lua_pushvalue(state, -2);
        auto scriptedRenderer = lua_newrive<ScriptedRenderer>(state, renderer);
        if (static_cast<lua_Status>(rive_lua_pcall(state, 2, 0)) != LUA_OK)
        {
            rive_lua_pop(state, 1);
        }
        scriptedRenderer->end();
    }
    rive_lua_pop(state, 1);
    renderer->restore();
}

std::vector<HitComponent*> ScriptedDrawable::hitComponents(
    StateMachineInstance* sm)
{
    if (!listensToPointerEvents())
    {
        return {};
    }
    auto* hitComponent = new HitScriptedDrawable(this, sm);
    return std::vector<HitComponent*>{hitComponent};
}

HitResult HitScriptedDrawable::processEvent(Vec2D position,
                                            ListenerType hitType,
                                            bool canHit,
                                            float timeStamp,
                                            int pointerId)
{
    HitResult hitResult = HitResult::none;
    auto scriptAsset = m_drawable->scriptAsset();
    auto vm = scriptAsset->vm();
    if (vm == nullptr || scriptAsset == nullptr ||
        !handlesEvent(canHit, hitType))
    {
        return HitResult::none;
    }
    Vec2D localPos;
    auto hasLocalPos = m_drawable->worldToLocal(position, &localPos);
    if (!hasLocalPos)
    {
        return hitResult;
    }
    auto state = vm->state;
    rive_lua_pushRef(state, m_drawable->self());
    auto mName = methodName(canHit, hitType);
    if (static_cast<lua_Type>(lua_getfield(state, -1, mName.c_str())) !=
        LUA_TFUNCTION)
    {
        fprintf(stderr, "expected %s to be a function\n", mName.c_str());
        rive_lua_pop(state, 1);
    }
    else
    {
        lua_pushvalue(state, -2);
        auto pointerEvent =
            lua_newrive<ScriptedPointerEvent>(state, pointerId, localPos);
        if (static_cast<lua_Status>(rive_lua_pcall(state, 2, 0)) != LUA_OK)
        {
            fprintf(stderr, "%s failed\n", mName.c_str());
            rive_lua_pop(state, 1);
        }
        hitResult = pointerEvent->m_hitResult;
    }
    rive_lua_pop(state, 1);
    return hitResult;
}
#else
void ScriptedDrawable::draw(Renderer* renderer) {}

std::vector<HitComponent*> ScriptedDrawable::hitComponents(
    StateMachineInstance* sm)
{
    return {};
}

HitResult HitScriptedDrawable::processEvent(Vec2D position,
                                            ListenerType hitType,
                                            bool canHit,
                                            float timeStamp,
                                            int pointerId)
{
    return HitResult::none;
}
#endif

void ScriptedDrawable::update(ComponentDirt value)
{
    Super::update(value);
    if ((value & ComponentDirt::ScriptUpdate) == ComponentDirt::ScriptUpdate)
    {
        scriptUpdate();
    }
}

Core* ScriptedDrawable::hitTest(HitInfo*, const Mat2D&) { return nullptr; }

StatusCode ScriptedDrawable::onAddedDirty(CoreContext* context)
{
    auto code = Super::onAddedDirty(context);
    if (code != StatusCode::Ok)
    {
        return code;
    }
    artboard()->addScriptedObject(this);
    return StatusCode::Ok;
}

bool ScriptedDrawable::advanceComponent(float elapsedSeconds,
                                        AdvanceFlags flags)
{
    if (elapsedSeconds == 0)
    {
        return false;
    }
    if ((flags & AdvanceFlags::AdvanceNested) == 0)
    {
        elapsedSeconds = 0;
    }
    return scriptAdvance(elapsedSeconds);
}

bool ScriptedDrawable::addScriptedDirt(ComponentDirt value, bool recurse)
{
    return Drawable::addDirt(value, recurse);
}

StatusCode ScriptedDrawable::import(ImportStack& importStack)
{
    auto result = registerReferencer(importStack);
    if (result != StatusCode::Ok)
    {
        return result;
    }
    return Super::import(importStack);
}

Core* ScriptedDrawable::clone() const
{
    ScriptedDrawable* twin =
        ScriptedDrawableBase::clone()->as<ScriptedDrawable>();
    if (m_fileAsset != nullptr)
    {
        twin->setAsset(m_fileAsset);
    }
    for (auto prop : m_customProperties)
    {
        auto clonedValue = prop->clone()->as<CustomProperty>();
        twin->addProperty(clonedValue);
        auto scriptInput = ScriptInput::from(clonedValue);
        if (scriptInput != nullptr)
        {
            scriptInput->scriptedObject(twin);
        }
    }
    return twin;
}

void ScriptedDrawable::markNeedsUpdate()
{
    addScriptedDirt(ComponentDirt::ScriptUpdate);
}

bool ScriptedDrawable::worldToLocal(Vec2D world, Vec2D* local)
{
    Mat2D toMountedArtboard;
    if (!worldTransform().invert(&toMountedArtboard))
    {
        return false;
    }

    *local = toMountedArtboard * world;

    return true;
}

bool HitScriptedDrawable::handlesEvent(bool canHit, ListenerType hitEvent)
{
    if (canHit)
    {
        switch (hitEvent)
        {
            case ListenerType::down:
                return m_drawable->wantsPointerDown();
            case ListenerType::up:
                return m_drawable->wantsPointerUp();
            case ListenerType::dragStart:
                return false;
            case ListenerType::dragEnd:
                return false;
            default:
                return m_drawable->wantsPointerMove();
        }
    }
    return m_drawable->wantsPointerExit();
}

std::string HitScriptedDrawable::methodName(bool canHit, ListenerType hitEvent)
{
    if (canHit)
    {
        switch (hitEvent)
        {
            case ListenerType::down:
                return "pointerDown";
            case ListenerType::up:
                return "pointerUp";
            case ListenerType::dragStart:
            case ListenerType::dragEnd:
                return "";
            default:
                return "pointerMove";
        }
    }
    return "pointerExit";
}