{ self, inputs, ... }:
let
  # Keep defaults in this let — a bare niri-settings.nix next to this file would get picked up by import-tree.
  niriBaseSettings =
    pkgs:
    {
      input.keyboard = {
        xkb.layout = "ca";
        xkb.variant = "";
      };
      input."focus-follows-mouse" = _: {
        props."max-scroll-amount" = "45%";
        content = { };
      };
      input."warp-mouse-to-focus" = _: { };
      layout.gaps = 5;

      window-rules = [
        {
          matches = [
            {
              app-id = "^$";
              title = "^$";
            }
          ];
          open-floating = true;
          open-focused = false;
        }
      ];
#TODO[epic=Binds] Go over binds again
      binds = {
        "Mod+T"."spawn-sh" = "${pkgs.lib.getExe pkgs.kitty} -e fish"; #TODO[epic=Binds] This should only be set if having kitty
        "Mod+Control+T"."spawn-sh" = "konsole"; #TODO[epic=Binds] This should only be set if having konsole
        "Mod+D"."spawn-sh" = "rofi -show drun"; #TODO[epic=Binds] This should only be set if having rofi
        "Mod+Space"."spawn-sh" = "dms ipc call spotlight toggle"; #TODO[epic=Binds] This should only be set if having dms
        "Mod+E"."spawn-sh" = "dolphin"; #TODO[epic=Binds] This should only be set if having dolphin
        "Mod+Control+O"."spawn-sh" = "rofi -show window"; #TODO[epic=Binds] This should only be set if having rofi
"Mod+V"."spawn-sh" = "dms ipc call clipboard toggle"; #TODO[epic=Binds] This should only be set if having dms
"Mod+N"."spawn-sh" = "dms ipc call notepad toggle"; #TODO[epic=Binds] This should only be set if having dms
"Mod+Shift+N"."spawn-sh" = "dms ipc call notifications toggle"; #TODO[epic=Binds] This should only be set if having dms
"Mod+M"."spawn-sh" = "dms ipc call processlist toggle"; #TODO[epic=Binds] This should only be set if having dms
"Mod+L"."spawn-sh" = "dms ipc call lock lock"; #TODO[epic=Binds] This should only be set if having dms

        "Mod+Q"."close-window" = _: { };
        "Mod+F"."maximize-column" = _: { };
        "Mod+Shift+F"."fullscreen-window" = _: { };
        "Mod+O"."toggle-overview" = _: { };
        "Mod+Shift+NumberSign"."show-hotkey-overlay" = _: { };
        "Mod+Shift+E".quit = _: { };

        "Mod+Left"."focus-column-or-monitor-left" = _: { };
        "Mod+Down"."focus-window-or-monitor-down" = _: { };
        "Mod+Up"."focus-window-or-monitor-up" = _: { };
        "Mod+Right"."focus-column-or-monitor-right" = _: { };

        "Mod+Shift+WheelScrollDown"."focus-workspace-down" = _: { };
        "Mod+Shift+WheelScrollUp"."focus-workspace-up" = _: { };

        "Mod+WheelScrollDown"."focus-column-or-monitor-right" = _: { };
        "Mod+WheelScrollUp"."focus-column-or-monitor-left" = _: { };

        "Mod+Shift+Left"."move-column-left-or-to-monitor-left" = _: { };
        "Mod+Shift+Down"."move-window-down" = _: { };
        "Mod+Shift+Up"."move-window-up" = _: { };
        "Mod+Shift+Right"."move-column-right-or-to-monitor-right" = _: { };
        "Mod+Page_Up"."focus-workspace-up" = _: { };
        "Mod+Page_Down"."focus-workspace-down" = _: { };
        "Mod+Shift+Page_Up"."move-column-to-workspace-up" = _: { };
        "Mod+Shift+Page_Down"."move-column-to-workspace-down" = _: { };
        "Mod+R"."switch-preset-column-width" = _: { };
        "Mod+BracketLeft"."consume-or-expel-window-left" = _: { };
        "Mod+BracketRight"."consume-or-expel-window-right" = _: { };
        "Mod+Comma"."consume-window-into-column" = _: { };
        "Mod+Period"."expel-window-from-column" = _: { };
        "Mod+Alt+Space"."toggle-window-floating" = _: { };
        #"Mod+Shift+V"."switch-focus-between-floating-and-tiling" = _: { }; #TODO[epic=Binds] Find free bind that is not in the way and not overcomplicated to remember

        "Mod+1"."focus-workspace" = 1;
        "Mod+2"."focus-workspace" = 2;
        "Mod+3"."focus-workspace" = 3;
        "Mod+4"."focus-workspace" = 4;
        "Mod+5"."focus-workspace" = 5;
        "Mod+6"."focus-workspace" = 6;
        "Mod+7"."focus-workspace" = 7;
        "Mod+8"."focus-workspace" = 8;
        "Mod+9"."focus-workspace" = 9;
        "Mod+Ctrl+1"."move-column-to-workspace" = 1;
        "Mod+Ctrl+2"."move-column-to-workspace" = 2;
        "Mod+Ctrl+3"."move-column-to-workspace" = 3;
        "Mod+Ctrl+4"."move-column-to-workspace" = 4;
        "Mod+Ctrl+5"."move-column-to-workspace" = 5;
        "Mod+Ctrl+6"."move-column-to-workspace" = 6;
        "Mod+Ctrl+7"."move-column-to-workspace" = 7;
        "Mod+Ctrl+8"."move-column-to-workspace" = 8;
        "Mod+Ctrl+9"."move-column-to-workspace" = 9;

        "XF86AudioRaiseVolume".spawn = [
          "wpctl"
          "set-volume"
          "@DEFAULT_AUDIO_SINK@"
          "0.05+"
        ];
        "XF86AudioLowerVolume".spawn = [
          "wpctl"
          "set-volume"
          "@DEFAULT_AUDIO_SINK@"
          "0.05-"
        ];
        "XF86AudioMute".spawn = [
          "wpctl"
          "set-mute"
          "@DEFAULT_AUDIO_SINK@"
          "toggle"
        ];

        # Backlight: relies on `pkgs.brightnessctl` being on PATH (provided by `desktopGui` when
        # any GUI session is enabled) and the user being in the `video` group (catalog default).
        "XF86MonBrightnessUp".spawn = [ "brightnessctl" "set" "+5%" ];
        "XF86MonBrightnessDown".spawn = [ "brightnessctl" "set" "5%-" ];

        Print.screenshot = _: { };
        "Ctrl+Print"."screenshot-screen" = _: { };
        "Alt+Print"."screenshot-window" = _: { };
      };
    };

  keyringNiriStartupKdl = ''
    spawn-at-startup "dbus-update-activation-environment" "--systemd" "--all"
  '';

  mergeNiriSettings =
    pkgs: niriCfg: keyringEnable:
    let
      lib = pkgs.lib;
      pi5 = self.lib.pi5NiriKdl;
      rpi5Extra = lib.optionalString (niriCfg.raspberryPi5DrmWorkaround or false) pi5.drmExtraConfig;
      base = niriBaseSettings pkgs;
      userExtra = niriCfg.extraSettings or { };
      keyringExtra = lib.optionalString keyringEnable keyringNiriStartupKdl;
      extraConfigMerged = keyringExtra + rpi5Extra + (userExtra.extraConfig or "");
      windowRules = (base.window-rules or [ ]) ++ (userExtra.window-rules or [ ]);
    in
    lib.recursiveUpdate base (
      lib.removeAttrs userExtra [ "window-rules" "extraConfig" ]
      // lib.optionalAttrs (windowRules != [ ]) {
        window-rules = windowRules;
      }
      // lib.optionalAttrs (rpi5Extra != "" || (userExtra.extraConfig or "") != "") {
        extraConfig = extraConfigMerged;
      }
    );
