{ inputs, pkgs, ... }:
let
  playerctl = "${pkgs.playerctl}/bin/playerctl";
  wl-paste = "${pkgs.wl-clipboard}/bin/wl-paste";
  nautilus = "${pkgs.gnome.nautilus}/bin/nautilus";
  gnome-calendar = "${pkgs.gnome.gnome-calendar}/bin/gnome-calendar";
  waybar = "${inputs.waybar.packages.${pkgs.system}.waybar}/bin/waybar";
  wpctl = "${pkgs.wireplumber}/bin/wpctl";
  alacritty = "${pkgs.alacritty}/bin/alacritty";
  swaylock = "${pkgs.swaylock-fancy}/bin/swaylock-fancy";
  rofi = "${pkgs.rofi}/bin/rofi";
  jq = "${pkgs.jq}/bin/jq";
  rofi-ykman = pkgs.writeShellScriptBin "rofi-ykman" ''
    accounts=$(${pkgs.yubikey-manager}/bin/ykman oath accounts list)
    prompt="YubiKey OATH"
    account=$(echo "''${accounts/, TOTP/\n}" | awk '{ print $0 "\0icon\x1fyubioath"; }' | ${rofi} -dmenu -i -p "$prompt" ''${shortcuts[@]})
    code=$(${pkgs.yubikey-manager}/bin/ykman oath accounts code "$account")
    IFS=', ' read -r -a code <<< "$code"
    echo -n "''${code[-1]}" | ${pkgs.wl-clipboard}/bin/wl-copy;
  '';

  workspace_command_prefix = "split-";
  hyprland_plugins = [ inputs.split-monitor-workspaces.packages.${pkgs.system}.split-monitor-workspaces ];

  # Disable split-monitor-workspaces
  # workspace_command_prefix = "";
  # hyprland_plugins = [];

  launch_alacritty = pkgs.writeShellScriptBin "launch_alacritty" ''
    RUNNING_WAYPIPE=false
    SSH_CLIENT=""
    CHILD_PID=$(pgrep -P "$1")

    if [ "$GRAND_CHILD_PID" != "" ]; then
        GRAND_CHILD_NAME=$(ps -p "$GRAND_CHILD_PID" -o comm=)
        if [ "$GRAND_CHILD_NAME" == "ssh" ]; then
            CHILD_PID=$GRAND_CHILD_PID
            SSH_CLIENT=$(ps -p "$CHILD_PID" -o args --no-headers | awk '{ print $2 }')
        fi
        if [ "$GRAND_CHILD_NAME" == "waypipe" ]; then
            RUNNING_WAYPIPE=true
            CHILD_PID=$(pgrep -P "$GRAND_CHILD_PID")
            SSH_CLIENT=$(ps -p "$GRAND_CHILD_PID" -o args --no-headers | awk '{ print $4 }')
        fi
    fi

    if [ $RUNNING_WAYPIPE == true ]; then
        PREVIOUS_SESSION_ID=$(grep -z "SSH_SESSION_ID" "/proc/$CHILD_PID/environ" | xargs -0 -n 1 | grep -oP "[0-9]*")
        SSH_SESSION_ID=$RANDOM
        ${alacritty} -e zsh -c "SSH_SESSION_ID=$SSH_SESSION_ID waypipe ssh -t \"$SSH_CLIENT\" env SSH_SESSION_ID=\"$SSH_SESSION_ID\" PREVIOUS_SESSION_ID=\"$PREVIOUS_SESSION_ID\" \"zsh --login\""
    else
        if [ "$(ps -p "$1" -o comm=)" == "alacritty" ]; then
            CWD=$(readlink -e /proc/"$CHILD_PID"/cwd)
            if [ "$CWD" != "" ]; then
                ${alacritty} --working-directory "$CWD"
            else
                ${alacritty}
            fi
        else
            ${alacritty}
        fi
    fi
  '';
