{ lib, pkgs, hyprlandSettings, ... }:
let
  settings = import ./settings.nix { inherit pkgs hyprlandSettings; };
  wallpaper = "/run/wallpaper.jpg";
in
{
  imports = [
    ./config.nix
    ./config/btop
    (import ./config/hypr {inherit pkgs hyprlandSettings;})
    ./config/kitty
    ./config/mako
    (import ./config/waybar {inherit pkgs hyprlandSettings;})
    ./config/wofi
  ];

  wayland.windowManager.hyprland = {
    enable = true;
    plugins = with pkgs.hyprlandPlugins; [
      hyprgrass
    ];
    settings = {
      plugin = {
        touch_gestures = {
          # The default sensitivity is probably too low on tablet screens,
          # I recommend turning it up to 4.0
          sensitivity = "4.0";

          # must be >= 3
          workspace_swipe_fingers = "3";

          # switching workspaces by swiping from an edge, this is separate from workspace_swipe_fingers
          # and can be used at the same time
          # possible values: l, r, u, or d
          # to disable it set it to anything else
          workspace_swipe_edge = "d";

          # in milliseconds
          long_press_delay = "400";

          # resize windows by long-pressing on window borders and gaps.
          # If general:resize_on_border is enabled, general:extend_border_grab_area is used for floating
          # windows
          resize_on_border_long_press = true;

          # in pixels, the distance from the edge that is considered an edge
          edge_margin = "10";

          # emulates touchpad swipes when swiping in a direction that does not trigger workspace swipe.
          # ONLY triggers when finger count is equal to workspace_swipe_fingers
          #
          # might be removed in the future in favor of event hooks
          emulate_touchpad_swipe = false;

          experimental = {
            # send proper cancel events to windows instead of hacky touch_up events,
            # NOT recommended as it crashed a few times, once it's stabilized I'll make it the default
            send_cancel = "0";
          };
          
          hyprgrass-bind = [
            # swipe left from right edge
            ", edge:r:l, workspace, +1"

            # swipe up from bottom edge
            ", edge:d:u, exec, ${settings.defaultApps.browser.pname}"

            # swipe down from left edge
            ", edge:l:d, exec, pactl set-sink-volume @DEFAULT_SINK@ -4%"

            # swipe down with 4 fingers
            ", swipe:4:d, killactive"

            # swipe diagonally left and down with 3 fingers
            # l (or r) must come before d and u
            ", swipe:3:ld, exec, foot"

            # tap with 3 fingers
           ", tap:3, exec, foot"

            # longpress can trigger mouse binds:
            ", longpress:2, movewindow"
            ", longpress:3, resizewindow"
          ];
        };
      };

      gestures = {
        workspace_swipe = lib.mkForce true;
        workspace_swipe_cancel_ratio = "0.15";
      };
    };
  };

  services = {
    hyprpolkitagent.enable = true;
    hyprpaper = {
      enable = true;
      settings = {
        preload = [ "/run/wallpaper.jpg" wallpaper ];
        wallpaper = [
          "${settings.displayLeft.input}, /run/wallpaper.jpg"
          "${settings.displayRight.input}, /run/wallpaper.jpg"
        ];
        splash = false;
      };
    };

    hypridle = {
      enable = true;
      settings = {
        general = {
          before_sleep_cmd = "loginctl lock-session"; # lock before suspend.
          after_sleep_cmd = "hyprctl dispatch dpms on"; # to avoid having to press a key twice to turn on the display.
          ignore_dbus_inhibit = false;
          lock_cmd = "pidof hyprlock || hyprlock"; # avoid starting multiple hyprlock instances.
        };
        listener = [
          # {
          #   timeout = 300; # 5min
          #   on-timeout = "brightnessctl -s set 10"; # set monitor backlight to minimum, avoid 0 on OLED monitor.
          #   on-resume = "brightnessctl -r"; # monitor backlight restore.
          # }
          {
            timeout = settings.lockScreenTimer;
            on-timeout = "loginctl lock-session"; # lock screen when timeout has passed
          }
          {
            timeout = settings.screenOffTimer;
            on-timeout = "hyprctl dispatch dpms off"; # screen off when timeout has passed
            on-resume = "hyprctl dispatch dpms on"; # screen on when activity is detected after timeout has fired.
          }
          {
            timeout = settings.suspendTimer;
            on-timeout = "systemctl suspend"; # suspend pc
          }
        ];
      };
    };
  };

  programs = {
    hyprlock = {
      enable = true;
      settings = {
        background = [
          {
            monitor = "";
            path = wallpaper; # supports png, jpg, webp (no animations, though)
            color = "rgba(25, 20, 20, 1.0)";

            # all these options are taken from hyprland, see https://wiki.hyprland.org/Configuring/Variables/#blur for explanations
            blur_passes = "3"; # 0 disables blurring
            blur_size = "7";
            noise = "0.0117";
            contrast = "0.8916";
            brightness = "0.8172";
            vibrancy = "0.1696";
            vibrancy_darkness = "0.0";
          }
        ];
        input-field = [
          {
            size = "200, 50";
            position = "0, -80";
            monitor = settings.displayLeft.input;
            dots_center = true;
            fade_on_empty = true;
            font_color = "rgb(202, 211, 245)";
            inner_color = "rgb(91, 96, 120)";
            outer_color = "rgb(24, 25, 38)";
            bothlock_color = -1;
            outline_thickness = 5;
            placeholder_text = ''<span foreground="##cad3f5">Password...</span>'';
            shadow_passes = 2;
          }
        ];
      };
    };
    vscode.profiles.default.userSettings."window"."titleBarStyle" = "custom";
  };

  home = {
    sessionVariables = {
      BROWSER                             = "${settings.defaultApps.browser.pname}";
      CLUTTER_BACKEND                     = "wayland";
      EDITOR                              = "${settings.defaultApps.editor.pname}";
      VISUAL                              = "${settings.defaultApps.visual.pname}";
      ICON_THEME                          = settings.iconTheme;
      GTK_CSD                             = "0";
      GTK_THEME                           = settings.gtkTheme;
      GTK_USE_PORTAL                      = "1";
      HYPRCURSOR_THEME                    = settings.cursorTheme;
      HYPRCURSOR_SIZE                     = settings.cursorSize;
      MOZ_ENABLE_WAYLAND                  = "1";
      NIXOS_OZONE_WL                      = "1";
      NIXOS_XDG_OPEN_USE_PORTAL           = "1";
      QT_AUTO_SCREEN_SCALE_FACTOR         = "1";
      QT_QPA_PLATFORM                     = "wayland-egl";
      QT_QPA_PLATFORMTHEME                = "gtk3";
      QT_SCALE_FACTOR                     = "1";
      QT_WAYLAND_DISABLE_WINDOWDECORATION = "1";
      SDL_VIDEODRIVER                     = "wayland";
      TERMINAL                            = "${settings.defaultApps.terminal.pname}";
      XCURSOR_THEME                       = settings.cursorTheme;
      XCURSOR_SIZE                        = settings.cursorSize;
      XDG_CACHE_HOME                      = "\${HOME}/.cache";
      XDG_CONFIG_HOME                     = "\${HOME}/.config";
      XDG_CURRENT_DESKTOP                 = "Hyprland";
      XDG_DATA_HOME                       = "\${HOME}/.local/share";
      XDG_SESSION_DESKTOP                 = "Hyprland";
      XDG_SESSION_TYPE                    = "wayland";
    };

    pointerCursor = {
      gtk.enable = true;
      package = settings.cursorThemePkg;
      name = settings.cursorTheme;
      size = settings.cursorSize;
    };
    
    packages = settings.requiredPkgs;
  };

  dconf = {
    enable = true;
    settings = {
      "org/gnome/desktop/interface".color-scheme = "prefer-dark";
      "org/gnome/desktop/interface".cursor-theme = settings.cursorTheme;
      "org/gnome/desktop/interface".gtk-theme = settings.gtkTheme;
      "org/gnome/desktop/interface".icon-theme = settings.iconTheme;
    };
  };

  gtk = {
    enable = true;

    cursorTheme = {
      name = settings.cursorTheme;
      package = settings.cursorThemePkg;
    };

    theme = {
      name = settings.gtkTheme;
      package = settings.gtkThemePkg;
    };

    iconTheme = {
      name = settings.iconTheme;
      package = settings.iconThemePkg;
    };

    gtk3.extraConfig = {
      gtk-application-prefer-dark-theme = true;
    };

    gtk4.extraConfig = {
      gtk-application-prefer-dark-theme = true;
    };

    font = {
      name = settings.fontName;
      package = settings.fontPackage;
      size = settings.fontSize;
    };
  };
}
