-- [[ LSP setup ]]
-- You can consolidate your enable calls into a single table
vim.lsp.enable({
	"luals",
	"rust",
	"gopls",
	"bashls",
	"terraform",
})

-- Global capabilities override remains exactly the same
vim.lsp.config("*", {
	capabilities = {
		textDocument = {
			semanticTokens = {
				multilineTokenSupport = true,
			},
		},
	},
})

-- Add rounded borders to diagnostic floating windows
vim.diagnostic.config({
	float = { border = "rounded" },
})

-- Consolidate all LSP actions into a single LspAttach autocmd
vim.api.nvim_create_autocmd("LspAttach", {
	group = vim.api.nvim_create_augroup("UserLspConfig", { clear = true }),
	callback = function(args)
		local client = assert(vim.lsp.get_client_by_id(args.data.client_id))

		-- args.buf is the modern 0.12 standard. It guarantees you are acting
		-- exactly on the buffer that triggered the attach.
		local bufnr = args.buf

		-- [[ INLAY HINTS ]]
		if client:supports_method("textDocument/inlayHint") then
			-- Enable them by default when opening the file
			vim.lsp.inlay_hint.enable(true, { bufnr = bufnr })

			-- Create a buffer-local keymap to toggle them on/off
			vim.keymap.set("n", "<leader>th", function()
				local is_enabled = vim.lsp.inlay_hint.is_enabled({ bufnr = bufnr })
				vim.lsp.inlay_hint.enable(not is_enabled, { bufnr = bufnr })
			end, { buffer = bufnr, desc = "Toggle Inlay Hints" })
		end
		-- [[ FOLDING SETUP ]]
		if client:supports_method("textDocument/foldingRange") then
			-- opt_local cleanly applies to the attached buffer without risking
			-- applying to the wrong window if attached in the background
			vim.opt_local.foldexpr = "v:lua.vim.lsp.foldexpr()"
			vim.opt_local.foldmethod = "expr"
		end

		-- [[ NAVIGATION ]]
		vim.keymap.set("n", "gd", function()
			require("fzf-lua").lsp_definitions()
		end, { buffer = bufnr, desc = "Go to definition" })

		vim.keymap.set("n", "gr", function()
			require("fzf-lua").lsp_references()
		end, { buffer = bufnr, desc = "Find references" })

		vim.keymap.set("n", "gI", function()
			require("fzf-lua").lsp_implementations()
		end, { buffer = bufnr, desc = "Go to implementation" })

		vim.keymap.set("n", "gD", vim.lsp.buf.declaration, { buffer = bufnr, desc = "Go to declaration" })

		vim.keymap.set("n", "K", function()
			vim.lsp.buf.hover({ border = "rounded", max_width = 120 })
		end, { buffer = bufnr, desc = "Show documentation" })

		-- [[ CODE ACTIONS ]]
		-- Note: Neovim 0.11+ automatically maps 'gra' to code actions natively.

		vim.keymap.set("n", "<leader>cf", function()
			vim.lsp.buf.code_action({
				context = { only = { "quickfix" } },
				apply = true,
			})
		end, { buffer = bufnr, desc = "Apply fix at cursor" })
	end,
})

-- vim.api.nvim_create_autocmd("LspAttach", {
-- 	group = vim.api.nvim_create_augroup("lsp_completion", { clear = true }),
-- 	callback = function(args)
-- 		local client_id = args.data.client_id
-- 		if not client_id then
-- 			return
-- 		end
--
-- 		local client = vim.lsp.get_client_by_id(client_id)
-- 		if client and client:supports_method("textDocument/completion") then
-- 			-- Enable native LSP completion for this client + buffer
-- 			vim.lsp.completion.enable(true, client_id, args.buf, {
-- 				autotrigger = true, -- auto-show menu as you type (recommended)
-- 				-- You can also set { autotrigger = false } and trigger manually with <C-x><C-o>
-- 			})
-- 		end
-- 	end,
-- })
