{ lib, pkgs, config, ... }:
with lib;
let
  cfg = config.modules.cli.neovim;
  nvim-spell-fr-utf8-dictionary = builtins.fetchurl {
    url = "https://ftp.nluug.nl/vim/runtime/spell/fr.utf-8.spl";
    sha256 = "abfb9702b98d887c175ace58f1ab39733dc08d03b674d914f56344ef86e63b61";
  };
  nvim-spell-fr-utf8-suggestions = builtins.fetchurl {
    url = "https://ftp.nluug.nl/vim/runtime/spell/fr.utf-8.sug";
    sha256 = "0294bc32b42c90bbb286a89e23ca3773b7ef50eff1ab523b1513d6a25c6b3f58";
  };
  nvim-k8s-lsp = pkgs.vimUtils.buildVimPlugin {
    pname = "nvim-k8s-lsp";
    version = "main";
    src = builtins.fetchGit {
      url = "https://github.com/tonychg/nvim-k8s-lsp.git";
      rev = "5e8221cce09cb71b7604c0c7469bf9053dd877ca";
      ref = "feat/add-helm-ls-support";
    };
  };
in
{
  options.modules.cli.neovim = {
    enable = mkEnableOption "enable Neovim text editor";
  };
  config = mkIf cfg.enable {
    home.file."${config.xdg.configHome}/nvim/spell/fr.utf-8.spl".source = nvim-spell-fr-utf8-dictionary;
    home.file."${config.xdg.configHome}/nvim/spell/fr.utf-8.sug".source = nvim-spell-fr-utf8-suggestions;

    home.file."${config.xdg.configHome}/nvim/lsp/bash.lua".source = ./files/lsp/bash.lua;
    home.file."${config.xdg.configHome}/nvim/lsp/helm.lua".source = ./files/lsp/helm.lua;
    home.file."${config.xdg.configHome}/nvim/lsp/lua.lua".source = ./files/lsp/lua.lua;
    home.file."${config.xdg.configHome}/nvim/lsp/nills.lua".source = ./files/lsp/nills.lua;
    home.file."${config.xdg.configHome}/nvim/lsp/pylsp.lua".source = ./files/lsp/pylsp.lua;
    home.file."${config.xdg.configHome}/nvim/lsp/terraformls.lua".source = ./files/lsp/terraformls.lua;
    home.file."${config.xdg.configHome}/nvim/lsp/tflint.lua".source = ./files/lsp/tflint.lua;
    home.file."${config.xdg.configHome}/nvim/lsp/yaml.lua".source = ./files/lsp/yaml.lua;

    programs.neovim = {
      enable = true;
      defaultEditor = true;
      vimAlias = true;
      withNodeJs = true;
      withPython3 = true;
      extraPackages = with pkgs; [
        # LSP Servers
        clang-tools
        hadolint
        helm-ls
        lua-language-server
        marksman
        nil
        nodePackages.bash-language-server
        python3Packages.python-lsp-server
        shellcheck

        terraform-lsp
        tflint
        vscode-langservers-extracted
        yaml-language-server

        # Formatters
        nixfmt-rfc-style
        shfmt
        yamlfmt
      ];
      extraLuaConfig =
        (builtins.readFile ./files/options.lua)
        + (builtins.readFile ./files/keybindings.lua)
        + (builtins.readFile ./files/lsp.lua)
      ;
      plugins = with pkgs.vimPlugins; [
        {
          plugin = nvim-autopairs;
          type = "lua";
          config = ''
            local autopair = require("nvim-autopairs").setup {}
          '';
        }
        {
          plugin = catppuccin-nvim;
          type = "lua";
          config = (builtins.readFile ./files/plugins/theme.lua);
        }
        {
          plugin = blink-cmp;
          type = "lua";
          config = (builtins.readFile ./files/plugins/blink-cmp.lua);
        }
        blink-emoji-nvim
        blink-cmp-dictionary
        {
          plugin = conform-nvim;
          type = "lua";
          config = (builtins.readFile ./files/plugins/conform.lua);
        }
        {
          plugin = fzf-lua;
          type = "lua";
          config = (builtins.readFile ./files/plugins/fzf-lua.lua);
        }
        {
          plugin = gitsigns-nvim;
          type = "lua";
          config = (builtins.readFile ./files/plugins/luasnip.lua);
        }
        {
          plugin = indent-blankline-nvim;
          type = "lua";
          config =''
            require("ibl").setup{
              indent = { char = "│"},
            }
          '';
        }
        {
          plugin = lualine-nvim;
          type = "lua";
          config = (builtins.readFile ./files/plugins/lualine.lua);
        }
        {
         plugin = neo-tree-nvim;
         type = "lua";
         config = (builtins.readFile ./files/plugins/neotree.lua);
        }
        nui-nvim
        {
          plugin = nvim-web-devicons;
          type = "lua";
          config=''
            require('nvim-web-devicons').setup {}
          '';
        }
        {
          plugin = nvim-lint;
          type = "lua";
          config = ( builtins.readFile ./files/plugins/nvim-lint.lua);
        }
        {
          plugin = nvim-sops;
          type = "lua";
          config = (builtins.readFile ./files/plugins/nvim-sops.lua);
        }
        plenary-nvim
        {
          plugin = (nvim-treesitter.withPlugins (p: [
              p.bash
              p.c
              p.cpp
              p.cmake
              p.dockerfile
              p.hcl
              p.helm
              p.javascript
              p.latex
              p.lua
              p.llvm
              p.markdown
              p.markdown_inline
              p.nix
              p.puppet
              p.python
              p.ruby
              p.terraform
              p.typescript
              p.vim
              p.yaml
            ])
          );
          type = "lua";
          config = ( builtins.readFile ./files/plugins/treesitter.lua);
        }
        {
          plugin = nvim-treesitter-context;
          type = "lua";
          config = ( builtins.readFile ./files/plugins/treesitter_context.lua);

        }
        {
          plugin = which-key-nvim;
          type = "lua";
          config = ( builtins.readFile ./files/plugins/whichkey.lua );
        }
        {
          plugin = nvim-k8s-lsp ;
          type = "lua";
          config = ( builtins.readFile ./files/plugins/nvim-k8s-lsp.lua );
        }
        vim-helm
      ];
    };
  };
}
