{ inputs, pkgs, ... }:
let
    playerctl = "${pkgs.playerctl}/bin/playerctl";
    wl-paste = "${pkgs.wl-clipboard}/bin/wl-paste";
    nautilus = "${pkgs.nautilus}/bin/nautilus";
    gnome-calendar = "${pkgs.gnome-calendar}/bin/gnome-calendar";
    wpctl = "${pkgs.wireplumber}/bin/wpctl";
    terminal-name = ".kitty-wrapped";
    terminal = "${pkgs.kitty}/bin/kitty";
    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 ];

    workspace_command_prefix = "split:";
    hyprland_plugins = [ inputs.hyprsplit.packages."${pkgs.system}".hyprsplit ];

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

    launch_terminal = pkgs.writeShellScriptBin "launch_terminal" ''
        function find_leaf_pid(){
            local PID=$1
            local CHILD_PID=$(pgrep -P "$PID")
            if [ "$CHILD_PID" != "" ]; then
                local RET=$(find_leaf_pid "$CHILD_PID")
                if [ "$RET" != "" ]; then
                    PID=$RET
                fi
            fi
            local NAME=$(ps -p "$PID" -o comm=)
            if [ "$NAME" == "zsh" ]; then
                echo "$PID"
            elif [ "$NAME" == "ssh" ]; then
                echo "$PID"
            fi
        }

        LEAF_PID=$(find_leaf_pid "$1")
        if [ "$(ps -p "$LEAF_PID" -o comm=)" == "ssh" ]; then
            SSH_COMMAND=$(ps -p "$LEAF_PID" -o args --no-headers)
            if [[ "$SSH_COMMAND" == *"waypipe"* ]]; then
                CLIENT=$(echo "$SSH_COMMAND" | awk '{ print $5 }')
                PREVIOUS_SESSION_ID=$(grep -z "SSH_SESSION_ID" "/proc/$LEAF_PID/environ" | xargs -0 -n 1 | grep -oP "[0-9]*")
                SSH_SESSION_ID=$RANDOM
                ${terminal} -e zsh -c "SSH_SESSION_ID=$SSH_SESSION_ID waypipe ssh -t \"$CLIENT\" env SSH_SESSION_ID=\"$SSH_SESSION_ID\" PREVIOUS_SESSION_ID=\"$PREVIOUS_SESSION_ID\" \"zsh --login\""
            else
                ${terminal} -e zsh -c "ssh -t \"$(echo "$SSH_COMMAND" | awk '{ print $2 }')\""
            fi

        else # Not an ssh session
            if [ "$(ps -p "$1" -o comm=)" == "${terminal-name}" ]; then
                CWD=$(readlink -e /proc/"$LEAF_PID"/cwd)
                if [ "$CWD" != "" ]; then
                    ${terminal} --working-directory "$CWD"
                else
                    ${terminal}
                fi
            else
                ${terminal}
            fi
        fi
    '';
in {
    home.packages = [
        pkgs.wl-clipboard
        pkgs.jq
    ];
    services.hyprpaper = {
        enable = true;
        settings = {
            ipc = "off";
            splash = false;
            preload = [ "${./files/wallpaper.png}" ];
            wallpaper = [
                # Fill in by host-specific config!
                # "Display,${./files/wallpaper.png}"
            ];
        };
    };

    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" = pkgs.lib.mkDefault "SUPER_L";
            "$altMod" = pkgs.lib.mkDefault "ALT_L";
            exec-once = [
                "hyprpaper"
                "hyprctl dispatch exec ${inputs.ags.packages.${pkgs.system}.default}/bin/ags-bar"
                "${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,${terminal}"
                "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)$"
                "bordersize 0, floating:0, onworkspace:w[tv1]"
                "rounding 0, floating:0, onworkspace:w[tv1]"
                "bordersize 0, floating:0, onworkspace:f[1]"
                "rounding 0, floating:0, onworkspace:f[1]"
            ];
            layerrule = [ "noanim,ags_bar_0" "noanim,selection" ];
            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, shift:both_capslock, caps:ctrl_modifier";
                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";
                force_split = 2;
            };
            gestures = {
                workspace_swipe = "on";
                workspace_swipe_invert = false;
            };
            workspace = [
                "w[tv1], gapsout:0, gapsin:0"
                "f[1], gapsout:0, gapsin:0"
            ];
            bindr = [
                "$mainMod, $mainMod, exec, pkill rofi || ${rofi} -show drun"
            ];
            bindm = [
                "$mainMod, mouse:272, movewindow"
                "$mainMod, mouse:273, resizewindow"
            ];
            binde = [
                "$mainMod $altMod, L, resizeactive, 20 0"
                "$mainMod $altMod, H, resizeactive, -20 0"
                "$mainMod $altMod, K, resizeactive, 0 -20"
                "$mainMod $altMod, J, resizeactive, 0 20"
            ];
            bind = [
                "$mainMod, return, exec, ${launch_terminal}/bin/launch_terminal $(hyprctl activewindow -j | ${jq} .pid)"
                "$mainMod SHIFT, return, exec, ${terminal}"
                "$mainMod, Q, killactive,"
                "$mainMod, A, exec, ${nautilus}"
                "$mainMod, S, exec, LC_TIME=\"en_GB.UTF-8\" ${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''
                '', Pause, exec, systemctl suspend''
                '', XF86Calculator, exec, systemctl suspend''

                "$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 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"
                "$mainMod, Caps_Lock, ${workspace_command_prefix}workspace, m+1"
                "$mainMod SHIFT, Caps_Lock, ${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));
        };
    };
}