{ lib, config, pkgs, ... }: let
  lua = lib.generators.mkLuaInline;

  bind = keys: dispatcher: { _args = [ keys dispatcher ]; };
  bindOpts = keys: dispatcher: opts: { _args = [ keys dispatcher opts ]; };

  dsp = {
    exec = cmd: lua ''hl.dsp.exec_cmd("${cmd}")'';
    close = lua "hl.dsp.window.close()";
    exit = lua "hl.dsp.exit()";
    float = lua ''hl.dsp.window.float({ action = "toggle" })'';
    fullscreen = lua "hl.dsp.window.fullscreen()";
    pseudo = lua "hl.dsp.window.pseudo()";
    layout = msg: lua ''hl.dsp.layout("${msg}")'';
    focus = dir: lua ''hl.dsp.focus({ direction = "${dir}" })'';
    swap = dir: lua ''hl.dsp.window.swap({ direction = "${dir}" })'';
    toggleSpecial = name: lua ''hl.dsp.workspace.toggle_special("${name}")'';
    moveToSpecial = name: lua ''hl.dsp.window.move({ workspace = "special:${name}" })'';
    focusWorkspace = ws: lua ''hl.dsp.focus({ workspace = "${toString ws}" })'';
    moveToWorkspace = ws: lua ''hl.dsp.window.move({ workspace = "${toString ws}", follow = false})'';
    drag = lua "hl.dsp.window.drag()";
    resize = lua "hl.dsp.window.resize()";
  };
  

  startupScript = pkgs.writeShellScriptBin "hyprland-start" ''
    ${pkgs.eww}/bin/eww open bar &
    ${pkgs.awww}/bin/awww-daemon &

    sleep 2
    keepassxc &
    firefox &
    jellyfin-mpv-shim &
    easyeffects --gapplication-service &

    sleep 2
    nextcloud &
    # telegram-desktop &
    # discord &
  '';
