{
  lib,
  config,
  pkgs,
  ...
}: let
  inherit (lib) mkIf mkEnableOption catppuccin;

  cfg = config.horseman.wm.hyprland;
  colors = config.horseman.catppuccin.colors;
  flavor = config.horseman.catppuccin.flavor;

  cursorSize = 24;
in {
  imports = [
    ./options.nix
    ./keybindings.nix
    ./animations.nix
    ./waybar.nix
  ];

  options = {
    horseman.wm.hyprland.enable = mkEnableOption "Hyprland";
  };

  config = mkIf cfg.enable {
    programs.hyprland = {
      enable = true;
      xwayland.enable = true;
    };

    security.polkit.enable = true;
    environment.systemPackages = with pkgs; [
      brightnessctl # Needed for brightness bindings
      hypridle # Sleep
      hyprlock # Lock
      hyprpaper # Wallpaper
      hyprpicker # RGB Picker
      hyprpolkitagent # Authentication popup
      hyprshot # Screenshot
      playerctl # Media control
      pulsemixer # Audio frontend
      wl-clipboard # Clipboard
      fuzzel # Launcher
      xdg-desktop-portal-hyprland # XDG Portal (needed but idk why)
      catppuccin-cursors."${flavor}Dark" # Cursors
      dunst # Notifications
    ];

    horseman.dots.gtk.enable = true;

    nix-hyprland = {
      enable = true;
      username = config.horseman.username;

      execOnce = [
        "hypridle"
        "hyprpaper"
        "systemctl --user start hyprpolkitagent"
        "waybar"
        "hyprctl setcursor catppuccin-${flavor}-dark-cursors 24"
        "dunst --startup_notification"
      ];

      env = [
        {
          name = "XCURSOR_SIZE";
          value = toString cursorSize;
        }
        {
          name = "HYPRCURSOR_SIZE";
          value = toString cursorSize;
        }
      ];

      windowrules = [
        "suppressevent maximize, class:.*"
        "nofocus,class:^$,title:^$,xwayland:1,floating:1,fullscreen:0,pinned:0"

        "opacity 1.0 override, initialTitle:^Picture-in-Picture$"

        "float, initialClass:CImg"
        "float, initialTitle:GLFW"
        "tile, initialTitle:sxiv"
        "tile, initialTitle:Godot"
        "fullscreen, initialTitle:.*QEMU.*"
      ];

      layerrules = [
        # "noanim, selection"
        "animation fade 3, selection"
      ];

      general = {
        gapsIn = 5;
        gapsOut = 5;
        borderSize = 2;

        resizeOnBorder = true;
        allowTearing = false;

        col.activeBorder = catppuccin.toRGB colors.accent;
        col.inactiveBorder = catppuccin.toRGBA colors.accent 0.25;

        layout = "dwindle";
      };

      decoration = {
        rounding = 10;
        activeOpacity = 1.0;
        inactiveOpacity = 0.7;

        dimSpecial = 0.4;

        shadow = {
          enabled = true;
          range = 15;
          colorInactive = "0x881a1a1a";
        };

        blur = {
          enabled = true;
          size = 5;
          passes = 3;
        };
      };

      dwindle = {
        pseudotile = true;
        preserveSplit = true;
      };

      master = {
        newStatus = "master";
      };

      misc = {
        forceDefaultWallpaper = 0;
        keyPressEnablesDPMS = true;
        newWindowTakesOverFullscreen = 2;

        enableSwallow = true;
        swallowRegex = "^kitty$";
      };

      input = {
        kbLayout = "us";
        repeatRate = 50;
        repeatDelay = 300;
        followMouse = 1;
        sensitivity = 0.0;
        touchpad.naturalScroll = true;
        numlockByDefault = true;

        touchpad.disableWhileTyping = true;
      };

      group = {
        autoGroup = false;
        dragIntoGroup = 1;

        col = {
          borderActive = config.nix-hyprland.general.col.activeBorder; # I don't wanna believe this can't be done better :(
          borderInactive = config.nix-hyprland.general.col.inactiveBorder;
          borderLockedActive = config.nix-hyprland.general.col.activeBorder;
          borderLockedInactive = config.nix-hyprland.general.col.inactiveBorder;
        };

        groupbar = {
          fontSize = 14;
          height = 26;
          keepUpperGap = true;
        };
      };

      binds = {
        workspaceCenterOn = 1;
        dragThreshold = 0;
        hideSpecialOnWorkspaceChange = true;
      };

      ecosystem = {
        noDonationNag = true;
      };

      monitors = {
        addDefault = true;
        defaultWallpaper = ../../../misc/default-wallpaper.jpg;
      };

      sleep = {
        lockCommand = "pidof hyprlock || hyprlock";

        listeners = [
          {
            timeout = 900;
            onTimeout = "hyprctl dispatch dpms off";
            onResume = "hyprctl dispatch dpms on";
          }
          {
            timeout = 910;
            onTimeout = "loginctl lock-session";
          }
        ];
      };
    };

    services.logind.settings.Login = {
      HandlePowerKey = "ignore";
      HandleLidSwitch = "lock";
      HandleLidSwitchDocked = "ignore";
    };
  };
}
