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

let
  cfg = config.home.hyprland;
  toggleRecorder = import ./scripts/toggle-recorder.nix { inherit pkgs; };
in
{
  options.home.hyprland.monitors = lib.mkOption {
    type = lib.types.listOf (lib.types.submodule {
      options = {
        output = lib.mkOption { type = lib.types.str; };
        mode = lib.mkOption {
          type = lib.types.str;
          default = "preferred";
        };
        position = lib.mkOption {
          type = lib.types.str;
          default = "auto";
        };
        scale = lib.mkOption {
          type = lib.types.number;
          default = 1;
        };
      };
    });
    default = [ ];
  };

  config = {
    home.packages = with pkgs; [
      bzmenu
      hyprshot
      hyprlock
      playerctl
      speedcrunch
      toggleRecorder
    ];
    wayland.windowManager.hyprland = {
      enable = true;
      configType = "lua";
      settings =
        let
          mkLuaInline = lib.generators.mkLuaInline;
          toLua = lib.generators.toLua;
          mkArgs = args: { _args = args; };
          defaultMonitor = {
            output = "";
            mode = "preferred";
            position = "auto";
            scale = 1;
          };
          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.7;
              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} + W" (dsp.exec_cmd "pkill -SIGUSR1 -f '^waybar$'") { })
            (bind "${mod} + Q" (dsp.window.close) { })
            (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} + SHIFT + Z" (dsp.exec_cmd "toggle-recorder") { })
            (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")

                  hl.monitor(${toLua {} defaultMonitor})

                  ${lib.concatMapStringsSep "\n"
                    (m: "hl.monitor(${toLua {} m})")
                    cfg.monitors}
                end
              '')
            ])

            (mkArgs [
              "config.reloaded"
              (mkLuaInline ''
                function()
                  hl.monitor(${toLua {} defaultMonitor})

                  ${lib.concatMapStringsSep "\n"
                    (m: "hl.monitor(${toLua {} m})")
                    cfg.monitors}
                end
              '')
            ])
          ];
        };
    };
  };
}
