-- lsp-config.lua: Configures Language Server Protocol for code analysis and diagnostics.

return {
  {
    "williamboman/mason.nvim",
    lazy = false,
    config = function()
      require("mason").setup()
    end,
  },
  {
    "williamboman/mason-lspconfig.nvim",
    lazy = false,
    opts = {
      auto_install = true,
      ensure_installed = {
        "lua_ls",
        "pyright",
        "bashls",
        "ts_ls",
        "solargraph",
        "html",
        "texlab",
        "ltex",
        "dockerls",
        "yamlls",
        "taplo",
        "cssls",
      },
    },
  },
  {
    "neovim/nvim-lspconfig",
    lazy = false,
    dependencies = {
      "SmiteshP/nvim-navic",
    },
    config = function()
      local capabilities = require("cmp_nvim_lsp").default_capabilities()
      local navic = require("nvim-navic")

      -- Common on_attach function
      local on_attach = function(client, bufnr)
        if client.server_capabilities.documentSymbolProvider then
          navic.attach(client, bufnr)
        end
      end

      -- Define server configurations
      local servers = {
        ts_ls = {
          capabilities = capabilities,
          on_attach = on_attach,
        },
        taplo = {
          capabilities = capabilities,
          on_attach = on_attach,
        },
        solargraph = {
          capabilities = capabilities,
          on_attach = on_attach,
        },
        textlsp = {
          filetypes = { "ltx", "txt" },
          capabilities = capabilities,
          on_attach = on_attach,
        },
        texlab = {
          capabilities = capabilities,
          on_attach = on_attach,
          settings = {
            texlab = {
              build = {
                executable = "latexmk",
                args = { "-pdf", "-interaction=nonstopmode", "-synctex=1", "%f" },
                onSave = true,
              },
              forwardSearch = {
                executable = "zathura",
                args = { "--synctex-forward", "%l:1:%f", "%p" },
              },
              chktex = {
                onOpenAndSave = true,
                onEdit = false,
              },
            },
          },
        },
        ltex = {
          capabilities = capabilities,
          on_attach = on_attach,
          filetypes = { "latex", "tex", "bib", "markdown", "mail", "text" },
          settings = {
            ltex = {
              language = "en-US",
              enabled = { "latex", "tex", "bib", "markdown", "mail", "text" },
              checkFrequency = "save", -- Only check when you save, not on every keystroke
              diagnosticSeverity = "warning", -- Less intrusive
              completionEnabled = true,
              additionalRules = {
                enablePickyRules = true,
                motherTongue = "en-US",
              },
              disabledRules = {
                -- Add rules you want to disable, e.g.:
                -- ["en-US"] = { "MORFOLOGIK_RULE_EN_US" },
              },
              dictionary = {
                -- Add custom words here that shouldn't be flagged
                ["en-US"] = {
                  -- "aerc",
                  -- "notmuch",
                  -- "dovecot",
                },
              },
              java = {
                path = "",
                initialHeapSize = 64,
                maximumHeapSize = 512,
              },
            },
          },
        },
        html = {
          capabilities = capabilities,
          on_attach = on_attach,
        },
        lua_ls = {
          capabilities = capabilities,
          on_attach = on_attach,
          settings = {
            Lua = {
              diagnostics = {
                globals = { "vim" },
              },
              workspace = {
                checkThirdParty = false,
              },
              telemetry = {
                enable = false,
              },
            },
          },
        },
        cssls = {
          capabilities = capabilities,
          on_attach = on_attach,
          settings = {
            css = {
              validate = true,
              lint = {
                unknownAtRules = "ignore",
              },
            },
            scss = {
              validate = true,
              lint = {
                unknownAtRules = "ignore",
              },
            },
            less = {
              validate = true,
              lint = {
                unknownAtRules = "ignore",
              },
            },
          },
        },
        pyright = {
          capabilities = capabilities,
          on_attach = on_attach,
        },
        bashls = {
          filetypes = { "sh", "bash", "zsh" },
          capabilities = capabilities,
          on_attach = on_attach,
          settings = {
            bashIde = {
              globPattern = "*@(.sh|.inc|.bash|.command|.zsh)",
              shellcheckPath = "shellcheck",
            },
          },
        },
        dockerls = {
          capabilities = capabilities,
          on_attach = on_attach,
        },
        yamlls = {
          capabilities = capabilities,
          on_attach = on_attach,
          settings = {
            yaml = {
              schemas = {
                ["https://json.schemastore.org/docker-compose.json"] = "docker-compose*.{yml,yaml}",
                ["https://json.schemastore.org/github-workflow.json"] = ".github/workflows/*",
              },
            },
          },
        },
      }

      -- Setup each server
      for server, config in pairs(servers) do
        vim.lsp.config[server] = config
        vim.lsp.enable(server)
      end

      -- Configure diagnostics globally
      vim.diagnostic.config({
        virtual_text = false, -- Disable inline diagnostic text (no more popups!)
        signs = true, -- Keep gutter signs
        underline = true, -- Underline errors
        update_in_insert = false, -- Don't update diagnostics while typing
        severity_sort = true,
        float = {
          border = "rounded",
          source = "always",
          header = "",
          prefix = "",
        },
      })

      -- LSP keymaps
      vim.keymap.set("n", "K", vim.lsp.buf.hover, {})
      vim.keymap.set("n", "<leader>gd", vim.lsp.buf.definition, {})
      vim.keymap.set("n", "<leader>gr", vim.lsp.buf.references, {})
      vim.keymap.set("n", "<leader>ca", vim.lsp.buf.code_action, {})

      -- Show diagnostics in floating window (optional - press this when you want to see the error)
      vim.keymap.set("n", "<leader>e", vim.diagnostic.open_float, {})
      vim.keymap.set("n", "[d", vim.diagnostic.goto_prev, {})
      vim.keymap.set("n", "]d", vim.diagnostic.goto_next, {})
    end,
  },
}
