{ pkgs, lib, inputs, ... }:

let
  inherit (builtins) readFile;
in
{
  config.home-manager.users.moritz.programs.neovim.lazy.plugins = [
    {
      plugin = pkgs.vimPlugins.oil-nvim;
      lazy = false;
      opts = { };
      dependencies = [{ plugin = pkgs.vimPlugins.nvim-web-devicons; }];
    }
    {
      plugin = pkgs.vimPlugins.lualine-nvim;
      opts = { };
      dependencies = [{ plugin = pkgs.vimPlugins.nvim-web-devicons; }];
    }
    {
      plugin = pkgs.vimPlugins.mini-nvim;
      lazy = false;
      conf = readFile ./lua/mini-nvim.lua;
    }
    {
      plugin = pkgs.vimPlugins.nvim-cmp;
      keys = [
        { key = "<leader>tc"; cmd = "<cmd>CmpToggle<cr>"; desc = "Toggle Cmp sources"; }
      ];
      conf = readFile ./lua/nvim-cmp.lua;
      event = [ "InsertEnter" ];
      dependencies = [
        {
          plugin = pkgs.vimPlugins.nvim-autopairs;
          opts = { };
        }
        { plugin = pkgs.vimPlugins.cmp-async-path; }
        { plugin = pkgs.vimPlugins.cmp-buffer; }
        { plugin = pkgs.vimPlugins.cmp-cmdline; }
        { plugin = pkgs.vimPlugins.cmp-nvim-lsp-signature-help; }
        { plugin = pkgs.vimPlugins.cmp-nvim-lsp; }
        {
          plugin = pkgs.vimUtils.buildVimPlugin {
            pname = "cmp-vimtex";
            version = lib.my.mkVersionInput inputs.cmp-vimtex;
            src = inputs.cmp-vimtex;
          };
        }
        { plugin = pkgs.vimPlugins.cmp_luasnip; }
        # {
        #   plugin = pkgs.vimPlugins.copilot-cmp;
        #   opts = { };
        #   dependencies = [
        #     {
        #       plugin = pkgs.vimPlugins.copilot-lua;
        #       opts = {
        #         suggestion = { enabled = false; };
        #         panel = { enabled = false; };
        #       };
        #       conf = /* lua */ ''
        #         require("copilot").setup(opts)
        #         vim.cmd("Copilot disable")
        #       '';
        #     }
        #   ];
        # }
        { plugin = pkgs.vimPlugins.friendly-snippets; }
        { plugin = pkgs.vimPlugins.lspkind-nvim; }
        {
          plugin = pkgs.vimPlugins.luasnip;
          conf = readFile ./lua/luasnip.lua;
        }
      ];
    }
    {
      plugin = pkgs.vimPlugins.direnv-vim;
      lazy = false;
    }
    {
      plugin = pkgs.vimPlugins.nvim-lspconfig.overrideAttrs (_: {
        version = lib.my.mkVersionInput inputs.nvim-lspconfig;
        src = inputs.nvim-lspconfig;
      });
      event = [ "BufRead" "BufNewFile" ];
      conf = readFile ./lua/nvim-lspconfig.lua;
      dependencies = [
        {
          # TODO: add all required tools to neovim or silence warnings
          plugin = pkgs.vimPlugins.none-ls-nvim;
          conf = readFile ./lua/null-ls-nvim.lua;
          dependencies = [
            {
              plugin = pkgs.vimUtils.buildVimPlugin {
                pname = "none-ls-shellcheck.nvim";
                version = lib.my.mkVersionInput inputs.none-ls-shellcheck-nvim;
                src = inputs.none-ls-shellcheck-nvim;
              };
            }
          ];
        }
        { plugin = pkgs.vimPlugins.lsp_lines-nvim; }
        {
          plugin = pkgs.vimPlugins.inc-rename-nvim;
          opts = {
            input_buffer_type = "dressing";
          };
          dependencies = [
            { plugin = pkgs.vimPlugins.dressing-nvim; }
          ];
        }
        {
          plugin = pkgs.vimUtils.buildVimPlugin {
            pname = "actions-preview-nvim";
            version = lib.my.mkVersionInput inputs.actions-preview-nvim;
            src = inputs.actions-preview-nvim;
          };
        }
      ];
    }
    {
      plugin = pkgs.vimPlugins.vim-fugitive;
      cmd = [
        "G"
        "Git"
        "Ggrep"
        "Glgrep"
        "Gclog"
        "Gllog"
        "Gcd"
        "Glcd"
        "Gedit"
        "Gsplit"
        "Gvsplit"
        "Gtabedit"
        "Gpedit"
        "Gdrop"
        "Gread"
        "Gwrite"
        "Gwq"
        "Gdiffsplit"
        "Gvdiffsplit"
        "GMove"
        "GRename"
        "GDelete"
        "GBrowse"
      ];
      keys = [
        { key = "<leader>gg"; cmd = "<cmd>Gedit :<cr>"; desc = "Open Status"; }
      ];
    }
    {
      plugin = pkgs.vimPlugins.vim-tmux-navigator;
      event = [ "VeryLazy" ];
    }
    {
      plugin = pkgs.vimPlugins.nvim-lastplace;
      event = [ "BufReadPost" "BufNewFile" ];
      opts = {
        lastplace_ignore_buftype = [ "quickfix" "nofile" "help" ];
        lastplace_ignore_filetype = [ "gitcommit" "gitrebase" "svn" "hgcommit" ];
        lastplace_open_folds = true;
      };
    }
    {
      plugin = pkgs.vimPlugins.telescope-nvim;
      cmd = [ "Telescope" ];
      conf = builtins.readFile ./lua/telescope.lua;
      keys = [
        { key = "<leader>ff"; cmd = "<cmd>Telescope find_files<cr>"; desc = "Find files"; }
        { key = "<leader>fb"; cmd = "<cmd>Telescope buffers<cr>"; desc = "Find buffers"; }
        { key = "<leader>fl"; cmd = "<cmd>Telescope current_buffer_fuzzy_find<cr>"; desc = "Search lines"; }
        {
          key = "<leader>fl";
          cmd = "y<ESC>:Telescope current_buffer_fuzzy_find default_text=<c-r>0<CR>";
          desc = "Search lines (selection)";
          mode = [ "v" ];
        }
        { key = "<leader>fg"; cmd = "<cmd>Telescope live_grep<cr>"; desc = "Live grep"; }
        {
          key = "<leader>fg";
          cmd = "y<ESC>:Telescope live_grep default_text=<c-r>0<CR>";
          desc = "Live grep (selection)";
          mode = [ "v" ];
        }
        { key = "<leader>fh"; cmd = "<cmd>Telescope help_tags<cr>"; desc = "Help tags"; }
        { key = "<leader>fr"; cmd = "<cmd>Telescope oldfiles<cr>"; desc = "Recent files"; }
      ];
      dependencies = [
        { plugin = pkgs.vimPlugins.plenary-nvim; }
        { plugin = pkgs.vimPlugins.telescope-fzf-native-nvim; }
      ];
    }
    {
      plugin = pkgs.vimPlugins.vim-startuptime;
      cmd = [ "StartupTime" ];
      conf = readFile ./lua/vim-startuptime.lua;
    }
    {
      plugin = pkgs.vimPlugins.typst-vim;
      ft = [ "typst" "typ" ];
    }
    {
      plugin = pkgs.vimPlugins.comment-nvim;
      event = [ "BufReadPost" "BufNewFile" ];
      opts = { };
    }
    {
      plugin = pkgs.vimPlugins.nvim-surround;
      event = [ "BufReadPost" "BufNewFile" ];
      opts = { };
    }
    {
      plugin = pkgs.vimPlugins.conform-nvim;
      keys = [
        { key = "="; cmd = "<cmd>lua require('conform').format()<cr>"; desc = "format buffer"; mode = [ "n" "v" ]; }
      ];
      cmd = [ "ConformInfo" "Format" ];
      conf = readFile ./lua/conform.lua;
    }
    { plugin = pkgs.vimPlugins.plantuml-syntax; }
    {
      plugin = pkgs.vimPlugins.vimtex;
      lazy = false;
      conf = /* lua */ ''
        vim.g.vimtex_view_method = "zathura"
        vim.g.vimtex_mappings_disable = vim.fn.executable("texlab") == 1 and { ["n"] = { "K" } } or {} -- disable `K` as it conflicts with LSP hover if texlab is in path
        vim.g.vimtex_quickfix_method = vim.fn.executable("pplatex") == 1 and "pplatex" or "latexlog"
      '';
      keys = [
        { key = "<localleader>l"; cmd = ""; desc = "+vimtex"; }
      ];
    }
  ];
}