{inputs, pkgs, lib, config, ...}:
let
  cfg = config.nix-config.hypr;
in
{
  config = {
    wayland.windowManager.hyprland = {
      enable = true;
      systemd.enable = true;
      settings = {
        "$mod" = "SUPER";

        # Global bindings
        bind = [
          # Launch applications
          "$mod, space, exec, ${lib.getExe config.nix-config.launcher}"
          "$mod, return, exec, kitty"
          "$mod, b, exec, ${cfg.browser}"
          "$mod, s, exec, ${cfg.ide}"
          "$mod, e, exec, ${lib.getExe pkgs.nautilus}"

          # Lock screen
          "$mod, l, exec, loginctl lock-session"

          # Clipboard management
          "$mod, V, exec, cliphist list | ${lib.getExe config.nix-config.launcher} --dmenu | cliphist decode | wl-copy"

          # Close window
          "$mod, Q, killactive,"
          # Force close window
          "$mod+Shift, Q, forcekillactive,"

          # Toggle Floating and reduce size
          "$mod, f, togglefloating,"
          "$mod, f, resizeactive, 50% 50%,"

          # "$mod, P, pseudo, " # dwindle
          # "$mod, J, togglesplit, " # dwindle
          # Toggle fullscreen
          "$mod+Shift, f, fullscreen,"

          # Alt-tab alternative
          "$mod, Tab, cyclenext,"
          "$mod, Tab, bringactivetotop,"

          # Move the window
          "$mod+Shift, left, movewindow, l"
          "$mod+Shift, right, movewindow, r"
          "$mod+Shift, up, movewindow, u"
          "$mod+Shift, down, movewindow, d"

          # Move window to workspace
          "$mod+Ctrl, left, movetoworkspace, -1"
          "$mod+Ctrl, right, movetoworkspace, +1"

          # Switch workspace
          "$mod, left, workspace, prev"
          "$mod, right, workspace, next"
          "$mod, mouse_down, workspace, prev"
          "$mod, mouse_up, workspace, next"


          # move to scratch workspace
          "$mod+Ctrl, up, movetoworkspace, special:magic"
          "$mod+Ctrl, down, movetoworkspace, prev"

          # switch to scratch workspace
          "$mod, up, togglespecialworkspace, magic"
          "$mod, down, togglespecialworkspace, magic"


          # Screenshot
          "$mod, Print, exec, hyprshot -m region -o ~/Pictures/Screenshots"
          "$mod+Shift, Print, exec, hyprshot -m window -o ~/Pictures/Screenshots"
          # # somehow logitech calls this SUPER_L but we refer to it by its code
          "SUPER_L&Shift_L, S, exec, hyprshot -m region -o ~/Pictures/Screenshots"
          "Shift&SUPER_L&Shift_L, S, exec, hyprshot -m window -o ~/Pictures/Screenshots"
          # when there is a dedicated screenshot button
          ", XF86Cut, exec, hyprshot -m region -o ~/Pictures/Screenshots"
          "Shift, XF86Cut, exec, hyprshot -m window -o ~/Pictures/Screenshots"

          # Power menu
          ", XF86PowerOff, exec, ${lib.getExe config.nix-config.powerMenu}"

          # Other pickers using the same launcher
          "$mod+Ctrl, space, exec, ${lib.getExe config.nix-config.filePicker}"
          "$mod, period, exec, ${lib.getExe config.nix-config.emojiPicker}"
        ];

        # repeatable bindings
        binde = [
          # Fn keys
          ", XF86MonBrightnessDown, exec, brightnessctl set 5%-"
          ", XF86MonBrightnessUp, exec, brightnessctl set +5%"
          ", XF86AudioRaiseVolume, exec, wpctl set-volume -l 1 @DEFAULT_AUDIO_SINK@ 5%+"
          ", XF86AudioLowerVolume, exec, wpctl set-volume -l 1 @DEFAULT_AUDIO_SINK@ 5%-"
          ", XF86AudioMute, exec, wpctl set-mute @DEFAULT_AUDIO_SINK@ toggle"

          # Reshape the window in focus
          "$mod, MINUS, resizeactive, -2% -2%"
          "$mod, KP_Subtract, resizeactive, -2% -2%"
          "$mod, PLUS, resizeactive, 2% 2%"
          "$mod, KP_Add, resizeactive, 2% 2%"
        ];

        # lock-screen bindings
        bindl = [
          ", XF86PowerOff, exec, hyprctl dispatch dpms on eDP-1"
          ## depending on the setup we expect different behaviors when closing the lid:
          # either sleep & lock screen OR switch to clamshell mode
          # through the `services.logind.lidSwitch` and `services.logind.lidSwitchDocked` we can differentiate both cases
          # when not docked, the system is put to sleep and the screen is implicitly locked as per the hypridle configuration
          # when docked, the lid switch is ignored by logind and needs to be handled manually, see below:


          # if an additional monitor is detected, simply deactivate the internal screen and continue working on the external monitor
          ", switch:on:Lid Switch, exec, hyprctl keyword monitor 'eDP-1,disable"
          ## on reopening the lid, turn the internal screen back on
          ", switch:off:Lid Switch, exec, hyprctl dispatch dpms on eDP-1"
          # we need to reload the monitor configuration so that the internal screen is turned back on
          ", switch:off:Lid Switch, exec, hyprctl reload"
        ];

        # bindr = [
        #     # Overview
        #   "$mod, , overview:toggle"
        # ];

        bindm = [
          # move the window using left click
          "$mod, mouse:272, movewindow"
          # resize the window using right click
          "$mod, mouse:273, resizewindow"
        ];



      };

      extraConfig = ''
        bind= , XF86AudioMicMute, submap, player_submap

        submap=player_submap
        bind=, XF86AudioRaiseVolume, exec, notify-send previous; hyprctl dispatch submap reset
        bind=, XF86AudioLowerVolume, exec, notify-send next; hyprctl dispatch submap reset
        bind=, XF86AudioMicMute, exec, notify-send pause; hyprctl dispatch submap reset
        submap=reset
      '';

    };
  };
}
