-- Launcher modal focus routing. The immediate-mode focus ring is shared by
-- the main launcher and its mod dialogs, so arrows and an armed confirmation
-- must be handled before the modal key guard returns.
--   luajit tests/engine/launcher_modal_focus_input_test.lua

package.path = "./?.lua;./?/init.lua;" .. package.path

local T = require("tests.harness")
local check, eq = T.check, T.eq
love = love or require("tests.love_stub")

local Kit = require("src.ui.kit.Kit")
local RomImporter = require("src.import.RomImporter")

local function resetFocus()
  Kit.focusId = "modal-primary"
  Kit._navQueue = nil
  Kit._activateId = nil
end

local function importer(field)
  return setmetatable({ _flex = true, [field] = {} }, RomImporter)
end

local modalFields = {
  "_modConfirm", "_modVersions", "_modReleaseNotes", "_appPatchNotes", "_findDetails",
}

for _, field in ipairs(modalFields) do
  resetFocus()
  local imp = importer(field)
  imp:keypressed("right")
  eq(Kit._navQueue, "right", field .. " accepts focus navigation")
  check(imp._ringArmed, field .. " navigation arms the focus ring")

  imp:keypressed("return")
  eq(Kit._activateId, "modal-primary",
    field .. " activates the focused modal control")
  check(imp[field] ~= nil, field .. " remains open until its button dispatches")
end

-- Enter without prior focus navigation must not invent an activation. This is
-- the vanilla compatibility contract behind the launcher's legacy Enter-to-
-- play shortcut; a modal simply absorbs that otherwise-unhandled key.
do
  resetFocus()
  local imp = importer("_modConfirm")
  imp:keypressed("return")
  eq(Kit._activateId, nil, "unarmed modal Enter does not activate focus")
  check(not imp._ringArmed, "unarmed modal Enter does not arm focus")
end

-- A focused text field remains exclusive. The modal fix must not move the
-- ring when an arrow is intended for a launcher text-input state.
do
  resetFocus()
  local imp = setmetatable({
    _flex = true,
    _findSearchFocus = true,
    findQuery = "PIKA",
  }, RomImporter)
  imp:keypressed("right")
  eq(Kit._navQueue, nil, "focused search field does not navigate the ring")
  check(not imp._ringArmed, "focused search field does not arm the ring")
end

-- Escape remains owned by the existing modal close path.
do
  resetFocus()
  local imp = importer("_findDetails")
  imp:keypressed("escape")
  eq(imp._findDetails, nil, "Escape closes details")
end
do
  resetFocus()
  local imp = importer("_modReleaseNotes")
  imp:keypressed("escape")
  eq(imp._modReleaseNotes, nil, "Escape closes release notes")
end
do
  resetFocus()
  local imp = importer("_appPatchNotes")
  imp:keypressed("escape")
  eq(imp._appPatchNotes, nil, "Escape closes patch notes")
end
do
  resetFocus()
  local imp = importer("_modVersions")
  imp._modConfirm = {}
  imp:keypressed("escape")
  eq(imp._modConfirm, nil, "Escape closes confirmation")
  eq(imp._modVersions, nil, "Escape clears versions behind confirmation")
end

resetFocus()
T.finish("launcher modal focus input")
