local h = require("tests.helpers")

local new_set = MiniTest.new_set

local child = MiniTest.new_child_neovim()
T = new_set({
  hooks = {
    pre_case = function()
      h.child_start(child)

      -- Load helpers and set up the environment in the child process
      child.lua([[
        h = require('tests.helpers')
        chat, tools = h.setup_chat_buffer()

        -- Reset test globals
        _G._test_func = nil
        _G._test_exit = nil
        _G._test_order = nil
        _G._test_output = nil
        _G._test_setup = nil

        ui_utils = require("codecompanion.utils.ui")
      ]])
    end,
    post_case = function()
      child.lua([[h.teardown_chat_buffer()]])
    end,
    post_once = child.stop,
  },
})

T["Tools"] = new_set()
T["Tools"]["user approval"] = new_set()

T["Tools"]["user approval"]["prompts a user when tool requires approval"] = function()
  child.lua([[
    ui_utils.confirm = function(prompt, choices, opts)
      _G.ui_called = true
      _G.ui_prompt = prompt
      _G.ui_choices = choices
      return 1 -- Simulate user selecting "Yes"
    end

    local tool_calls = {
      {
        ["function"] = {
          name = "func_approval",
          arguments = { data = "Test Data" },
        },
      },
    }
    tools:execute(chat, tool_calls)
  ]])

  -- Check that UI was called with expected values
  h.eq(true, child.lua_get([[_G.ui_called]]))
  h.eq("Run the func_approval tool?", child.lua_get([[_G.ui_prompt]]))
  h.eq({ "1 Approve", "2 Reject", "3 Cancel" }, child.lua_get([[_G.ui_choices]]))

  -- Check that tool executed after approval
  h.eq("Test Data", child.lua_get([[_G._test_func]]))
  h.eq("Setup->Success->Exit", child.lua_get([[_G._test_order]]))
end

T["Tools"]["user approval"]["approval can be conditionally set - true in this case"] = function()
  child.lua([[
    -- Mock vim.ui.select to capture what gets called
    local original_select = vim.ui.select
    _G.ui_called = false

    ui_utils.confirm = function(prompt, choices, opts)
      _G.ui_called = true
      return 1 -- Simulate user selecting "Yes"
    end

    local tool_calls = {
      {
        ["function"] = {
          name = "func_approval2",
          arguments = { data = "Approve" },
        },
      },
    }
    tools:execute(chat, tool_calls)
  ]])

  -- Check that UI was called with expected values
  h.eq(true, child.lua_get([[_G.ui_called]]))
  h.eq("Setup->Success->Exit", child.lua_get([[_G._test_order]]))
end

T["Tools"]["user approval"]["approval can be conditionally set - false in this case"] = function()
  child.lua([[
    -- Mock vim.ui.select to capture what gets called
    local original_select = vim.ui.select
    _G.ui_called = false

    ui_utils.confirm = function(prompt, choices, opts)
      _G.ui_called = true
      return 1 -- Simulate user selecting "Yes"
    end

    local tool_calls = {
      {
        ["function"] = {
          name = "func_approval2",
          arguments = { data = "Reject" },
        },
      },
    }
    tools:execute(chat, tool_calls)
  ]])

  h.eq(false, child.lua_get([[_G.ui_called]]))
end

T["Tools"]["user approval"]["approval can be rejected"] = function()
  child.lua([[
    -- Mock vim.ui.select to capture what gets called
    local original_select = vim.ui.select
    _G.ui_called = true

    ui_utils.confirm = function(prompt, choices, opts)
      _G.ui_called = true
      return 2 -- Simulate user selecting "Yes"
    end
    local tool_calls = {
      {
        ["function"] = {
          name = "func_approval",
          arguments = { data = "Test Data" },
        },
      },
    }
    tools:execute(chat, tool_calls)
  ]])

  h.eq(true, child.lua_get([[_G.ui_called]]))
  h.eq("Setup->Rejected", child.lua_get([[_G._test_order]]))
end

return T
