{ lib, pkgs, config, ... }:

let
  cfg = config.home.hyprland;
in

{
  options.home.hyprland = {
    execOnce = lib.mkOption {
      type = lib.types.listOf lib.types.str;
      default = [ "waybar" ];
      description = "Commands to run once when Hyprland starts (maps to Hyprland `exec-once`).";
    };
  };
  config = {
    home.packages = with pkgs; [
      bzmenu
      hyprshot
      hyprlock
      playerctl
      speedcrunch
    ];

    wayland.windowManager.hyprland = {
      enable = true;
      configType = "lua";
      settings =
      let
        mkLuaInline = lib.generators.mkLuaInline;
        toLua = lib.generators.toLua;
        mkArgs = args: { _args = args; };
        bind =
          keys: dispatcher: options:
          mkArgs [
            keys
            dispatcher
            options
          ];
        dsp = {
          exec_cmd = app: mkLuaInline ''hl.dsp.exec_cmd("${app}")'';
          focus = arg: mkLuaInline "hl.dsp.focus(${toLua { } arg})";
          window = {
            move = arg: mkLuaInline "hl.dsp.window.move(${toLua { } arg})";
            drag = mkLuaInline "hl.dsp.window.drag()";
            resize = mkLuaInline "hl.dsp.window.resize()";
            close = mkLuaInline "hl.dsp.window.close()";
            kill = mkLuaInline "hl.dsp.window.kill()";
            fullscreen = mkLuaInline "hl.dsp.window.fullscreen()";
          };
          exit = mkLuaInline "hl.dsp.exit()";
          workspace = {
            move = arg: mkLuaInline "hl.dsp.workspace.move(${toLua { } arg})";
          };
        };
        mod = "SUPER";
        workspaces = lib.stringToCharacters "abcdefgimnopqrstuvwxyz";
      in
      {
        config = {
          general = {
            resize_on_border = true;
            allow_tearing = true;
          };

          animations.enabled = true;

          decoration = {
            inactive_opacity = 0.8;
            active_opacity = 0.9;
            rounding = 5;
            rounding_power = 2.5;
            blur = {
              enabled = true;
              brightness = 1.0;
              contrast = 1.0;
              noise = 0.01;

              vibrancy = 0.2;
              vibrancy_darkness = 0.5;

              passes = 4;
              size = 7;

              popups = true;
              popups_ignorealpha = 0.2;
            };
            shadow = {
              enabled = true;
              color = "rgba(00000055)";
              offset = "0 15";
              range = 100;
              render_power = 2;
              scale = 0.97;
            };
          };

          misc = {
            focus_on_activate = true;
          };
        };

        bind = lib.flatten [
          (bind "${mod} + Q" (dsp.window.kill) { })
          (bind "${mod} + L" (dsp.exec_cmd "hyprlock") { })
          (bind "${mod} + D" (dsp.exec_cmd "rofi -show drun") { })
          (bind "${mod} + B" (dsp.exec_cmd "bzmenu --launcher rofi") { })
          (bind "${mod} + F" (dsp.window.fullscreen) { })
          (bind "${mod} + Z" (dsp.exec_cmd "hyprshot -m region") { })
          (bind "${mod} + M" (dsp.exit) { })
          (bind "${mod} + SPACE" (dsp.exec_cmd "firefox") { })
          (bind "${mod} + RETURN" (dsp.exec_cmd "kitty") { })

          (bind "${mod} + SHIFT + LEFT" (dsp.window.move { direction = "l"; }) { })
          (bind "${mod} + SHIFT + DOWN" (dsp.window.move { direction = "d"; }) { })
          (bind "${mod} + SHIFT + UP" (dsp.window.move { direction = "u"; }) { })
          (bind "${mod} + SHIFT + RIGHT" (dsp.window.move { direction = "r"; }) { })

          (bind "${mod} + LEFT" (dsp.focus { direction = "l"; }) { })
          (bind "${mod} + DOWN" (dsp.focus { direction = "d"; }) { })
          (bind "${mod} + UP" (dsp.focus { direction = "u"; }) { })
          (bind "${mod} + RIGHT" (dsp.focus { direction = "r"; }) { })

          (bind "${mod} + 1" (dsp.focus { workspace = 1; }) {})
          (bind "${mod} + 2" (dsp.focus { workspace = 2; }) {})
          (bind "${mod} + 3" (dsp.focus { workspace = 3; }) {})
          (bind "${mod} + 4" (dsp.focus { workspace = 4; }) {})
          (bind "${mod} + 5" (dsp.focus { workspace = 5; }) {})
          (bind "${mod} + 6" (dsp.focus { workspace = 6; }) {})
          (bind "${mod} + 7" (dsp.focus { workspace = 7; }) {})
          (bind "${mod} + 8" (dsp.focus { workspace = 8; }) {})
          (bind "${mod} + 9" (dsp.focus { workspace = 9; }) {})

          (bind "${mod} + SHIFT + 1" (dsp.window.move { workspace = 1; }) {})
          (bind "${mod} + SHIFT + 2" (dsp.window.move { workspace = 2; }) {})
          (bind "${mod} + SHIFT + 3" (dsp.window.move { workspace = 3; }) {})
          (bind "${mod} + SHIFT + 4" (dsp.window.move { workspace = 4; }) {})
          (bind "${mod} + SHIFT + 5" (dsp.window.move { workspace = 5; }) {})
          (bind "${mod} + SHIFT + 6" (dsp.window.move { workspace = 6; }) {})
          (bind "${mod} + SHIFT + 7" (dsp.window.move { workspace = 7; }) {})
          (bind "${mod} + SHIFT + 8" (dsp.window.move { workspace = 8; }) {})
          (bind "${mod} + SHIFT + 9" (dsp.window.move { workspace = 9; }) {})

          (bind "XF86AudioLowerVolume" (dsp.exec_cmd "wpctl set-volume @DEFAULT_AUDIO_SINK@ 5%-") {
            repeating = true;
            locked = true;
          })
          (bind "XF86AudioRaiseVolume" (dsp.exec_cmd "wpctl set-volume @DEFAULT_AUDIO_SINK@ 5%+") {
            repeating = true;
            locked = true;
          })
          (bind "XF86AudioPlay" (dsp.exec_cmd "playerctl play-pause") { locked = true; })
          (bind "XF86AudioPrev" (dsp.exec_cmd "playerctl previous") { locked = true; })
          (bind "XF86AudioNext" (dsp.exec_cmd "playerctl next") { locked = true; })

          (bind "${mod} + mouse:272" dsp.window.drag { mouse = true; })
          (bind "${mod} + mouse:273" dsp.window.resize { mouse = true; })
        ];

        on = mkArgs [
          "hyprland.start"
          (mkLuaInline ''
            function()
              hl.exec_cmd("waybar")
            end'')
        ];
      };
    };
  };
}
