{
  lib,
  pkgs,
  config,
  ...
}: let
  inherit (lib) mkEnableOption mkOption mkIf types;
  inherit (builtins) listToAttrs;
  cfg = config.programs.murex;
in {
  options.programs.murex = {
    enable = mkEnableOption "murex shell";
    managePlugins = mkEnableOption "plugin management";
    direnv = mkEnableOption "direnv integration";
    plugins = mkOption {
      type = with types; listOf package;
      default = [];
    };
    profile = mkOption {
      type = types.str;
      default = "";
    };
    preload = mkOption {
      type = types.str;
      default = "";
    };
    useXdgConfig = mkEnableOption "override MUREX_{PRELOAD,MODULES,PROFILE} env vars to conform to XDG_CONFIG_HOME";
  };
  config = mkIf cfg.enable {
    home.file = let
      plugins = listToAttrs (map (plugin: {
          name = ".murex_modules/${plugin.pname}";
          value = {
            recursive = true;
            source = plugin;
          };
        })
        cfg.plugins);
    in
      lib.mergeAttrs plugins {
        ".murex_preload" = {
          text = cfg.preload;
          executable = true;
          enable = cfg.preload != "";
        };
        ".murex_profile" = {
          text =
            cfg.profile
            + (
              if cfg.direnv
              then ''
                direnv hook murex -> source
              ''
              else ""
            );
          executable = true;
          enable = cfg.direnv || cfg.profile != "";
        };
        ".murex_modules/packages.json" = {
          text = builtins.toJSON (map (plugin: {
              Protocol = "nix";
              URI = "nix://managed.git";
              Package = plugin.pname;
            })
            cfg.plugins);
          enable = cfg.managePlugins && (cfg.plugins != []);
        };
      };
    home.sessionVariables =
      mkIf
      cfg.useXdgConfig {
        MUREX_PRELOAD = "$XDG_CONFIG_HOME/murex/";
        MUREX_MODULES = "$XDG_CONFIG_HOME/murex/";
        MUREX_PROFILE = "$XDG_CONFIG_HOME/murex/";
      };
  };
}
