{pkgs, ...}:
with pkgs; {
  imports = [
    ./rofi.nix
    ./services.nix
    ./waybar.nix
  ];

  home.packages = [
    hyprpanel
    swww
    wl-clipboard
  ];

  wayland.windowManager.hyprland = {
    enable = true;
    systemd.variables = ["--all"];

    settings = let
      rofi-clipboard = pkgs.writeScript "rofi-clipboard" ''
        tmp_dir="/tmp/cliphist"
        rm -rf "$tmp_dir"

        if [[ -n "$1" ]]; then
            cliphist decode <<<"$1" | wl-copy
            exit
        fi

        mkdir -p "$tmp_dir"

        read -r -d "" prog <<EOF
        /^[0-9]+\s<meta http-equiv=/ { next }
        match(\$0, /^([0-9]+)\s(\[\[\s)?binary.*(jpg|jpeg|png|bmp)/, grp) {
            system("echo " grp[1] "\\\\\t | cliphist decode >$tmp_dir/"grp[1]"."grp[3])
            print \$0"\0icon\x1f$tmp_dir/"grp[1]"."grp[3]
            next
        }
        1
        EOF

        cliphist list | gawk "$prog"
      '';

      scratchpad = pkgs.writeScript "hyprscratchpad" ''
        COMMAND=$1
        CLASS=$2
        WORKSPACE=$3

        if [[ $(hyprctl clients | grep -v '"title":' | grep "class: $CLASS") ]];then
          hyprctl dispatch togglespecialworkspace $WORKSPACE
        else
          hyprctl dispatch togglespecialworkspace $WORKSPACE && hyprctl dispatch exec "$COMMAND"
        fi
      '';

      mod = "SUPER";
      modC = "SUPER CTRL";
      modS = "SUPER SHIFT";

      browser = "zen-bin";
      colorPicker = "notify-send -i gtk-color-picker $(${lib.getExe hyprpicker} -a) 'Copied to clipboard.'";
      fileManager = "nautilus";
      launcher = "rofi -show drun";
      clipboard = "rofi -modi '   ':${rofi-clipboard} -show '   ' -show-icons";
      terminal = "wezterm";

      screenshot = mode: "${lib.getExe hyprshot} --clipboard-only -m ${mode}";
    in {
      cursor.no_hardware_cursors = true;
      decoration.rounding = 5;
      dwindle.preserve_split = true;
      gestures.workspace_swipe = true;

      input.touchpad = {
        clickfinger_behavior = true;
        natural_scroll = true;
      };

      device = [
        {
          name = "logitech-usb-receiver";
          sensitivity = -0.5;
        }
      ];

      windowrule = [
        "float, ^(equibop)$"
        "float, ^(org.telegram.desktop)$"
      ];

      layerrule = [
        "dimaround, rofi"
      ];

      animations = {
        enabled = true;

        bezier = [
          "overshot,0.7,0.6,0.1,1.1"
          "bounce,1,1.6,0.1,0.85"
        ];

        animation = [
          "windows,1,5,bounce,popin"
          "border,1,20,default"
          "fade,1,5,default"
          "workspaces,1,5,overshot,slide"
        ];
      };

      general = {
        border_size = 2;
        gaps_in = 10;
        resize_on_border = true;

        "col.active_border" = "rgba(a6e3a1ee) rgba(cba6f7ee) 45deg";
        "col.inactive_border" = "rgba(595959aa)";
      };

      exec-once = [
        "hyprpanel"
        "swww-daemon"
        "${writeScript "wallpaper" ''
          while : ; do
            for file in $(${uutils-coreutils}/bin/uutils-ls ${./walls}/*.jpg | sort -R | tail -1); do
              swww img "$file" --transition-fps 165
              sleep 5m
            done
          done
        ''}"
      ];

      misc = {
        force_default_wallpaper = 0;
        disable_hyprland_logo = true;
      };

      monitor = [
        "DP-1,  2560x1440@165, auto, auto"
      ];

      env = [
        # Nvidia stuff
        "__GLX_VENDOR_LIBRARY_NAME, nvidia"
        "LIBVA_DRIVER_NAME,         nvidia"
        "NVD_BACKEND,               direct"

        # Cursors
        "HYPRCURSOR_SIZE, 24"
        "XCURSOR_SIZE, 24"
      ];

      bindm = [
        "${mod},  mouse:272, movewindow"
        "${mod},  mouse:273, resizewindow"
      ];

      bind =
        [
          # Apps
          "${mod},      v, exec, ${clipboard}"
          "${mod},      c, exec, ${colorPicker}"
          "${mod},      w, exec, ${browser}"
          "${mod},      e, exec, ${fileManager}"
          "${mod},      r, exec, ${launcher}"
          "${mod}, Return, exec, ${terminal}"

          # Scratchpads
          "${mod}, d, exec, ${scratchpad} equibop equibop equibop"
          "${mod}, t, exec, ${scratchpad} telegram-desktop org.telegram.desktop telegram"

          # Screenshots
          "${modS}, s, exec, ${screenshot "window"}"
          "${modC}, 3, exec, ${screenshot "output -c"}"
          "${modC}, 4, exec, ${screenshot "region -C 0,0"}"

          # Mouse controls
          "${mod}, mouse_down, workspace, e-1"
          "${mod},   mouse_up, workspace, e+1"

          # Quitting
          "${mod},  q, killactive"
          "${modS}, q, exit"

          # Toggles
          "${mod}, Space, togglefloating"

          # Focus movements
          "${mod}, h, movefocus, l"
          "${mod}, j, movefocus, d"
          "${mod}, k, movefocus, u"
          "${mod}, l, movefocus, r"

          # Window movements
          "${modS}, h, movewindow, l"
          "${modS}, j, movewindow, d"
          "${modS}, k, movewindow, u"
          "${modS}, l, movewindow, r"

          # Window resizing
          "${modC}, h, resizeactive, -30  0"
          "${modC}, j, resizeactive, 0   30"
          "${modC}, k, resizeactive, 0  -30"
          "${modC}, l, resizeactive, 30   0"

          # Volume controls
          ", XF86AudioRaiseVolume, exec, wpctl set-volume @DEFAULT_AUDIO_SINK@ 5%+"
          ", XF86AudioLowerVolume, exec, wpctl set-volume @DEFAULT_AUDIO_SINK@ 5%-"
          ", XF86AudioMute, exec, wpctl set-mute @DEFAULT_AUDIO_SINK@ toggle"

          # Media controls
          ", XF86AudioPlay, exec, playerctl play-pause"
          ", XF86AudioNext, exec, playerctl next"
          ", XF86AudioPrev, exec, playerctl previous"
        ]
        ++ (
          builtins.concatLists (builtins.genList (
              x: let
                ws = let
                  c = (x + 1) / 10;
                in
                  builtins.toString (x + 1 - (c * 10));
              in [
                # Workspaces
                "${mod},  ${ws}, workspace,       ${builtins.toString (x + 1)}"
                "${modS}, ${ws}, movetoworkspace, ${builtins.toString (x + 1)}"
              ]
            )
            10)
        );
    };
  };
}
