describe("Commands", function()
  local h, checkmate
  local bufnr, temp_file

  lazy_setup(function()
    stub(vim.api, "nvim_echo")
    vim.wait(10)
  end)

  lazy_teardown(function()
    ---@diagnostic disable-next-line: undefined-field
    vim.api.nvim_echo:revert()
  end)

  before_each(function()
    _G.reset_state()

    h = require("tests.checkmate.helpers")
    checkmate = require("checkmate")
    ---@diagnostic disable-next-line: missing-fields
    checkmate.setup()
    bufnr, temp_file = h.setup_todo_file_buffer("")
  end)

  after_each(function()
    checkmate.stop()
    h.cleanup_buffer(bufnr, temp_file)
  end)

  it("toggle calls toggle()", function()
    local s = spy.on(checkmate, "toggle")
    vim.cmd("Checkmate toggle")
    assert.spy(s).was.called(1)
    assert.spy(s).was.called_with(nil)
    s:clear()
    vim.cmd("Checkmate toggle checked")
    assert.spy(s).was.called(1)
    assert.spy(s).was.called_with("checked")
    s:revert()
  end)

  it("create calls create()", function()
    local s = spy.on(checkmate, "create")
    vim.cmd("Checkmate create")
    assert.spy(s).was.called(1)
    s:revert()
  end)

  it("uncheck calls uncheck()", function()
    local s = spy.on(checkmate, "uncheck")
    vim.cmd("Checkmate uncheck")
    assert.spy(s).was.called(1)
    s:revert()
  end)

  it("lint calls lint()", function()
    local s = spy.on(checkmate, "lint")
    vim.cmd("Checkmate lint")
    assert.spy(s).was.called(1)
    s:revert()
  end)

  it("archive calls archive()", function()
    local s = spy.on(checkmate, "archive")
    vim.cmd("Checkmate archive")
    assert.spy(s).was.called(1)
    s:revert()
  end)

  it("remove_all_metadata calls remove_all_metadata()", function()
    local s = spy.on(checkmate, "remove_all_metadata")
    vim.cmd("Checkmate remove_all_metadata")
    assert.spy(s).was.called(1)
    s:revert()
  end)

  describe("metadata subcommands", function()
    it("metadata add calls add_metadata()", function()
      local s = spy.on(checkmate, "add_metadata")
      vim.cmd("Checkmate metadata add foo")
      assert.spy(s).was.called(1)
      assert.spy(s).was.called_with("foo", nil)
      s:clear()
      vim.cmd("Checkmate metadata add foo bar")
      assert.spy(s).was.called(1)
      assert.spy(s).was.called_with("foo", "bar")
      s:revert()
    end)

    it("metadata remove calls remove_metadata()", function()
      local s = spy.on(checkmate, "remove_metadata")
      vim.cmd("Checkmate metadata remove baz")
      assert.spy(s).was.called(1)
      assert.spy(s).was.called_with("baz")
      s:revert()
    end)

    it("metadata toggle calls toggle_metadata()", function()
      local s = spy.on(checkmate, "toggle_metadata")
      vim.cmd("Checkmate metadata toggle done")
      assert.spy(s).was.called(1)
      assert.spy(s).was.called_with("done", nil)
      s:clear()
      vim.cmd("Checkmate metadata toggle priority high")
      assert.spy(s).was.called(1)
      assert.spy(s).was.called_with("priority", "high")
      s:revert()
    end)
  end)
end)
