-- Work around https://github.com/neovim/neovim/issues/21856
vim.api.nvim_create_autocmd({ "VimLeave" }, {
  callback = function()
    vim.fn.jobstart("/bin/true", { detach = true })
  end,
})

vim.diagnostic.config({
  -- Use the default configuration
  -- virtual_lines = true,

  -- Alternatively, customize specific options
  -- virtual_lines = {
  --  -- Only show virtual line diagnostics for the current cursor line
  --  current_line = true,
  -- },

  -- Open in floating window
  float = {
    source = "always",
    border = "shadow",
  },
})

require("nvim-web-devicons").setup {}

require("fidget").setup {
  progress = {
    display = {
      progress_icon = {
        pattern = "dots",
        period = 1,
      },
    },
  },
}

require("fzf-lua").setup {
  previewers = {
    builtin = {
      extensions = {
        ["png"] = { "chafa" },
        ["jpg"] = { "chafa" },
        ["jpeg"] = { "chafa" },
        ["gif"] = { "chafa" },
      },
    },
  },
}

vim.keymap.set("n", "<C-p>", "<cmd>lua require('fzf-lua').files()<CR>", { noremap = true, silent = true })
vim.keymap.set("n", "<C-g>", "<cmd>lua require('fzf-lua').git_status()<CR>", { noremap = true, silent = true })
vim.keymap.set("n", "<C-/>", "<cmd>lua require('fzf-lua').live_grep()<CR>", { noremap = true, silent = true })
vim.keymap.set("n", "<C-\\>", "<cmd>lua require('fzf-lua').buffers()<CR>", { noremap = true, silent = true })
vim.keymap.set("n", "<C-b>", "<cmd>lua require('fzf-lua').builtin()<CR>", { noremap = true, silent = true })
vim.keymap.set("n", "ca", "<cmd>lua require('fzf-lua').lsp_code_actions()<CR>", { noremap = true, silent = true })

require("nvim-treesitter.configs").setup {
  highlight = {
    enable = true,
    additional_vim_regex_highlighting = false,
  },
  indent = {
    enable = true,
    disable = { "c", "cpp" },
  }
}

require("nvim-format-buffer").setup({
  verbose = false,
  format_rules = {
    { pattern = { "*.c", "*.h" }, command = "clang-format" },
    {
      pattern = { "*.js", "*.mjs", "*.ts", "*.mts", "*.cjs", "*.tsx", "*.vue", "*.css" },
      command = function()
        return "prettier --stdin-filepath " .. vim.api.nvim_buf_get_name(0)
      end,
    },
    { pattern = { "*.sql" }, command = "pg_format --spaces=2 --wrap-limit=1000 --no-rcfile" },
    { pattern = { "*.py", "*.pyi" }, command = "ruff check --select I --fix --silent - | ruff format -" }
  },
})

require("vim.lsp.log").set_format_func(vim.inspect)
-- vim.lsp.set_log_level("debug")

vim.keymap.set("n", "[d", "<cmd>lua vim.diagnostic.jump({count = -1, float = true})<CR>", { noremap = true, silent = true })
vim.keymap.set("n", "]d", "<cmd>lua vim.diagnostic.jump({count = 1, float = true})<CR>", { noremap = true, silent = true })
vim.keymap.set("n", "[e", "<cmd>lua vim.diagnostic.jump({count = -1, severity = vim.diagnostic.severity.ERROR, float = true})<CR>", { noremap = true, silent = true })
vim.keymap.set("n", "]e", "<cmd>lua vim.diagnostic.jump({count = -1, severity = vim.diagnostic.severity.ERROR, float = true})<CR>", { noremap = true, silent = true })

vim.keymap.set("n", "gd", "<Cmd>lua vim.lsp.buf.definition()<CR>", { noremap = true, silent = true })
vim.keymap.set("n", "gD", "<Cmd>lua vim.lsp.buf.declaration()<CR>", { noremap = true, silent = true })
vim.keymap.set("n", "gh", "<cmd>lua vim.lsp.buf.signature_help()<CR>", { noremap = true, silent = true })
vim.keymap.set("n", "gI", "<cmd>lua vim.lsp.buf.implementation()<CR>", { noremap = true, silent = true })
vim.keymap.set("n", "gt", "<cmd>lua vim.lsp.buf.type_definition()<CR>", { noremap = true, silent = true })

vim.keymap.set("n", "gl", "<cmd>lua vim.diagnostic.reset()<CR>", { noremap = true, silent = true })

vim.lsp.enable("pyright")
vim.lsp.config("pyright", {})

vim.lsp.enable("ts_ls")
vim.lsp.config("ts_ls", {
  init_options = {
    plugins = {
      {
        name = "@vue/typescript-plugin",
        location = "/home/mordae/.config/yarn/global/node_modules/@vue/typescript-plugin",
        languages = { "javascript", "typescript", "vue" },
      },
    },
  },
  filetypes = {
    "javascript",
    "typescript",
    "vue",
  },
})

vim.lsp.enable("volar")
vim.lsp.config("volar", {
  init_options = {
    typescript = {
      tsdk = "/home/mordae/.config/yarn/global/node_modules/typescript/lib",
    }
  }
})

vim.lsp.enable("clangd")
vim.lsp.config("clangd", {
  cmd = {
    "clangd",
    "--background-index",
    "--suggest-missing-includes",
    "--enable-config",
    "--query-driver=/usr/lib64/ccache/*,/usr/bin/*",
  }
})

vim.lsp.enable("ruff")
vim.lsp.config("ruff", {})

vim.lsp.enable("rust_analyzer")
vim.lsp.config("rust_analyzer", {})

-- Automatic completion triggering
-- vim.api.nvim_create_autocmd("LspAttach", {
--   callback = function(ev)
--     local client = vim.lsp.get_client_by_id(ev.data.client_id)
--     if client:supports_method("textDocument/completion") then
--       vim.lsp.completion.enable(true, client.id, ev.buf, { autotrigger = true })
--     end
--   end,
-- })

local function check_back_space()
  local col = vim.fn.col('.') - 1
  return col <= 0 or vim.fn.getline('.'):sub(col, col):match('%s')
end

function tab_complete()
  if check_back_space() then
    return vim.api.nvim_replace_termcodes('<Tab>', true, false, true)
  end
  return vim.api.nvim_replace_termcodes('<C-p>', true, false, true)
end

vim.api.nvim_set_keymap('i', '<Tab>', 'v:lua.tab_complete()', { expr = true, noremap = true })
vim.api.nvim_set_keymap('i', '<S-Tab>', '<C-n>', { noremap = true })
