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

with lib;

let
  cfg = config.home.roles.emacs;

  doomEmacs = pkgs.fetchFromGitHub {
    owner = "doomemacs";
    repo = "doomemacs";
    rev = "38d94da67dc84897a4318714dcc48494c016d8c4";
    sha256 = "sha256-Uc6qONH3jjUVDgW+pPBCGC7mh88ZY05u1y37fQrsxq0=";
  };

  # Shared emacs packages
  emacsPackages = epkgs: [
    epkgs.vterm
    epkgs.treesit-grammars.with-all-grammars
  ];

  # Default emacs configuration with vterm support
  defaultEmacsPackage =
    if pkgs.stdenv.isDarwin
    then pkgs.emacs-macport.pkgs.withPackages emacsPackages
    else pkgs.emacs.pkgs.withPackages emacsPackages;
in
{
  options.home.roles.emacs = {
    enable = mkEnableOption "Doom Emacs with vterm and tree-sitter support";
  };

  config = mkIf cfg.enable {
    home.packages = [
      pkgs.emacs-all-the-icons-fonts
      pkgs.fira-code
      pkgs.fontconfig
      pkgs.graphviz
      pkgs.isort
      pkgs.nerd-fonts.fira-code
      pkgs.nerd-fonts.droid-sans-mono
      pkgs.nil # nix lsp language server
      pkgs.nixfmt-rfc-style
      (pkgs.ripgrep.override {withPCRE2 = true;})
      pkgs.pipenv
      pkgs.poetry
      pkgs.python3
    ];

    programs.emacs = {
      enable = true;
      package = defaultEmacsPackage;
    };

    fonts.fontconfig.enable = true;

    # Mount emacs and tree-sitter grammars from nix store
    home.file = {
      "${config.xdg.configHome}/emacs".source = doomEmacs;
    };

    home.sessionPath = [
      "${config.xdg.configHome}/emacs/bin"
    ];

    home.sessionVariables = {
      DOOMDIR = "${config.xdg.configHome}/doom";
      DOOMLOCALDIR = "${config.xdg.dataHome}/doom";
    };

    # TODO: Use mkOutOfStoreSymlink instead?
    home.activation.doomConfig = lib.hm.dag.entryAfter ["writeBoundary"] ''
      # Always remove and recreate the symlink to ensure it points to the source directory
      rm -rf "${config.xdg.configHome}/doom"
      ln -sf "${config.home.homeDirectory}/nixos-configs/home/roles/emacs/doom" "${config.xdg.configHome}/doom"
    '';
  };
}
