-- Plugins

-- LSP stuff
local lsp_zero = require('lsp-zero')


lsp_zero.on_attach(function(_, bufnr)
	lsp_zero.default_keymaps({ buffer = bufnr })
end)

lsp_zero.format_on_save({
	format_opts = {
		async = false,
		timeout_ms = 10000,
	},
	servers = {
		['gopls'] = { 'go' },
		['nil_ls'] = { 'nix' },
		['lua_ls'] = { 'lua' },
		['ts_ls'] = { 'typescript', 'javascript' },
	},
})
-- LSP: go
local lspconfig = require('lspconfig')
lspconfig.gopls.setup({
	settings = {
		gopls = {
			analyses = {
				unusedparams = true,
			},
			staticcheck = true,
			gofumpt = true,
		}
	}
})
vim.api.nvim_create_autocmd("BufWritePre", {
	pattern = "*.go",
	callback = function()
		local params = vim.lsp.util.make_range_params()
		params.context = { only = { "source.organizeImports" } }
		-- buf_request_sync defaults to a 1000ms timeout. Depending on your
		-- machine and codebase, you may want longer. Add an additional
		-- argument after params if you find that you have to write the file
		-- twice for changes to be saved.
		-- E.g., vim.lsp.buf_request_sync(0, "textDocument/codeAction", params, 3000)
		local result = vim.lsp.buf_request_sync(0, "textDocument/codeAction", params)
		for cid, res in pairs(result or {}) do
			for _, r in pairs(res.result or {}) do
				if r.edit then
					local enc = (vim.lsp.get_client_by_id(cid) or {}).offset_encoding or "utf-16"
					vim.lsp.util.apply_workspace_edit(r.edit, enc)
				end
			end
		end
		vim.lsp.buf.format({ async = false })
	end
})

-- LSP: nix
lspconfig.nil_ls.setup({
	autostart = true,
	settings = {
		['nil'] = {
			formatting = {
				command = { "nixfmt" },
			},
		},
	},
})

-- LSP: lua
lspconfig.lua_ls.setup({
	on_init = function(client)
		local path = client.workspace_folders[1].name
		if vim.loop.fs_stat(path .. '/.luarc.json') or vim.loop.fs_stat(path .. '/.luarc.jsonc') then
			return
		end

		client.config.settings.Lua = vim.tbl_deep_extend('force', client.config.settings.Lua, {
			runtime = {
				-- Tell the language server which version of Lua you're using
				-- (most likely LuaJIT in the case of Neovim)
				version = 'LuaJIT'
			},
			-- Make the server aware of Neovim runtime files
			workspace = {
				checkThirdParty = false,
				library = {
					vim.env.VIMRUNTIME
					-- Depending on the usage, you might want to add additional paths here.
					-- "${3rd}/luv/library"
					-- "${3rd}/busted/library",
				}
				-- or pull in all of 'runtimepath'. NOTE: this is a lot slower
				-- library = vim.api.nvim_get_runtime_file("", true)
			}
		})
	end,
	settings = {
		Lua = {
			format = {
				enable = true,
				defaultConfig = {
					indent_style = "space",
					indent_size = "2",
				}
			}
		}
	}
})

-- LSP: ts/js
lspconfig.ts_ls.setup({
	init_options = {
		plugins = {
		},
	},
	filetypes = {
		"typescript",
		"javascript",
	},
})

-- LSP: rust

lspconfig.rust_analyzer.setup {
}

-- LSP: python
lspconfig.pyright.setup {
}

-- LSP: C/C++
lspconfig.clangd.setup({})

-- LSP: zig
lspconfig.zls.setup({})

-- Telescope
require('telescope').setup({
	extensions = {
		fzf = {
			fuzzy = true,
			override_generic_sorter = true,
			override_file_sorter = true,
			case_mode = "smart_case",
		}
	},
})

-- Tresitter stuff
require('nvim-treesitter.configs').setup {
	ensure_installed = {},
	auto_install = false,
	highlight = { enable = true },
	indent = { enable = true },

	incremental_selection = {
		enable = true,
		keymaps = {
			init_selection = '<c-space>',
			node_incremental = '<c-space>',
			scope_incremental = '<c-s>',
			node_decremental = '<M-space>',
		},
	},
	textobjects = {
		select = {
			enable = true,
			lookahead = true,

			keymaps = {
				['aa'] = '@parameter.outer',
				['ia'] = '@parameter.inner',
				['af'] = '@function.outer',
				['if'] = '@function.inner',
				['ac'] = '@class.outer',
				['ic'] = '@class.inner',
			}
		}
	}
}

-- Lualine
require('lualine').setup({
	options = {
		icons_enabled = false,
		component_separators = '|',
		disabled_filetypes = {},
		always_divide_middle = true,
		globalstatus = true,
	},
	sections = {
		lualine_a = { 'mode' },
		lualine_b = { 'branch', 'diff', 'diagnostics' },
		lualine_c = {
			{
				'filename',
				file_status = true,
				newfile_status = true,
				path = 3,
				shorting_target = 30,
				symbols = {
					modified = '[+]',
					readonly = '[-]',
					unnamed = '[No name]',
					newfile = '[New]'
				}
			}
		},
		lualine_x = { 'encoding', 'fileformat', 'filetype' },
		lualine_y = { 'progress' },
		lualine_z = { 'location' }
	}
})

-- Copilot
require('copilot').setup({
	suggestions = { enabled = false },
	panel = { enabled = false },
})
require('copilot_cmp').setup()

-- Cmp
local cmp = require('cmp')
local cmp_action = lsp_zero.cmp_action()

cmp.setup({
	snippet = {
		expand = function(args)
			require('luasnip').lsp_expand(args.body)
		end,
	},
	mapping = cmp.mapping.preset.insert({
		-- Enter to confirm completion
		['<CR>'] = cmp.mapping.confirm({ select = false }),
		-- Ctrl+Space to open completion menu
		['<C-Space>'] = cmp.mapping.complete(),
		-- Move between snippet placeholders
		['<C-f>'] = cmp_action.luasnip_jump_forward(),
		['<C-b>'] = cmp_action.luasnip_jump_backward(),
		-- Scroll in completion docs
		['<C-k>'] = cmp.mapping.scroll_docs(-4),
		['<C-j>'] = cmp.mapping.scroll_docs(4),
	}),
	sources = cmp.config.sources({
	}, {
		{ name = "copilot",  group_index = 2 },
		{ name = "nvim_lsp", group_index = 2 },
		-- { name = "luasnip" },
		-- { name = "buffer" },
	})
})


-- Colorscheme
require('catppuccin').setup({
})
vim.cmd.colorscheme "catppuccin"