#ifdef WITH_RIVE_SCRIPTING
#include "rive/math/vec2d.hpp"
#include "rive/lua/rive_lua_libs.hpp"
#include "rive/math/raw_path.hpp"
#include "rive/math/contour_measure.hpp"
#include "rive/math/path_measure.hpp"
#include "rive/factory.hpp"

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

using namespace rive;

RenderPath* ScriptedPathData::renderPath(lua_State* L)
{
    if (m_isRenderPathDirty)
    {
        m_isRenderPathDirty = false;
        const bool sameFrameRebuild =
            m_renderPath && m_renderFrameId == Artboard::frameId();
        m_renderFrameId = Artboard::frameId();

        ScriptingContext* context =
            static_cast<ScriptingContext*>(lua_getthreaddata(L));
        if (!m_renderPath || sameFrameRebuild)
        {
            m_renderPath = context->factory()->makeEmptyRenderPath();
            m_renderPath->fillRule(FillRule::clockwise);
        }
        else
        {
            m_renderPath->rewind();
        }
        m_renderPath->addRawPath(rawPath);
    }

    return m_renderPath.get();
}

ScriptedPathData::ScriptedPathData(const RawPath* path)
{
    rawPath.addPath(*path);
}

int ScriptedPathData::totalCommands() { return (int)rawPath.verbs().size(); }

static ScriptedPath* lua_pushpath(lua_State* L)
{
    return lua_newrive<ScriptedPath>(L);
}

static int path_new(lua_State* L)
{
    lua_pushpath(L);
    return 1;
}

static int path_moveTo(lua_State* L)
{
    auto scriptedPath = lua_torive<ScriptedPath>(L, 1);
    auto vec = lua_checkvec2d(L, 2);
    scriptedPath->rawPath.move(*vec);
    scriptedPath->markDirty();
    return 0;
}

static int path_lineTo(lua_State* L)
{
    auto scriptedPath = lua_torive<ScriptedPath>(L, 1);
    auto vec = lua_checkvec2d(L, 2);
    scriptedPath->rawPath.line(*vec);
    scriptedPath->markDirty();
    return 0;
}

static int path_quadTo(lua_State* L)
{
    auto scriptedPath = lua_torive<ScriptedPath>(L, 1);
    auto p1 = lua_checkvec2d(L, 2);
    auto p2 = lua_checkvec2d(L, 3);
    scriptedPath->rawPath.quad(*p1, *p2);
    scriptedPath->markDirty();
    return 0;
}

static int path_cubicTo(lua_State* L)
{
    auto scriptedPath = lua_torive<ScriptedPath>(L, 1);
    auto p1 = lua_checkvec2d(L, 2);
    auto p2 = lua_checkvec2d(L, 3);
    auto p3 = lua_checkvec2d(L, 4);
    scriptedPath->rawPath.cubic(*p1, *p2, *p3);
    scriptedPath->markDirty();
    return 0;
}

static int path_close(lua_State* L)
{
    auto scriptedPath = lua_torive<ScriptedPath>(L, 1);
    scriptedPath->rawPath.close();
    scriptedPath->markDirty();
    return 0;
}

static int path_reset(lua_State* L)
{
    auto scriptedPath = lua_torive<ScriptedPath>(L, 1);
    scriptedPath->rawPath.reset();
    scriptedPath->markDirty();
    return 0;
}

static int path_add(lua_State* L)
{
    auto scriptedPath = (ScriptedPathData*)lua_touserdata(L, 1);
    auto scriptedPathToAdd = (ScriptedPathData*)lua_touserdata(L, 2);
    const Mat2D* transform = nullptr;
    int nargs = lua_gettop(L);
    if (nargs == 3)
    {
        auto matrix = lua_torive<ScriptedMat2D>(L, 3);
        transform = &matrix->value;
    }
    scriptedPath->rawPath.addPath(scriptedPathToAdd->rawPath, transform);
    scriptedPath->markDirty();
    return 0;
}

