{
  config,
  pkgs,
  lib,
  ...
}: let
  cfg = config.hive.doom;
  doom-pkgs = with pkgs; [
    cmake
    emacs-all-the-icons-fonts
    fira
    fira-code-symbols
    fontconfig
    gcc
    nerd-fonts.fira-code
  ];
  default-core-pkgs = with pkgs; [
    (ripgrep.override {withPCRE2 = true;})
    (aspellWithDicts (d: [d.en d.de d.en-computers d.en-science]))
    binutils
    editorconfig-core-c
    fd
    git
    gnumake
    gnutls
    ispell
    libtool
    vscode-langservers-extracted
  ];
  default-shell-pkgs = with pkgs; [
    bash-language-server
  ];
  default-nix-pkgs = with pkgs; [
    alejandra
    nixd
  ];
  default-latex-pkgs = with pkgs; [
    pandoc
    poppler
    texlab
    texlive.combined.scheme-medium
  ];
  default-cxx-pkgs = with pkgs; [
    clang
    clang-tools
    cmake
    cppcheck
    doxygen
    gdb
    ninja
  ];
  default-python-pkgs = with pkgs; [
    python
    pythonPackages.black
    pyright
  ];
  doom-path-pkgs =
    lib.optionals cfg.withLatexPkgs (cfg.overrideLatexPkgs default-latex-pkgs)
    ++ lib.optionals cfg.withShellPkgs (cfg.overrideShellPkgs default-shell-pkgs)
    ++ lib.optionals cfg.withNixPkgs (cfg.overrideNixPkgs default-nix-pkgs)
    ++ lib.optionals cfg.withCXXPkgs (cfg.overrideCXXPkgs default-cxx-pkgs)
    ++ lib.optional cfg.enableCopilot pkgs.unstable.copilot-language-server
    ++ default-core-pkgs;
  doom-socket-name = "main";
  wrapped-emacs = pkgs.symlinkJoin {
    name = "wrapped-emacs";
    paths = [pkgs.emacs30];
    nativeBuildInputs = [pkgs.makeBinaryWrapper];
    postBuild = ''
      wrapProgram $out/bin/emacs \
        --prefix PATH : ${lib.makeBinPath doom-path-pkgs} \
        --add-flags "--init-directory=${config.xdg.configHome}/doom-emacs" \
        --set DOOMDIR "${config.home.sessionVariables.DOOMDIR}" \
        --set DOOMLOCALDIR "${config.home.sessionVariables.DOOMLOCALDIR}"

      wrapProgram $out/bin/emacsclient \
        --prefix PATH : ${lib.makeBinPath doom-path-pkgs} \
        --set DOOMDIR "${config.home.sessionVariables.DOOMDIR}" \
        --set DOOMLOCALDIR "${config.home.sessionVariables.DOOMLOCALDIR}"
    '';
  };
  doom-setup = pkgs.writeShellScript "doom-setup" ''
    export PATH="${lib.makeBinPath doom-path-pkgs}:$PATH"
    export EMACS="${wrapped-emacs}/bin/emacs"
    export DOOMDIR="${config.home.sessionVariables.DOOMDIR}"
    export DOOMLOCALDIR="${config.home.sessionVariables.DOOMLOCALDIR}"
    if [ ! -d "$DOOMLOCALDIR" ]; then
      ${config.xdg.configHome}/doom-emacs/bin/doom install --force --no-env
    else
      ${config.xdg.configHome}/doom-emacs/bin/doom "$@"
    fi
  '';
  doom-open = pkgs.writeShellScriptBin "doom-open" ''
    export EMACS_SOCKET_NAME="$XDG_RUNTIME_DIR/emacs/${doom-socket-name}"
    if [ -t 0 ]; then
      exec ${wrapped-emacs}/bin/emacsclient -t "$@"
    else
      exec ${wrapped-emacs}/bin/emacsclient -c "$@"
    fi
  '';
