local util = require("lspconfig.util")

local M = {}

M.setup = function(opts)
  require("lspconfig").gopls.setup({
    cmd = { "gopls", "serve" },
    cmd_env = { GOFUMPT_SPLIT_LONG_LINES = "on" },
    on_attach = opts.on_attach,
    capabilities = opts.capabilities,
    document_highlight = { enabled = false },
    filetypes = { "go", "gomod", "gowork", "gotmpl" },
    root_dir = util.root_pattern("go.work", "go.mod", ".git"),
    flags = {
      debounce_text_changes = 150,
    },
    settings = {
      gopls = {
        gofumpt = true,
        analyses = {
          nilness = true,
          unusedparams = true,
          unusedwrite = true,
          useany = true,
        },
        usePlaceholders = true,
        completeUnimported = true,
        directoryFilters = { "-.git", "-.vscode", "-.idea", "-.vscode-test", "-node_modules", "-vendor" },
        semanticTokens = true,
      },
    },
  })
end

vim.api.nvim_create_autocmd("BufWritePre", {
  pattern = { "*.go" },
  callback = function()
    local params = vim.lsp.util.make_range_params(nil, "utf-16")
    params.context = { only = { "source.organizeImports" } }
    local result = vim.lsp.buf_request_sync(0, "textDocument/codeAction", params, 3000)
    for _, res in pairs(result or {}) do
      for _, r in pairs(res.result or {}) do
        if r.edit then
          vim.lsp.util.apply_workspace_edit(r.edit, "utf-16")
        else
          vim.lsp.buf.execute_command(r.command)
        end
      end
    end
  end,
})

return M
