-- InspectInput/Inspect_ControllerUtils.lua
-- Helper utilities for joypad input.

InspectControllerUtils = InspectControllerUtils or {}

local function getJoypadDataSafe(playerNum)
    if getJoypadData then
        return getJoypadData(playerNum)
    end
    if JoypadState and JoypadState.players then
        return JoypadState.players[(playerNum or 0) + 1]
    end
    return nil
end

function InspectControllerUtils.getJoypadData(playerNum)
    return getJoypadDataSafe(playerNum or 0)
end

function InspectControllerUtils.getJoypadId(playerNum)
    local data = getJoypadDataSafe(playerNum or 0)
    if not data then return -1 end
    if data.id ~= nil then
        return data.id
    end
    return -1
end

function InspectControllerUtils.isJoypadActive(playerNum)
    local data = getJoypadDataSafe(playerNum or 0)
    if not data then return false end
    if data.id == nil or data.id < 0 then return false end
    if data.isConnected and type(data.isConnected) == "function" then
        return data:isConnected()
    end
    if data.controller and data.controller.connected ~= nil then
        return data.controller.connected
    end
    if isJoypadConnected then
        return isJoypadConnected(data.id)
    end
    return true
end

function InspectControllerUtils.wasMouseRecentlyActive()
    if wasMouseActiveMoreRecentlyThanJoypad then
        return wasMouseActiveMoreRecentlyThanJoypad()
    end
    return false
end

local function applyDeadzone(value, deadzone)
    value = value or 0
    if math.abs(value) < (deadzone or 0) then
        return 0
    end
    return value
end

function InspectControllerUtils.getAxis(joypadId, axisName, deadzone)
    if not axisName then return 0 end
    local value = 0
    if axisName == "LeftStickX" and getJoypadMovementAxisX then
        value = getJoypadMovementAxisX(joypadId)
    elseif axisName == "LeftStickY" and getJoypadMovementAxisY then
        value = getJoypadMovementAxisY(joypadId)
    elseif axisName == "RightStickX" and getJoypadAimingAxisX then
        value = getJoypadAimingAxisX(joypadId)
    elseif axisName == "RightStickY" and getJoypadAimingAxisY then
        value = getJoypadAimingAxisY(joypadId)
    end
    return applyDeadzone(value or 0, deadzone or 0.2)
end

local function getButtonIndex(joypadId, name)
    if name == "A" then
        return (getJoypadAButton and getJoypadAButton(joypadId)) or Joypad.AButton
    elseif name == "B" then
        return (getJoypadBButton and getJoypadBButton(joypadId)) or Joypad.BButton
    elseif name == "X" then
        return (getJoypadXButton and getJoypadXButton(joypadId)) or Joypad.XButton
    elseif name == "Y" then
        return (getJoypadYButton and getJoypadYButton(joypadId)) or Joypad.YButton
    elseif name == "LB" then
        return (getJoypadLBumper and getJoypadLBumper(joypadId)) or Joypad.LBumper
    elseif name == "RB" then
        return (getJoypadRBumper and getJoypadRBumper(joypadId)) or Joypad.RBumper
    elseif name == "Back" then
        return (getJoypadBackButton and getJoypadBackButton(joypadId)) or Joypad.Back
    elseif name == "Start" then
        return (getJoypadStartButton and getJoypadStartButton(joypadId)) or Joypad.Start
    elseif name == "L3" then
        return (getJoypadLeftStickButton and getJoypadLeftStickButton(joypadId)) or Joypad.LStickButton
    elseif name == "R3" then
        return (getJoypadRightStickButton and getJoypadRightStickButton(joypadId)) or Joypad.RStickButton
    end
    return nil
end

function InspectControllerUtils.isPressed(joypadId, name)
    if not name or not joypadId or joypadId < 0 then return false end
    if name == "DPadUp" then
        return isJoypadUp and isJoypadUp(joypadId) or false
    elseif name == "DPadDown" then
        return isJoypadDown and isJoypadDown(joypadId) or false
    elseif name == "DPadLeft" then
        return isJoypadLeft and isJoypadLeft(joypadId) or false
    elseif name == "DPadRight" then
        return isJoypadRight and isJoypadRight(joypadId) or false
    elseif name == "LT" then
        return isJoypadLTPressed and isJoypadLTPressed(joypadId) or false
    elseif name == "RT" then
        return isJoypadRTPressed and isJoypadRTPressed(joypadId) or false
    elseif name == "L3" then
        return isJoypadLeftStickButtonPressed and isJoypadLeftStickButtonPressed(joypadId) or false
    elseif name == "R3" then
        return isJoypadRightStickButtonPressed and isJoypadRightStickButtonPressed(joypadId) or false
    end

    local idx = getButtonIndex(joypadId, name)
    if idx == nil then return false end
    if isJoypadPressed then
        return isJoypadPressed(joypadId, idx) or false
    end
    return false
end

function InspectControllerUtils.getTimeMs()
    if getTimeInMillis then
        return getTimeInMillis()
    end
    return os.time() * 1000
end

function InspectControllerUtils.getRenderDelta()
    if UIManager and UIManager.getMillisSinceLastRender then
        return UIManager.getMillisSinceLastRender()
    end
    return 33.3
end

return InspectControllerUtils