in {
  options.hive.doom = {
    enable = lib.mkEnableOption "Enable Doom Emacs";
    asDefaultEditor = lib.mkEnableOption "set the EDITOR variable to use the current emacs server (graphical/non-graphical)";
    enableCopilot = lib.mkEnableOption "Enable Copilot in Doom Emacs";
    enableTidal = lib.mkEnableOption "Enable TidalCycles";
    withLatexPkgs = lib.mkEnableOption "Enable LaTeX packages in doom path";
    withShellPkgs = lib.mkEnableOption "Enable shell packages in doom path";
    withNixPkgs = lib.mkEnableOption "Enable LaTeX packages in doom path";
    withCXXPkgs = lib.mkEnableOption "Enable CXX packages in doom path";
    withPythonPkgs = lib.mkEnableOption "Enable python packages in doom path";
    overrideLatexPkgs = lib.mkOption {
      type = lib.types.functionTo (lib.types.listOf lib.types.package);
      default = pkgs: pkgs;
      example = ''
        prev: with pkgs; [
          texlive.combined.scheme-full
        ]
      '';
      description = "Override the default LaTeX packages in the doom path.";
    };
    overrideShellPkgs = lib.mkOption {
      type = lib.types.functionTo (lib.types.listOf lib.types.package);
      default = pkgs: pkgs;
      example = ''
        prev: with pkgs; [
          shellcheck
        ]
      '';
      description = "Override the default shell packages in the doom path.";
    };
    overrideNixPkgs = lib.mkOption {
      type = lib.types.functionTo (lib.types.listOf lib.types.package);
      default = pkgs: pkgs;
      example = ''
        prev: with pkgs; [
          nixpkgs-fmt
        ]
      '';
      description = "Override the default Nix packages in the doom path.";
    };
    overrideCXXPkgs = lib.mkOption {
      type = lib.types.functionTo (lib.types.listOf lib.types.package);
      default = pkgs: pkgs;
      example = ''
        prev: with pkgs; [
          openmp
        ]
      '';
      description = "Override the default C++ packages in the doom path.";
    };
    overridePythonPkgs = lib.mkOption {
      type = lib.types.functionTo (lib.types.listOf lib.types.package);
      default = pkgs: pkgs;
      example = ''
        prev: with pkgs; [
          pythonPackages.black
        ]
      '';
      description = "Override the default Python packages in the doom path.";
    };
  };

  config = lib.mkIf cfg.enable {
    fonts.fontconfig.enable = true;

    programs.emacs = {
      enable = true;
      package = wrapped-emacs;
    };

    home = {
      sessionPath = ["${config.xdg.configHome}/doom-emacs/bin"];
      sessionVariables =
        {
          DOOMDIR = "${config.xdg.configHome}/doom-config";
          DOOMLOCALDIR = "${config.xdg.configHome}/doom-local";
        }
        // lib.optionalAttrs cfg.asDefaultEditor {
          EDITOR = "${doom-open.name}";
        };
      packages = doom-pkgs ++ lib.optional cfg.asDefaultEditor doom-open;
    };

    systemd.user.services.doom-emacs-server = {
      Unit = {
        Description = "Doom Emacs Server";
      };
      Service = {
        ExecStart = "${wrapped-emacs}/bin/emacs --fg-daemon=${doom-socket-name}";
        SuccessExitStatus = 15;
      };
      Install = {
        WantedBy = []; # Lazy start by socket
      };
    };
    systemd.user.sockets.doom-emacs-server = {
      Socket = {
        ListenStream = "/run/user/%U/emacs/${doom-socket-name}";
        DirectoryMode = "0700";
      };
      Install = {
        WantedBy = ["sockets.target"];
      };
    };

    xdg = {
      enable = true;
      configFile = {
        "doom-config/splash.png" = {
          source = ./static/splash.png;
        };
        "doom-config/config.el" = {
          source = ./static/config.el;
        };
        "doom-config/config.d/copilot.el" = {
          enable = cfg.enableCopilot;
          source = ./static/config.d/copilot.el;
        };
        "doom-config/packages/treesit-docgen.el" = {
          source = ./static/packages/treesit-docgen.el;
        };
        "doom-config/init.el" = {
          source = ./static/init.el;
          onChange = "${doom-setup} sync --force -e";
        };
        "doom-config/packages.el" = {
          source = ./static/packages.el;
          onChange = "${doom-setup} sync --force -u -e";
        };
        "doom-config/packages.d/copilot.el" = {
          enable = cfg.enableCopilot;
          source = ./static/packages.d/copilot.el;
          onChange = "${doom-setup} sync --force -u -e";
        };
        "doom-config/packages.d/tidal.el" = {
          enable = cfg.enableTidal;
          source = ./static/packages.d/tidal.el;
          onChange = "${doom-setup} sync --force -u -e";
        };
        "doom-emacs" = {
          source = builtins.fetchGit {
            url = "https://github.com/doomemacs/doomemacs";
            rev = "c27621a777c11354a4913c7eb455db3766984709";
          };
          onChange = "${doom-setup} --force sync -u -e";
        };
      };
      desktopEntries = {
        emacs = {
          name = "Doom Emacs";
          genericName = "Text Editor";
          icon = ./static/icon.png;
          exec = "${wrapped-emacs}/bin/emacs %F";
          terminal = false;
          categories = ["Application" "Development" "TextEditor"];
          mimeType = ["text/*"];
          settings = {
            StartupWMClass = "Doom Emacs";
          };
        };
        emacsclient = {
          name = "Doom Emacs (Client)";
          genericName = "Text Editor";
          icon = ./static/icon.png;
          exec = ''
            sh -c "if [ -n \\"\\$*\\" ]; then exec ${wrapped-emacs}/bin/emacsclient --alternate-editor= --display=\\"\\$DISPLAY\\" \\"\\$@\\"; else exec emacsclient --alternate-editor= --create-frame; fi" sh %F
          '';
          terminal = false;
          categories = ["Application" "Development" "TextEditor"];
          mimeType = ["text/*"];
          settings = {
            StartupWMClass = "Doom Emacs";
          };
        };
      };
    };
  };
}
