{ config
, lib
, pkgs
, ...
}:

with lib;
let
  cfg = config.my.programs.nvim;

  mkPlugin = fileName:
    let
      path = ./plugins + "/${fileName}";
      pluginName = lib.removeSuffix ".lua" fileName;
    in
    {
      plugin = pkgs.vimPlugins.${pluginName};
      type = "lua";
      config = lib.readFile path;
    };
  pluginFileNames = builtins.attrNames (builtins.readDir ./plugins);
  pluginsWithConfig = builtins.map mkPlugin pluginFileNames;
in
{
  options.my.programs.nvim.enable = mkEnableOption "nvim";

  config = mkIf cfg.enable {
    home-manager.users.moritz = {
      home.packages = with pkgs; [
        (
          if config.my.programs.hyprland.enable
          then neovide-hyprland
          else neovide
        )
      ];

      programs.neovim = {
        enable = true;
        package = pkgs.neovim-nightly;
        vimAlias = true;
        vimdiffAlias = true;
        withNodeJs = true;
        withPython3 = true;
        extraLuaConfig = lib.concatLines (
          builtins.map
            builtins.readFile
            [ ./options.lua ./keybinds.lua ./init.lua ]
        );
        extraPackages = with pkgs; [
          alejandra
          black
          isort
          jq
          nil
          nixpkgs-fmt
          nodePackages.bash-language-server
          rustfmt
          shellcheck
          shfmt
          stylua
          sumneko-lua-language-server
          taplo
          yamlfmt
        ];
        plugins = with pkgs.vimPlugins; [
          cmp-nvim-lsp
          cmp_luasnip
          copilot-cmp
          direnv-vim
          impatient-nvim
          lsp_lines-nvim
          lspkind-nvim
          lspsaga-nvim-original
          lualine-lsp-progress
          luasnip
          nui-nvim
          nvim-cmp
          nvim-lspconfig
          nvim-treesitter.withAllGrammars
          nvim-ufo
          nvim-web-devicons
          plenary-nvim
          popup-nvim
          promise-async
          vim-fugitive
          vim-lion
        ] ++ pluginsWithConfig;
      };
    };
  };
}