static int path_command(lua_State* L)
{
    auto scriptedPath = (ScriptedPathData*)lua_touserdata(L, 1);
    auto rawPath = scriptedPath->rawPath;
    auto verbs = rawPath.verbs();
    auto points = rawPath.points();
    auto verbIndex = int(luaL_checknumber(L, 2));
    auto verbName = "none";
    std::vector<Vec2D> verbPoints;

    if (verbIndex >= 0 && verbIndex < (int)verbs.size())
    {
        auto verb = verbs[verbIndex];

        // Calculate the point index for this verb by summing point counts of
        // previous verbs
        int pointIndex = 0;
        for (int i = 0; i < verbIndex; i++)
        {
            pointIndex += path_verb_to_point_count(verbs[i]);
        }

        switch (verb)
        {
            case PathVerb::move:
                verbName = "moveTo";
                if (pointIndex < (int)points.size())
                {
                    verbPoints.push_back(points[pointIndex]);
                }
                break;
            case PathVerb::line:
                verbName = "lineTo";
                if (pointIndex < (int)points.size())
                {
                    verbPoints.push_back(points[pointIndex]);
                }
                break;
            case PathVerb::quad:
                verbName = "quadTo";
                if (pointIndex + 1 < (int)points.size())
                {
                    verbPoints.push_back(points[pointIndex]);
                    verbPoints.push_back(points[pointIndex + 1]);
                }
                break;
            case PathVerb::cubic:
                verbName = "cubicTo";
                if (pointIndex + 2 < (int)points.size())
                {
                    verbPoints.push_back(points[pointIndex]);
                    verbPoints.push_back(points[pointIndex + 1]);
                    verbPoints.push_back(points[pointIndex + 2]);
                }
                break;
            case PathVerb::close:
                verbName = "close";
                // close has no points
                break;
        }
    }
    lua_newrive<ScriptedPathCommand>(L, verbName, verbPoints);
    return 1;
}

static int path_contours(lua_State* L)
{
    auto scriptedPath = (ScriptedPathData*)lua_touserdata(L, 1);
    // Use the copy constructor to ensure ContourMeasure outlives the path
    auto iter = make_rcp<RefCntContourMeasureIter>(scriptedPath->rawPath);
    auto firstContour = iter->get()->next();
    if (firstContour)
    {
        lua_newrive<ScriptedContourMeasure>(L, firstContour, iter);
        return 1;
    }
    lua_pushnil(L);
    return 1;
}

static int path_measure(lua_State* L)
{
    auto scriptedPath = (ScriptedPathData*)lua_touserdata(L, 1);
    PathMeasure pathMeasure(&scriptedPath->rawPath);
    lua_newrive<ScriptedPathMeasure>(L, std::move(pathMeasure));
    return 1;
}

static int path_namecall(lua_State* L)
{
    int atom;
    const char* str = lua_namecallatom(L, &atom);
    if (str != nullptr)
    {
        switch (atom)
        {
            case (int)LuaAtoms::moveTo:
                return path_moveTo(L);
            case (int)LuaAtoms::lineTo:
                return path_lineTo(L);
            case (int)LuaAtoms::quadTo:
                return path_quadTo(L);
            case (int)LuaAtoms::cubicTo:
                return path_cubicTo(L);
            case (int)LuaAtoms::close:
                return path_close(L);
            case (int)LuaAtoms::reset:
                return path_reset(L);
            case (int)LuaAtoms::add:
                return path_add(L);
            case (int)LuaAtoms::contours:
                return path_contours(L);
            case (int)LuaAtoms::measure:
                return path_measure(L);
        }
    }

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

static void contour_measure_direct_length(void* udata, void* result)
{
    lua_userdatadirectfield_setnumber(
        result,
        ((ScriptedContourMeasure*)udata)->measure()->length());
}

static void contour_measure_direct_isClosed(void* udata, void* result)
{
    lua_userdatadirectfield_setboolean(
        result,
        ((ScriptedContourMeasure*)udata)->measure()->isClosed() ? 1 : 0);
}

static void path_measure_direct_length(void* udata, void* result)
{
    lua_userdatadirectfield_setnumber(
        result,
        ((ScriptedPathMeasure*)udata)->measure()->length());
}

static void path_measure_direct_isClosed(void* udata, void* result)
{
    lua_userdatadirectfield_setboolean(
        result,
        ((ScriptedPathMeasure*)udata)->measure()->isClosed() ? 1 : 0);
}

// ContourMeasure methods
static int contour_measure_length(lua_State* L)
{
    auto scripted = lua_torive<ScriptedContourMeasure>(L, 1);
    lua_pushnumber(L, scripted->measure()->length());
    return 1;
}

static int contour_measure_isClosed(lua_State* L)
{
    auto scripted = lua_torive<ScriptedContourMeasure>(L, 1);
    lua_pushboolean(L, scripted->measure()->isClosed());
    return 1;
}

static int contour_measure_positionAndTangent(lua_State* L)
{
    auto scripted = lua_torive<ScriptedContourMeasure>(L, 1);
    float distance = (float)luaL_checknumber(L, 2);
    auto posTan = scripted->measure()->getPosTan(distance);
    lua_pushvec2d(L, posTan.pos);
    lua_pushvec2d(L, posTan.tan);
    return 2;
}

static int contour_measure_warp(lua_State* L)
{
    auto scripted = lua_torive<ScriptedContourMeasure>(L, 1);
    auto src = lua_checkvec2d(L, 2);
    Vec2D result = scripted->measure()->warp(*src);
    lua_pushvec2d(L, result);
    return 1;
}

static int contour_measure_extract(lua_State* L)
{
    auto scripted = lua_torive<ScriptedContourMeasure>(L, 1);
    float startDistance = (float)luaL_checknumber(L, 2);
    float endDistance = (float)luaL_checknumber(L, 3);
    auto destPath = lua_torive<ScriptedPath>(L, 4);
    bool startWithMove = lua_isboolean(L, 5) ? lua_toboolean(L, 5) : true;
    scripted->measure()->getSegment(startDistance,
                                    endDistance,
                                    &destPath->rawPath,
                                    startWithMove);
    destPath->markDirty();
    return 0;
}

static int contour_measure_next(lua_State* L)
{
    auto scripted = lua_torive<ScriptedContourMeasure>(L, 1);
    auto iter = scripted->iter();
    if (iter)
    {
        auto nextContour = iter->get()->next();
        if (nextContour)
        {
            // Create new ScriptedContourMeasure with the same rcp iter
            // The iter is already advanced, so we can reuse it
            lua_newrive<ScriptedContourMeasure>(L, nextContour, iter);
            return 1;
        }
    }
    lua_pushnil(L);
    return 1;
}

static int path_index(lua_State* L)
{
    int atom;
    const char* key = lua_tostringatom(L, 2, &atom);

    // If it's not a string/atom, treat it as a numeric index
    if (!key)
    {
        int index = luaL_checkinteger(L, 2);
        // Convert from 1-based Lua index to 0-based C++ index
        // Replace the index at position 2 with the 0-based version
        lua_pushinteger(L, index - 1); // Push 0-based index
        lua_replace(L, 2);             // Replace the value at position 2
        // Now stack has: 1=path, 2=0-based index, which is what path_command
        // expects
        return path_command(L);
    }

    // String indices are handled by __namecall for methods
    return 0;
}

static int path_length(lua_State* L)
{
    auto scriptedPath = (ScriptedPathData*)lua_touserdata(L, 1);

    auto totalCommands = scriptedPath->totalCommands();
    lua_pushnumber(L, totalCommands);
    return 1;
}

static int contour_measure_index(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;
    }

    switch (atom)
    {
        case (int)LuaAtoms::length:
            return contour_measure_length(L);
        case (int)LuaAtoms::isClosed:
            return contour_measure_isClosed(L);
        case (int)LuaAtoms::next:
            return contour_measure_next(L);
        default:
            return 0;
    }
}