in {
  home.packages = [
    pkgs.wl-clipboard
    pkgs.jq
  ];

  services.hyprpaper = {
    enable = true;
    settings = {
      ipc = "on";
      splash = false;
      preload = [ "${./files/wallpaper.png}" ];
      wallpaper = [
        # Fill in by host-specific config!
        # "Display,${./files/wallpaper.png}"
      ];
    };
  };

  services.dunst = {
    enable = true;
    settings = {
      global = {
        frame_color = "#00000000";
        separator_color = "frame";
        background = "#24273A";
        foreground = "#ffffff";
        font = "Ubuntu 10.5";
        width = "(0, 600)";
        padding = 15;
        origin = "top-right";
        offset = "10x10";
        horizontal_padding = 20;
        gap_size = 15;
      };
    };
  };
  wayland.windowManager.hyprland = {
    enable = true;
    systemd.variables = [ "--all" ];
    systemd.enable = true;
    systemd.enableXdgAutostart = true;
    xwayland.enable = true;
    package = inputs.hyprland.packages.${pkgs.system}.hyprland;
    plugins = [ ] ++ hyprland_plugins;
    settings = {
      "$mainMod" = "SUPER";
      exec-once = [
        "hyprpaper"
        "${waybar}"
        "${wl-paste} --type text --watch cliphist store"
        "${wl-paste} --type image --watch cliphist store"
        "${pkgs.mate.mate-polkit}/bin/polkit-mate"
      ];
      env = [
        "WLR_NO_HARDWARE_CURSORS,1"
        "TERMINAL,${alacritty}"
        "WLR_RENDERER_ALLOW_SOFTWARE,1"
      ];
      debug = { disable_logs = false; };
      windowrulev2 = [
        "float, title:^(rofi)(.*)$"
        "center, title:^(rofi)(.*)$"
        "noborder, title:^(rofi)(.*)$"
        "stayfocused, title:^()$,class:^(steam)$"
        "minsize 1 1, title:^()$,class:^(steam)$"
        "stayfocused, title:^()$,class:^(steam)$"
      ];
      windowrule = [ "noanim,waybar" ];
      general = {
        gaps_in = 1;
        gaps_out = pkgs.lib.mkDefault 5;
        border_size = 2;
        "col.active_border" = "rgba(002f5fee)";
        "col.inactive_border" = "rgba(ffffff00)";
        layout = "dwindle";
      };
      input = {
        kb_layout = "us";
        follow_mouse = 1;
        kb_options = pkgs.lib.mkDefault "compose:rctrl";
        numlock_by_default = true;
      };
      binds = { scroll_event_delay = 1; };
      xwayland = { force_zero_scaling = true; };
      misc = { disable_hyprland_logo = 1; };
      decoration = {
        rounding = 1;
        blur = { enabled = false; };
      };
      animations = {
        enabled = "yes";
        bezier = "myBezier, 0.05, 0.9, 0.1, 1.05";
        animation = [
          "windows, 1, 2, myBezier"
          "windowsOut, 1, 2, default, popin 80%"
          "border, 1, 2, default"
          "borderangle, 1, 2, default"
          "fade, 1, 2, default"
          "workspaces, 1, 1, default"
        ];
      };
      dwindle = {
        preserve_split = "yes";
        no_gaps_when_only = 1;
        force_split = 2;
      };
      gestures = {
        workspace_swipe = "on";
        workspace_swipe_invert = false;
      };
      bindr = [
        "$mainMod, SUPER_L, exec, pkill rofi || ${rofi} -show drun"
        "$mainMod, SUPER_R, exec, pkill rofi || ${rofi} -show drun"
      ];
      bindm = [
        "$mainMod, mouse:272, movewindow"
        "$mainMod, mouse:273, resizewindow"
      ];
      bind = [
        "$mainMod, return, exec, ${launch_alacritty}/bin/launch_alacritty $(hyprctl activewindow -j | ${jq} .pid)"
        "$mainMod SHIFT, return, exec, ${alacritty}"
        "$mainMod, Q, killactive,"
        "$mainMod, A, exec, ${nautilus}"
        "$mainMod, S, exec, ${gnome-calendar}"
        "$mainMod, B, exec, MOZ_ENABLE_WAYLAND=1 firefox"
        "$mainMod, M, fullscreen, 1"
        "$mainMod, F11, fullscreen"
        "$mainMod, F, togglefloating,"
        "$mainMod, SPACE, togglesplit, # dwindle"
        "CONTROL_L ALT_L, L, exec, ${swaylock}"
        ''
          $mainMod, C, exec, cliphist list | awk '{print $0, "\0icon\x1fcom.github.davidmhewitt.clipped"; }' | ${rofi} -dmenu -display-columns 2 | cliphist decode | wl-copy''
        "$mainMod, Y, exec, ${rofi-ykman}/bin/rofi-ykman"
        "$mainMod, N, exec, ${./files/rofi-ssh.sh}"

        "$mainMod, Escape, exec, ${rofi} -show power-menu -modi power-menu:${
          ./files/rofi-power-menu.sh
        }"

        ",XF86MonBrightnessUp, exec, ${pkgs.brightnessctl}/bin/brightnessctl set +10%"
        ",XF86MonBrightnessDown, exec, ${pkgs.brightnessctl}/bin/brightnessctl set 10%-"
        ",XF86AudioRaiseVolume, exec, ${wpctl} set-volume @DEFAULT_AUDIO_SINK@ 10%+ --limit 1.0"
        ",XF86AudioLowerVolume, exec, ${wpctl} set-volume @DEFAULT_AUDIO_SINK@ 10%-"
        ",XF86AudioMicMute, exec, ${wpctl} set-mute @DEFAULT_AUDIO_SOURCE@ toggle"
        ",mouse_right, exec, ${wpctl} set-volume @DEFAULT_AUDIO_SINK@ 1%+ --limit 1.0"
        ",mouse_left, exec, ${wpctl} set-volume @DEFAULT_AUDIO_SINK@ 1%-"
        ",XF86AudioMute, exec, ${wpctl} set-mute @DEFAULT_AUDIO_SINK@ toggle"
        ",XF86AudioNext, exec, ${playerctl} next"
        ",XF86AudioPrev, exec, ${playerctl} previous"
        "$mainMod,XF86AudioMute, exec, ${playerctl} play-pause"
        "$mainMod,XF86AudioRaiseVolume, exec, ${playerctl} next"
        "$mainMod,XF86AudioLowerVolume, exec, ${playerctl} previous"
        '', Print, exec, ${pkgs.grim}/bin/grim -g "$(${pkgs.slurp}/bin/slurp -d)" - | wl-copy''

        "$mainMod, H, exec, ${./files/vim-hypr-nav.sh} l"
        "$mainMod, L, exec, ${./files/vim-hypr-nav.sh} r"
        "$mainMod, K, exec, ${./files/vim-hypr-nav.sh} u"
        "$mainMod, J, exec, ${./files/vim-hypr-nav.sh} d"
        "$mainMod CONTROL_L, H, swapwindow, l"
        "$mainMod CONTROL_L, L, swapwindow, r"
        "$mainMod CONTROL_L, K, swapwindow, u"
        "$mainMod CONTROL_L, J, swapwindow, d"
        "$mainMod SHIFT, H, movewindow, l"
        "$mainMod SHIFT, L, movewindow, r"
        "$mainMod SHIFT, K, movewindow, u"
        "$mainMod SHIFT, J, movewindow, d"
        "$mainMod ALT, L, resizeactive, 20 0"
        "$mainMod ALT, H, resizeactive, -20 0"
        "$mainMod ALT, K, resizeactive, 0 -20"
        "$mainMod ALT, J, resizeactive, 0 20"
        "$mainMod SHIFT, T, ${workspace_command_prefix}movetoworkspace, empty"
        "$mainMod, T, ${workspace_command_prefix}workspace, empty"
        "$mainMod, TAB, ${workspace_command_prefix}workspace, m+1"
        "$mainMod SHIFT, TAB, ${workspace_command_prefix}workspace, m-1"
      ] ++ (
        # workspaces
        # binds $mod + [shift +] {1..10} to [move to] workspace {1..10}
        builtins.concatLists (builtins.genList
          (x:
            let
              ws = let c = (x + 1) / 10; in builtins.toString (x + 1 - (c * 10));
            in
            [
              "$mainMod, ${ws}, ${workspace_command_prefix}workspace, ${toString (x + 1)}"
              "$mainMod SHIFT, ${ws}, ${workspace_command_prefix}movetoworkspace, ${toString (x + 1)}"
            ]) 10));
    };
  };
}