local map = vim.keymap.set

-- Disable arrow keys in normal, visual, and insert modes.
local keys = { "<Up>", "<Down>", "<Left>", "<Right>" }
for _, key in ipairs(keys) do
  map({ "n", "i", "v" }, key, "<Nop>", { noremap = true, silent = true })
end

-- Neotree
map("n", "<C-b>", "<cmd>Neotree toggle<CR>", { desc = "Open neotree"})

-- Telescope
map("n", "<C-p>", "<cmd>Telescope find_files<CR>", { desc = "Telescope: Find files" })
map("n", "<C-g>", "<cmd>Telescope live_grep<CR>", { desc = "Telescope: Live grep" })

vim.api.nvim_create_autocmd("LspAttach", {
  group = vim.api.nvim_create_augroup("UserLspConfig", {}),
  callback = function(ev)
    local opts = { buffer = ev.buf }
    local tele = require("telescope.builtin")

    -- LSP
    map("n", "gd", tele.lsp_definitions, vim.tbl_extend("force", opts, { desc = "Goto Definition" }))
    map("n", "<leader>fs", tele.lsp_document_symbols, vim.tbl_extend("force", opts, { desc = "Doc Symbols" }))
    map("n", "<leader>fS", tele.lsp_dynamic_workspace_symbols, vim.tbl_extend("force", opts, { desc = "Dynamic Symbols" }))
    map("n", "<leader>ft", tele.lsp_type_definitions, vim.tbl_extend("force", opts, { desc = "Goto Type" }))
    map("n", "<leader>fr", tele.lsp_references, vim.tbl_extend("force", opts, { desc = "Goto References" }))
    map("n", "<leader>fi", tele.lsp_implementations, vim.tbl_extend("force", opts, { desc = "Goto Impl" }))

    map("n", "K", vim.lsp.buf.hover, vim.tbl_extend("force", opts, { desc = "Hover" }))
    map("n", "<leader>e", vim.diagnostic.open_float, vim.tbl_extend("force", opts, { desc = "Diagnostic" }))
    map("n", "<leader>k", vim.lsp.buf.signature_help, vim.tbl_extend("force", opts, { desc = "Sig Help" }))
    map("n", "<leader>rn", vim.lsp.buf.rename, vim.tbl_extend("force", opts, { desc = "Rename" }))
    map("n", "<leader>ca", vim.lsp.buf.code_action, vim.tbl_extend("force", opts, { desc = "Code Action" }))
    map("n", "<leader>wf", vim.lsp.buf.format, vim.tbl_extend("force", opts, { desc = "Format" }))

    -- Visual mode code action
    map("v", "<leader>ca", vim.lsp.buf.code_action, vim.tbl_extend("force", opts, { desc = "Code Action" }))
  end,
})