in {
  config = lib.mkIf (config.usercfg.wm == "Wayland") {
    wayland.windowManager.hyprland = {
      enable = true;
      xwayland.enable = true;
      configType = "lua";
      settings = {
        on = {
          _args = [
            "hyprland.start"
            (lua ''
              function()
                hl.exec_cmd("dbus-update-activation-environment --systemd WAYLAND_DISPLAY XDG_CURRENT_DESKTOP")
                hl.exec_cmd("${pkgs.polkit_gnome}/libexec/polkit-gnome-authentication-agent-1")
                hl.exec_cmd("${pkgs.wl-clipboard}/bin/wl-paste --type text --watch ${lib.getExe pkgs.cliphist} store")
                hl.exec_cmd("${pkgs.wl-clipboard}/bin/wl-paste --type image --watch ${lib.getExe pkgs.cliphist} store")
                hl.exec_cmd("${lib.getExe pkgs.swayidle} -w timeout 600 '${pkgs.swaylock-effects}/bin/swaylock' before-sleep '${pkgs.swaylock-effects}/bin/swaylock'")
                hl.exec_cmd("${lib.getExe startupScript}")
                hl.exec_cmd("[workspace special:magic silent] kitty --title flying_kitty")
              end'')
          ];
        };

        monitor = [{
          output = "";
          mode = "preferred";
          position = "auto";
          scale = "auto";
          bitdepth = 10;
        }];
        #Fullscreen HDR is possible without the hdr cm setting if "render:cm_auto_hdr" is enabled.

        config = {
          input = {
            kb_layout = "us";
            kb_variant = "intl";#, phonetic";
            kb_options = "grp:alt_shift_toggle";
            follow_mouse = 1;
            sensitivity = 0;

            touchpad = {
              natural_scroll = false;
              scroll_factor = 1;
              disable_while_typing = false;
              tap_to_click = false;
            };
          };
          render = {
            cm_enabled = true;
            cm_auto_hdr = 1;
          };
          quirks = {
            # prefer_hdr = 1;
          };
          misc = {
            force_default_wallpaper = -1;
            disable_hyprland_logo = true;
            animate_mouse_windowdragging = false;
            animate_manual_resizes = false;
            vrr = 1;
          };
          ecosystem = {
            no_update_news = true;
            no_donation_nag = true;
          };
          general = {
            gaps_in = config.colorScheme.palette.gaps-window;
            gaps_out = config.colorScheme.palette.gaps-screen;
            border_size = lib.toInt config.colorScheme.palette.border-width;
            col = {
              active_border = "rgb(${config.colorScheme.palette.base04})";
              inactive_border = "rgb(${config.colorScheme.palette.base03})";
            };
            layout = "dwindle";
          };

          decoration = {
            rounding = lib.toInt config.colorScheme.palette.border-radius;
            inactive_opacity = 1.0;
            active_opacity = 1.0;
            fullscreen_opacity = 1.0;

            blur = {
              enabled = true;
              size = 2;
              passes = 1;
              new_optimizations = true;
            };
          };

          dwindle = {
            #pseudotile = true;
            preserve_split = true;
          };
          animations = {
            enabled = true;
          };

          master = {
            new_status = "master";
          };
        };

        curve = [{
          _args = [
            "customcurve"
            {
              type = "bezier";
              points = lua "{ {0.0, 0.9}, {0.1, 1.0} }";
            }
          ];
        }];

        animation = [
          { leaf = "windows"; enabled = true; speed = 4; bezier = "customcurve"; }
          { leaf = "windowsOut"; enabled = true; speed = 4; bezier = "customcurve"; style = "popin 80%"; }
          { leaf = "border"; enabled = true; speed = 10; bezier = "customcurve"; }
          { leaf = "borderangle"; enabled = true; speed = 1; bezier = "customcurve"; }
          { leaf = "fade"; enabled = true; speed = 4; bezier = "customcurve"; }
          { leaf = "workspaces"; enabled = true; speed = 4; bezier = "customcurve"; }
        ];


        gesture = {
          fingers = 3;
          direction = "vertical";
          action = "workspace";
        };

        window_rule = [
          { match.title = "noshadow"; float= false;}
          {
            match.title = "^(flying_kitty)$";
            float = true;
            center = true;
            size = "1100 600";
            move = "{0 600}";
            animation = "slide";
          }
          { match.title = "^(Volume Control)$"; float = true; }
          { match.title = "^(Picture-in-Picture)$"; float = true; }
          { match.title = "^(Steam)$"; float = true; }
          # --- Chat & Workspace Assignments ---
            { match.class = "^(org.telegram.desktop)$"; workspace = "2 silent"; }
            { match.class = "^(discord)$"; workspace = "2 silent"; }
            { match.class = "^(org.keepassxc.KeePassXC)$"; workspace = "8 silent"; }
            { match.title = "^(Nextcloud)$"; workspace = "8 silent"; }
            { match.class = "^(org.telegram.desktop)$"; match.title = "^(Media viewer)$"; float = true; center = true; }
            { 
              match.class = "^(Tk)$"; 
              match.title = "^(Server Configuration)$"; 
              workspace = "8 silent"; 
            }
              # --- KeePassXC Dialogs ---
            {
              match.class = "^(org.keepassxc.KeePassXC)$";
              match.title = "^(KeePassXC -  Access Request)$";
              float = true;
              pin = true;
            }
            {
              match.class = "^(org.keepassxc.KeePassXC)$";
              match.title = "^(Unlock Database - KeePassXC)$";
              float = true;
              pin = true;
            }
            # --- Generic System / File Dialogs ---
            { match.title = "^(Open)$"; float = true; }
            { match.title = "^(Choose Files)$"; float = true; }
            { match.title = "^(Save As)$"; float = true; }
            { match.title = "^(Confirm to replace files)$"; float = true; }
            { match.title = "^(File Operation Progress)$"; float = true; }

            # --- Firefox Window Rules ---
            {
              match.class = "^(firefox)$";
              match.title = "^(Picture-in-Picture)$";
              float = true;
              pin = true;
              suppress_event = "fullscreen";
            }
            {
              match.class = "^(firefox)$";
              match.title = "^(Firefox — Sharing Indicator)$";
              float = true;
              suppress_event = "fullscreen";
            }
            {
              match.class = "^(firefox)$";
              match.title = "^(Extension:.* Mozilla Firefox)$";
              float = true;
              suppress_event = "fullscreen";
            }

            # --- Telegram Media Viewer ---
            {
              match.class = "^(org.telegram.desktop)$";
              match.title = "^(Media viewer)$";
              float = true;
              center = true;
            }

            # --- Idle Inhibition ---
            { match.class = "^(.*)$"; idle_inhibit = "fullscreen"; }
            { match.class = "^(steam_app_.*)$"; idle_inhibit = "focus"; }
            { match.class = "^(mpv)$"; idle_inhibit = "focus"; }

        ];

        # windowrule = [ "noshadow, floating:0" ];

        # windowrulev2 = [
        #   "workspace 2 silent, class:^(org.telegram.desktop)$"
        #   "workspace 2 silent, class:^(discord)$"
        #   "workspace 8 silent, class:^(org.keepassxc.KeePassXC)$"
        #   "workspace 8 silent, title:^(Nextcloud)$"
        #   "workspace 8 silent, class:^(Tk)$,title:^(Server Configuration)$"
        #   "float,class:^(org.keepassxc.KeePassXC)$,title:^(KeePassXC -  Access Request)$"
        #   "pin,class:^(org.keepassxc.KeePassXC)$,title:^(KeePassXC -  Access Request)$"
        #   "float,class:^(org.keepassxc.KeePassXC)$,title:^(Unlock Database - KeePassXC)$"
        #   "pin,class:^(org.keepassxc.KeePassXC)$,title:^(Unlock Database - KeePassXC)$"
        #   "float,title:^(Open)$"
        #   "float,title:^(Choose Files)$"
        #   "float,title:^(Save As)$"
        #   "float,title:^(Confirm to replace files)$"
        #   "float,title:^(File Operation Progress)$"
        #   "float,class:^(firefox)$,title:^(Picture-in-Picture)$"
        #   "pin,class:^(firefox)$,title:^(Picture-in-Picture)$"
        #   "suppressevent fullscreen,class:^(firefox)$,title:^(Picture-in-Picture)$"
        #   "float,class:^(firefox)$,title:^(Firefox — Sharing Indicator)$"
        #   "suppressevent fullscreen,class:^(firefox)$,title:^(Firefox — Sharing Indicator)$"
        #   "float,class:^(firefox)$,title:^(Extension:.* Mozilla Firefox)$"
        #   "suppressevent fullscreen,class:^(firefox)$,title:^(Extension:.* Mozilla Firefox)$"
        #   "float,class:^(org.telegram.desktop)$,title:^(Media viewer)$"
        #   "center,class:^(org.telegram.desktop)$,title:^(Media viewer)$"
        #   "idleinhibit fullscreen, class:^(.*)"
        #   "idleinhibit focus, class:^(steam_app_.*)$"
        #   "idleinhibit focus, class:^(mpv)$"
        # ];

        layer_rule = [ {
          match.namespace = "^eww%-blur$";
          blur = true;
          ignore_alpha = 0.5;
        }];

        bind = [
          (bind "SUPER + RETURN" (dsp.exec "kitty"))
          (bind "SUPER + SHIFT + RETURN" (dsp.toggleSpecial "magic"))
          (bind "SUPER + SHIFT + S" (dsp.moveToSpecial "magic"))
          (bind "SUPER + Q" dsp.close)
          (bind "SUPER + T" dsp.float)
          (bind "SUPER + F" dsp.fullscreen)
          (bind "SUPER + P" dsp.pseudo)
          (bind "SUPER + J" (dsp.layout "togglesplit"))
          (bind "SUPER + D" (dsp.exec "${lib.getExe pkgs.wofi} -modi --show drun"))
          (bind "SUPER + SHIFT + D" (dsp.exec "~/.config/hypr/themes/apatheia/eww/launch_bar"))
          (bind "SUPER + V" (dsp.exec "${lib.getExe pkgs.cliphist} list | ${lib.getExe pkgs.wofi} -dmenu | ${lib.getExe pkgs.cliphist} decode | ${pkgs.wl-clipboard}/bin/wl-copy"))
          (bind "PRINT" (dsp.exec "${lib.getExe pkgs.hyprshot} -m region --raw | ${lib.getExe pkgs.satty} --filename - --early-exit --action-on-enter save-to-clipboard --copy-command '${pkgs.wl-clipboard}/bin/wl-copy'"))
          (bind "SUPER + L" (dsp.exec "${pkgs.swaylock-effects}/bin/swaylock"))
          (bind "SUPER + left" (dsp.focus "left"))
          (bind "SUPER + right" (dsp.focus "right"))
          (bind "SUPER + up" (dsp.focus "up"))
          (bind "SUPER + down" (dsp.focus "down"))
          (bind "SUPER + mouse_down" (dsp.focusWorkspace "e+1"))
          (bind "SUPER + mouse_up" (dsp.focusWorkspace "e-1"))

          (bind "SUPER + 1" (dsp.focusWorkspace 1))
          (bind "SUPER + SHIFT + 1" (dsp.moveToWorkspace 1))
          (bind "SUPER + 2" (dsp.focusWorkspace 2))
          (bind "SUPER + SHIFT + 2" (dsp.moveToWorkspace 2))
          (bind "SUPER + 3" (dsp.focusWorkspace 3))
          (bind "SUPER + SHIFT + 3" (dsp.moveToWorkspace 3))
          (bind "SUPER + 4" (dsp.focusWorkspace 4))
          (bind "SUPER + SHIFT + 4" (dsp.moveToWorkspace 4))
          (bind "SUPER + 5" (dsp.focusWorkspace 5))
          (bind "SUPER + SHIFT + 5" (dsp.moveToWorkspace 5))
          (bind "SUPER + 6" (dsp.focusWorkspace 6))
          (bind "SUPER + SHIFT + 6" (dsp.moveToWorkspace 6))
          (bind "SUPER + 7" (dsp.focusWorkspace 7))
          (bind "SUPER + SHIFT + 7" (dsp.moveToWorkspace 7))
          (bind "SUPER + 8" (dsp.focusWorkspace 8))
          (bind "SUPER + SHIFT + 8" (dsp.moveToWorkspace 8))
          (bind "SUPER + 9" (dsp.focusWorkspace 9))
          (bind "SUPER + SHIFT + 9" (dsp.moveToWorkspace 9))
          (bind "SUPER + 0" (dsp.focusWorkspace 0))
          (bind "SUPER + SHIFT + 0" (dsp.moveToWorkspace 0))
          (bind "XF86AudioPlay" (dsp.exec "${lib.getExe pkgs.playerctl} play-pause"))
          (bind "XF86AudioPrev" (dsp.exec "${lib.getExe pkgs.playerctl} previous"))
          (bind "XF86AudioNext" (dsp.exec "${lib.getExe pkgs.playerctl} next"))
          (bindOpts "XF86AudioRaiseVolume" (dsp.exec "amixer -q sset 'Master' 5%+") { locked = true; repeating = true; })
          (bindOpts "XF86AudioLowerVolume" (dsp.exec "amixer -q sset 'Master' 5%-") { locked = true; repeating = true; })
          (bindOpts "XF86AudioMute" (dsp.exec "amixer -q sset 'Master' toggle") { locked = true; })
          (bindOpts "XF86MonBrightnessUp" (dsp.exec "${lib.getExe pkgs.brightnessctl} s 5%+") { locked = true; repeating = true; })
          (bindOpts "XF86MonBrightnessDown" (dsp.exec "${lib.getExe pkgs.brightnessctl} s 5%-") { locked = true; repeating = true; })
          (bindOpts "SUPER + mouse:272" dsp.drag { mouse = true; })
          (bindOpts "SUPER + mouse:273" dsp.resize { mouse = true; })
        ];
      };
    };
  };
}
