-- Require core UI modules with consistent syntax
local ISContextMenu            = require("ISUI/ISContextMenu")
local ISToolTip                = require("ISUI/ISToolTip")
local ISWorldObjectContextMenu = require("ISUI/ISWorldObjectContextMenu")

local ContextMenu = {}

local CONTEXT_MENU_MODULES = {
  "ZLMasturbation",
  "ZLDebugMenu",
  "ZLAskForSex",
  "ZLHandleZombie",   
  "ZLRapeZombie"     
}

function ContextMenu._createContextMenu(playerIndex, context, worldObjects, isTest)
  local modOptions = PZAPI.ModOptions:getOptions("ZomboLewdFramework")

  -- Testing branch: short-circuit if in test mode
  if isTest then
    if ISWorldObjectContextMenu.Test then
      return true
    end
    return ISWorldObjectContextMenu.setTest()
  end

  local character = getSpecificPlayer(playerIndex)
  -- Abort if player is asleep or in a vehicle
  if character:isAsleep() or character:getVehicle() then
    return
  end

  -- Lazy-load context menu modules once
  if not ContextMenu.Modules then
    ContextMenu.Modules = {}
    for _, moduleName in ipairs(CONTEXT_MENU_MODULES) do
      local modulePath = "ZomboLewd/ZLContextMenu/" .. moduleName
      table.insert(ContextMenu.Modules, require(modulePath))
    end
  end

  -- Identify the first valid square from worldObjects
  local square
  for _, obj in ipairs(worldObjects) do
    square = obj:getSquare()
    if square then break end
  end
  if not square then return end

  local clickedPlayer = square:getPlayer()
  local clickedZombie = square:getZombie()

  -- Dispatch to the appropriate module based on context
  if clickedZombie then
    if clickedZombie:getVariableBoolean("isSubdued") then
      ContextMenu.Modules[5](ContextMenu, character, clickedZombie, context, worldObjects)
    else
      ContextMenu.Modules[4](ContextMenu, character, clickedZombie, context, worldObjects)
    end

  elseif clickedPlayer then
    if clickedPlayer:isLocalPlayer() then
      ContextMenu.Modules[1](ContextMenu, character, context, worldObjects)
    else
      ContextMenu.Modules[3](ContextMenu, character, clickedPlayer, context, worldObjects)
    end

  elseif modOptions:getOption("box_debug"):getValue() then
    ContextMenu.Modules[2](ContextMenu, character, context, worldObjects)
  end
end

-- Register event handler
Events.OnPreFillWorldObjectContextMenu.Add(ContextMenu._createContextMenu)

return ContextMenu