static int contour_measure_namecall(lua_State* L)
{
    int atom;
    const char* str = lua_namecallatom(L, &atom);
    if (str != nullptr)
    {
        switch (atom)
        {
            case (int)LuaAtoms::positionAndTangent:
                return contour_measure_positionAndTangent(L);
            case (int)LuaAtoms::warp:
                return contour_measure_warp(L);
            case (int)LuaAtoms::extract:
                return contour_measure_extract(L);
        }
    }

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

// PathMeasure methods
static int path_measure_length(lua_State* L)
{
    auto scripted = lua_torive<ScriptedPathMeasure>(L, 1);
    lua_pushnumber(L, scripted->measure()->length());
    return 1;
}

static int path_measure_isClosed(lua_State* L)
{
    auto scripted = lua_torive<ScriptedPathMeasure>(L, 1);
    lua_pushboolean(L, scripted->measure()->isClosed());
    return 1;
}

static int path_measure_positionAndTangent(lua_State* L)
{
    auto scripted = lua_torive<ScriptedPathMeasure>(L, 1);
    float distance = (float)luaL_checknumber(L, 2);
    auto posTanDist = scripted->measure()->atDistance(distance);
    lua_pushvec2d(L, posTanDist.pos);
    lua_pushvec2d(L, posTanDist.tan);
    return 2;
}

static int path_measure_warp(lua_State* L)
{
    auto scripted = lua_torive<ScriptedPathMeasure>(L, 1);
    auto src = lua_checkvec2d(L, 2);
    // Use atDistance to get position and tangent, then apply warp formula
    auto posTanDist = scripted->measure()->atDistance(src->x);
    Vec2D result = {
        posTanDist.pos.x - posTanDist.tan.y * src->y,
        posTanDist.pos.y + posTanDist.tan.x * src->y,
    };
    lua_pushvec2d(L, result);
    return 1;
}

static int path_measure_extract(lua_State* L)
{
    auto scripted = lua_torive<ScriptedPathMeasure>(L, 1);
    float startDistance = (float)luaL_checknumber(L, 2);
    float endDistance = (float)luaL_checknumber(L, 3);
    auto destPath = lua_torive<ScriptedPath>(L, 4);
    bool startWithMove = lua_isboolean(L, 5) ? lua_toboolean(L, 5) : true;
    scripted->measure()->getSegment(startDistance,
                                    endDistance,
                                    &destPath->rawPath,
                                    startWithMove);
    destPath->markDirty();
    return 0;
}

static int path_measure_index(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;
    }

    switch (atom)
    {
        case (int)LuaAtoms::length:
            return path_measure_length(L);
        case (int)LuaAtoms::isClosed:
            return path_measure_isClosed(L);
        default:
            return 0;
    }
}

