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

let
in
with lib;
{
  options = {
    nixvim = {
      enable = mkEnableOption "enable k9s";
      theme = mkOption {
        type = types.str;
        default = "latte";
        description = "Catppuccin theme variant for k9s.";
      };
	  lsp_jobb = mkEnableOption "enable jobb lsps";
    };
  };

  config = mkIf config.nixvim.enable {
    programs.nixvim = {
      enable = true;

      package = inputs.neovim-nightly-overlay.packages.${pkgs.stdenv.hostPlatform.system}.default;
      colorschemes = {
        catppuccin = {
          enable = true;
          settings = {
            flavour = config.nixvim.theme;
          };
        };
      };

      #################################
      ## Neovim options
      #################################
      opts = {
        number = true;
        relativenumber = true;
        signcolumn = "yes";
        tabstop = 4;
        shiftwidth = 4;
        swapfile = false;
        wrap = true;
        termguicolors = true;
        winborder = "rounded";
      };
      clipboard.register = "unnamedplus";

      globals.mapleader = " ";

      #################################
      ## Keymaps
      #################################
      keymaps = [
        # Telescope
        {
          mode = "n";
          key = "<leader>f";
          action = "<cmd>Telescope find_files<CR>";
        }
        {
          mode = "n";
          key = "<leader>o";
          action = "<cmd>Telescope live_grep<CR>";
        }

        # Substitute
        {
          mode = "n";
          key = "s";
          action = "<cmd>lua require('substitute').operator()<CR>";
        }
        {
          mode = "n";
          key = "ss";
          action = "<cmd>lua require('substitute').line()<CR>";
        }
        {
          mode = "n";
          key = "S";
          action = "<cmd>lua require('substitute').eol()<CR>";
        }
        {
          mode = "x";
          key = "s";
          action = "<cmd>lua require('substitute').visual()<CR>";
        }

        # LSP
        {
          mode = "n";
          key = "<leader>lf";
          action = "<cmd>lua vim.lsp.buf.format()<CR>";
        }
        {
          mode = "n";
          key = "<leader>gg";
          action = "<cmd>LazyGit<CR>";
        }

        # Navigation fixes for wrap
        {
          mode = "n";
          key = "j";
          action = "gj";
          options.silent = true;
        }
        {
          mode = "n";
          key = "k";
          action = "gk";
          options.silent = true;
        }

        # Buffers
        {
          mode = "n";
          key = "<Tab>";
          action = ":bnext<CR>";
        }
        {
          mode = "n";
          key = "<S-Tab>";
          action = ":bprevious<CR>";
        }
        {
          mode = "n";
          key = "<leader>c";
          action = ":bdelete<CR>";
        }

        # Window movement
        {
          mode = "n";
          key = "<C-k>";
          action = "<cmd>wincmd k<CR>";
        }
        {
          mode = "n";
          key = "<C-j>";
          action = "<cmd>wincmd j<CR>";
        }
        {
          mode = "n";
          key = "<C-h>";
          action = "<cmd>wincmd h<CR>";
        }
        {
          mode = "n";
          key = "<C-l>";
          action = "<cmd>wincmd l<CR>";
        }

        # Save / quit
        {
          mode = "n";
          key = "<Space>w";
          action = ":w<CR>";
        }
        {
          mode = "n";
          key = "<Space>q";
          action = ":qa<CR>";
        }

        # Oil
        {
          mode = "n";
          key = "-";
          action = "<CMD>Oil<CR>";
        }
        {
          mode = "n";
          key = "<leader>h";
          action = "<CMD>Oil<CR>";
        }
      ];

      #################################
      ## Plugins
      #################################
      plugins = {
        web-devicons.enable = true;

        lualine = {
          enable = true;

          settings = {
            options.theme = "catppuccin";
            tabline = {
              lualine_a = [ "mode" ];
              lualine_b = [
                "branch"
                "diagnostics"
              ];
              lualine_y = [ "buffers" ];
            };
            sections = {
				lualine_a = [];
				lualine_b = [];
				lualine_c = [];
				lualine_x = [];
				lualine_y = [];
				lualine_z = [];
			};
          };
        };

        treesitter = {
          enable = true;

          grammarPackages = with pkgs.vimPlugins.nvim-treesitter.builtGrammars; [
            bash
            json
            lua
            make
            markdown
            helm
            nix
            regex
            toml
            vim
            vimdoc
            xml
            yaml
          ];
        };
        oil = {
          enable = true;
          settings = {
            default_file_explorer = true;
            columns = [ "icon" ];
            win_options = {
              wrap = false;
              signcolumn = "no";
            };
          };
        };

        auto-session.enable = true;

        comment.enable = true;
        which-key.enable = true;
        nvim-autopairs.enable = true;
        vim-surround.enable = true;

        lazygit.enable = true;

        telescope.enable = true;
        luasnip.enable = true;

        cmp = {
          enable = true;

          settings = {
            mapping = {
              "<C-Space>" = "cmp.mapping.complete()";
              "<C-d>" = "cmp.mapping.scroll_docs(-4)";
              "<C-e>" = "cmp.mapping.close()";
              "<C-f>" = "cmp.mapping.scroll_docs(4)";
              "<CR>" = "cmp.mapping.confirm({ select = true })";
              "<S-Tab>" = "cmp.mapping(cmp.mapping.select_prev_item(), {'i', 's'})";
              "<Tab>" = "cmp.mapping(cmp.mapping.select_next_item(), {'i', 's'})";
            };
            sources = [
              { name = "nvim_lsp"; }
              { name = "luasnip"; }
            ];
          };
        };
        lsp = {
          enable = true;
          servers = {
            gopls.enable = true;
            nixd.enable = true;
            lua_ls.enable = true;
            bashls.enable = true;

            tinymist.enable = true;
            tinymist.settings.formatterMode = "typstyle";

            yamlls.enable = true;
            jsonls.enable = true;
            ts_ls.enable = true;
            helm_ls.enable = true;

            nginx_language_server.enable = config.nixvim.lsp_jobb;
            dockerls.enable = config.nixvim.lsp_jobb;
            docker_compose_language_service.enable = config.nixvim.lsp_jobb;
            omnisharp.enable = config.nixvim.lsp_jobb;
          };
        };
      };
      enableMan = false;

      #################################
      ## LSP
      #################################
      #################################
      ## Autocommands
      #################################
      autoCmd = [
        {
          event = [
            "BufRead"
            "BufNewFile"
          ];
          pattern = "*.{md,typ}";
          callback = "vim.opt_local.spell = true";
        }
      ];

      #################################
      ## Colorscheme
      #################################
    };

  };
}
