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

let cfg = config.sydnix.users.crumb.emacs;
in {
  options.sydnix.users.crumb.emacs.enable =
    lib.mkEnableOption ''Emacs, à la crumb'';
  config = lib.mkIf cfg.enable
    (let
      emacsBasePackage = pkgs.emacs-pgtk;
      # Hard-coded path. }:\
      emacsConfigDir =
        "/persist/dots/modules/home/users/${config.home.username}/emacs";

      # Create a new instance of nixpkgs with emacs-overlay applied. This is a
      # little unorthodox, but we do it
      #   1. for the sake of organisation — For pure aesthetics and a clean
      #      codebase, I want everything Emacs to stay in this file;
      #   2. and, there's simply no need to leak emacs-overlay's packages into the
      #      global nixpkgs instance when nothing else is using it!
      # pkgs' = import inputs.nixpkgs {
      #   system = args.system;
      #   overlays = [ inputs.emacs-overlay.overlays.emacs ];
      # };

      emacsDataDir = "${config.xdg.dataHome}/emacs";
      emacsCacheDir = "${config.xdg.cacheHome}/emacs";
      straightBaseDir = "${emacsDataDir}/straight";

      fontPackages = [
        pkgs.julia-mono
        pkgs.nerd-fonts.victor-mono
        pkgs.ibm-plex
      ];

      my-aspell = pkgs.aspellWithDicts
        (dicts: with dicts; [
          en en-computers en-science
        ]);

      my-tex = pkgs.texlive.combine {
        inherit (pkgs.texlive)
          scheme-basic # Set of common packages.
          fontspec
          dvisvgm dvipng wrapfig # For Org-mode previews/export.
          amsmath # Essential for mathematics.
          ulem hyperref
          capt-of
          pgf # Includes TikZ.
          tikz-cd # Commutative diagrams w/ TikZ.
          quiver # Commutative diagrams w/ TikZ & q.uiver.app.
          metafont
          preview # For new-gen org-latex-preview.
          mylatexformat # For new-gen org-latex-preview.
          collection-fontsrecommended # Essential fonts.
          etoolbox # For Org-mode exports.
          ;
      };

      my-emacs =
        let ewp = (pkgs.emacsPackagesFor emacsBasePackage).emacsWithPackages
          (epkgs: with epkgs; [
            jinx
            pdf-tools
            treesit-grammars.with-all-grammars
          ]);
        in pkgs.symlinkJoin {
          name = "sydmacs";
          paths = [ ewp ];
          nativeBuildInputs = [ pkgs.makeWrapper ];
          postBuild =
            let runtime-binaries = [
              my-aspell
              pkgs.git # Dependency of Straight.el.
              pkgs.ghostscript # For TeX.
              my-tex
              pkgs.unzip # For jump-to-source.
            ];
            in ''
              find "$out/bin" -name emacs -or -name "emacs-*" \
                | while IFS= read -r emacs; do
                  wrapProgram "$emacs" \
                    --add-flags "--init-directory \"${emacsConfigDir}\"" \
                    --set EMACS_STRAIGHT_BASE_DIR "${straightBaseDir}" \
                    --set EMACS_CACHE_DIR "${emacsCacheDir}" \
                    --set EMACS_DATA_DIR "${emacsDataDir}" \
                    --set ASPELL_CONF "dict-dir ${my-aspell}/lib/aspell" \
                    --prefix PATH : "${lib.makeBinPath runtime-binaries}"
                done
          '';
          meta = emacsBasePackage.meta;
          version = emacsBasePackage.version;
        };

      emacsclient-or-emacs = pkgs.writeShellScriptBin "emacsclient-or-emacs" ''
        emacsclient --alternate-editor=${config.programs.emacs.finalPackage}/bin/emacs "$@"
      '';
    in {
      programs.emacs = {
        enable = true;
        package = my-emacs;
      };

      sydnix.impermanence.cache.directories = 
        # Impermanence expects the path to be relative to ~.
        map (lib.removePrefix config.home.homeDirectory) [
          straightBaseDir
          emacsCacheDir
          emacsDataDir
        ];

      # Set emacsclient as the default editor for the time being.
      home.sessionVariables =
        let e = "${emacsclient-or-emacs}/bin/emacsclient-or-emacs";
        in {
          "EDITOR" = e;
          "VISUAL" = e;
        };

      home.file =
        let default =
              lib.removePrefix "${config.home.homeDirectory}/"
                "${straightBaseDir}/straight/versions/default.el";
        in {
          ${default}.source =
            config.lib.file.mkOutOfStoreSymlink
              "${emacsConfigDir}/straight-lockfile.el";
        };

      home.packages = [
        emacsclient-or-emacs
        (pkgs.writeShellScriptBin "emacs-fuckyou" ''
          ${my-emacs}/bin/emacs "$@"
        '')
      ] ++ fontPackages;

      # There's probably a better place to put this, but the current setup demands
      # Fontconfig for Emacs to find my fonts.
      fonts.fontconfig.enable = true;

      # TODO: Make sure this is using the right package for Emacs...
      services.emacs = {
        enable = true;
        # Generate a desktop entry for emacsclient.
        client.enable = true;
      };

      # We do this ourselves.
      stylix.targets.emacs.enable = false;

      home.shellAliases = {
        e = "emacsclient-or-emacs";
        ec = "emacsclient";
        em = "emacs";
      };

      # Mark Emacs as a valid PDF reader.
      xdg.mimeApps.associations.added = {
        "application/pdf" = [
          "emacsclient.desktop"
          "emacs.desktop"
        ];
      };
    });
}
