-- Lado servidor de OverInteractive.
--
-- En partidas hosteadas el cliente del streamer es el único que habla con la app
-- (el canal de archivos vive en su perfil), pero no tiene autoridad sobre el mundo
-- ni sobre los demás jugadores. Así que releva cada comando por sendClientCommand
-- y acá se ejecuta de verdad: se resuelven los objetivos según el modo elegido en
-- la app y se corre la misma acción de shared/OverInteractiveActions.lua.
--
-- En single player este archivo no interviene: el cliente ejecuta directo.

OverInteractive = OverInteractive or {}

local function isAlive(player)
    if not player then return false end
    local bd = player:getBodyDamage()
    return bd == nil or bd:getOverallBodyHealth() > 0
end

local function OnClientCommand(module, command, player, args)
    if module ~= "OverInteractive" or command ~= "invoke" then return end
    if not args or not args.code then return end

    local action = OverInteractive.Actions and OverInteractive.Actions[args.code]
    if not action then
        print("[OverInteractive] comando desconocido: " .. tostring(args.code))
        return
    end

    -- Reconstruir los parámetros posicionales (llegan aplanados como p1..pN).
    local params = {}
    for i = 1, tonumber(args.n) or 0 do
        params[i] = args["p" .. i]
    end

    local viewer  = args.viewer or "El Chat"
    local targets = OverInteractive.ResolveTargets(args.target or "all", player)

    local here = OverInteractive.ServerCodes and OverInteractive.ServerCodes[args.code]

    for _, target in ipairs(targets) do
        if isAlive(target) then
            -- Un objetivo que falla no debe cortar al resto.
            local ok, msg = pcall(function()
                if here then
                    -- Mundo y stats: autoridad del servidor. En el caso del mundo
                    -- el jugador solo sirve para ubicar el efecto.
                    action(target, params, viewer)
                else
                    -- Inventario y body damage: los aplica el cliente del afectado
                    -- sobre su propio getPlayer(); desde acá se perderían.
                    local out = { code = args.code, viewer = viewer, n = #params }
                    for i = 1, #params do out["p" .. i] = params[i] end
                    sendServerCommand(target, "OverInteractive", "apply", out)
                end
            end)
            if not ok then
                print("[OverInteractive] " .. tostring(args.code) .. " fallo: " .. tostring(msg))
            end
        end
    end
end

Events.OnClientCommand.Add(OnClientCommand)