in
{
  flake.homeManagerModules.desktopNiri =
    { lib, pkgs, osConfig ? { }, ... }:
    let
      niriOs = osConfig.chiasson.desktop.niri or { };
      niriEnabled = osConfig.chiasson.desktop.niri.enable or false;
      keyringEnabled = osConfig.chiasson.desktop.keyring.enable or false;
      mergedSettings = mergeNiriSettings pkgs niriOs keyringEnabled;
      niriConfigPkg = inputs.wrapper-modules.wrappers.niri.wrap {
        inherit pkgs;
        settings = mergedSettings;
      };
    in
    {
      config = lib.mkIf niriEnabled {
        xdg.configFile."niri/config.kdl".source = "${niriConfigPkg}/niri-config.kdl";
      };
    };

  flake.nixosModules.desktopNiri =
    { config, options, lib, pkgs, self, ... }:
    let
      cfg = config.chiasson.desktop;
      hmAvailable = lib.hasAttrByPath [ "home-manager" "sharedModules" ] options;
    in
    {
      options.chiasson.desktop.niri = {
        enable = lib.mkOption {
          type = lib.types.bool;
          default = false;
          description = "Niri compositor session + NixOS packages.";
        };

        raspberryPi5DrmWorkaround = lib.mkEnableOption ''
          Pi 5 + RP1 DSI: Niri DRM debug rules (renderD128, ignore card1/2) + matching DankGreeter niri config.
          Opt-in only — HDMI-only / other Pi setups do not need this.
        '';

        extraSettings = lib.mkOption {
          type = lib.types.attrs;
          default = { };
          description = ''
            Merged into shared defaults → `config.kdl` via wrapper-modules. Put raw KDL in `extraConfig`.
          '';
        };
      };

      config = lib.mkMerge [
        {
          assertions = [
            {
              assertion = !cfg.niri.raspberryPi5DrmWorkaround || cfg.niri.enable;
              message = "chiasson.desktop.niri.raspberryPi5DrmWorkaround requires chiasson.desktop.niri.enable.";
            }
          ];
        }
        (lib.mkIf cfg.niri.enable {
          programs.niri.enable = true;
          programs.niri.package = pkgs.niri;
          programs.xwayland.enable = true;
          xdg.portal.extraPortals = [ pkgs.xdg-desktop-portal-gnome ];
          # Niri resolves `xwayland-satellite` from PATH to provide XWayland + `$DISPLAY` for X11
          # clients (Steam, etc.). See https://github.com/YaLTeR/niri/issues/452
          environment.systemPackages = [ pkgs.xwayland-satellite ];
        })
        (lib.mkIf (cfg.niri.enable && hmAvailable) {
          "home-manager".sharedModules = [ self.homeManagerModules.desktopNiri ];
        })
      ];
    };
}