static int path_measure_namecall(lua_State* L)
{
    int atom;
    const char* str = lua_namecallatom(L, &atom);
    if (str != nullptr)
    {
        switch (atom)
        {
            case (int)LuaAtoms::positionAndTangent:
                return path_measure_positionAndTangent(L);
            case (int)LuaAtoms::warp:
                return path_measure_warp(L);
            case (int)LuaAtoms::extract:
                return path_measure_extract(L);
        }
    }

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

static int property_namecall_atom(lua_State* L,
                                  ScriptedPathCommand* pathCommand,
                                  uint8_t tag,
                                  int atom,
                                  bool& error)
{
    switch (atom)
    {
        case (int)LuaAtoms::type:
        {
            lua_pushstring(L, pathCommand->type().c_str());
            return 1;
        }
    }
    error = true;
    return 0;
}

static int pathCommand_index(lua_State* L)
{
    int atom;
    const char* key = lua_tostringatom(L, 2, &atom);

    // If it's not a string/atom, treat it as a numeric index
    if (!key)
    {
        int luaIndex = luaL_checkinteger(L, 2);
        int index = luaIndex - 1;

        auto pathCommand = (ScriptedPathCommand*)lua_touserdata(L, 1);
        auto points = pathCommand->points();
        auto size = (int)points.size();
        if (index >= 0 && index < size)
        {
            auto point = points[index];
            lua_pushvec2d(L, point);
            return 1;
        }
    }
    else
    {
        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 pathCommand = (ScriptedPathCommand*)lua_touserdata(L, 1);

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

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

static int pathCommand_length(lua_State* L)
{
    auto pathCommand = (ScriptedPathCommand*)lua_touserdata(L, 1);

    auto points = pathCommand->points();
    lua_pushnumber(L, (int)points.size());
    return 1;
}

static int pathCommand_namecall(lua_State* L)
{
    int atom;
    const char* str = lua_namecallatom(L, &atom);

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

static const luaL_Reg pathStaticMethods[] = {
    {"new", path_new},
    {NULL, NULL},
};

int luaopen_rive_path(lua_State* L)
{
    {
        lua_register_rive<ScriptedPathData>(L);

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

        lua_pushcfunction(L, path_length, nullptr);
        lua_setfield(L, -2, "__len");

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

        lua_setreadonly(L, -1, true);
        lua_pop(L, 1); // pop the metatable
    }
    {
        luaL_register(L, ScriptedPath::luaName, pathStaticMethods);
        lua_register_rive<ScriptedPath>(L);

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

        lua_pushcfunction(L, path_length, nullptr);
        lua_setfield(L, -2, "__len");

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

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

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

        lua_pushcfunction(L, pathCommand_length, nullptr);
        lua_setfield(L, -2, "__len");

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

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

    // Register ContourMeasure
    lua_register_rive<ScriptedContourMeasure>(L);
    lua_pushcfunction(L, contour_measure_index, nullptr);
    lua_setfield(L, -2, "__index");
    lua_pushcfunction(L, contour_measure_namecall, nullptr);
    lua_setfield(L, -2, "__namecall");
    lua_setreadonly(L, -1, true);
    lua_pop(L, 1); // pop the metatable

    lua_registeruserdatadirectfieldget(L,
                                       ScriptedContourMeasure::luaTag,
                                       "length",
                                       contour_measure_direct_length);
    lua_registeruserdatadirectfieldget(L,
                                       ScriptedContourMeasure::luaTag,
                                       "isClosed",
                                       contour_measure_direct_isClosed);

    // Register PathMeasure
    lua_register_rive<ScriptedPathMeasure>(L);
    lua_pushcfunction(L, path_measure_index, nullptr);
    lua_setfield(L, -2, "__index");
    lua_pushcfunction(L, path_measure_namecall, nullptr);
    lua_setfield(L, -2, "__namecall");
    lua_setreadonly(L, -1, true);
    lua_pop(L, 1); // pop the metatable

    lua_registeruserdatadirectfieldget(L,
                                       ScriptedPathMeasure::luaTag,
                                       "length",
                                       path_measure_direct_length);
    lua_registeruserdatadirectfieldget(L,
                                       ScriptedPathMeasure::luaTag,
                                       "isClosed",
                                       path_measure_direct_isClosed);

    return 1;
}

#endif
