{
  config,
  lib,
  pkgs,
  ...
}:
let
  dotfiles = "${config.home.homeDirectory}/ndots/modules/home-manager/hyprland/hypr";
in
{
  options.custom.hyprland.enable = lib.mkEnableOption "Hyprland user config";

  config = lib.mkIf config.custom.hyprland.enable {

    systemd.user.targets.hyprland-session = {
      Unit = {
        Description = "hyprland compositor session";
        BindsTo = [ "graphical-session.target" ];
        Wants = [ "graphical-session-pre.target" ];
        After = [ "graphical-session-pre.target" ];
      };
    };
    wayland.windowManager.hyprland.settings.input.numlock_by_default = true;

    xdg.configFile."hypr/hyprland.lua".text = ''
            local home = os.getenv("HOME")
            local config_dir = home .. "/.config/hypr"
            package.path = config_dir .. "/?.lua;" .. config_dir .. "/?/init.lua;" .. package.path

            -- Monitors ----------------------------------------
            hl.monitor({
            	output = "DP-1",
            	mode = "1920x1080@239.96Hz",
            	position = "1080x0",
            	scale = 1,
            })

            -- Looks ----------------------------------------
            hl.env("HYPRCURSOR_THEME", "Bibata-Modern-Ice-Right")
            hl.env("HYPRCURSOR_SIZE", "24")

            hl.config({
            	input = {
            		kb_layout = "us,us",
            		kb_variant = ",intl",
            		kb_options = "grp:alt_shift_toggle",
            	},
            	general = {
            		gaps_in = 7,
            		gaps_out = 10,
            		border_size = 2,
            		col = {
            			active_border = "rgba(ebcc71ff)",
            			inactive_border = "rgba(54461eff)",
            		},
            		layout = "dwindle",
            	},
            	scrolling = {
            		fullscreen_on_one_column = true,
            		column_width = 0.95,
            		focus_fit_method = 0,
            	},
            	dwindle = {
            		preserve_split = true,
            	},
            	master = {
            		new_status = "slave",
            		allow_small_split = false,
            		special_scale_factor = 0.75,
            		mfact = 0.40,
            		orientation = "center",
            		new_on_top = true,
            	},
            })

            hl.device({
            	name = "8bitdo-retro-18-numpad-keyboard",
            	kb_options = "numpad:mac",
            	numlock_by_default = true,
            })

            hl.config({
            	decoration = {
            		rounding = 15,
            		rounding_power = 2,
            		active_opacity = 1.0,
            		inactive_opacity = 0.75,
            		fullscreen_opacity = 1.0,
            		blur = {
            			enabled = true,
            			size = 1,
            			passes = 2,
            			new_optimizations = true,
            			vibrancy = 0.5,
            			vibrancy_darkness = 0.2,
            		},
            		shadow = {
            			enabled = true,
            			range = 15,
            			render_power = 3,
            			color = "rgba(121212aa)",
            		},
            	},
            })

            hl.layer_rule({
            	name = "swaync-control-center-blur",
            	match = { namespace = "swaync-control-center" },
            	blur = true,
            	dim_around = true,
            	ignore_alpha = 0.5,
            	no_screen_share = true,
            })
            hl.layer_rule({
            	name = "swaync-notification-blur",
            	match = { namespace = "swaync-notification-window" },
            	blur = true,
            	ignore_alpha = 0.5,
            	no_screen_share = true,
            })

            -- Animations ----------------------------------------
            hl.config({ animations = { enabled = true } })

            -- Bezier curves
            hl.curve("easeOutQuint", { type = "bezier", points = { { 0.23, 1 }, { 0.32, 1 } } })
            hl.curve("easeInOutCubic", { type = "bezier", points = { { 0.65, 0.05 }, { 0.36, 1 } } })
            hl.curve("linear", { type = "bezier", points = { { 0, 0 }, { 1, 1 } } })
            hl.curve("almostLinear", { type = "bezier", points = { { 0.5, 0.5 }, { 0.75, 1 } } })
            hl.curve("quick", { type = "bezier", points = { { 0.15, 0 }, { 0.1, 1 } } })

            -- Animations
            hl.animation({ leaf = "global", enabled = true, speed = 10, bezier = "default" })
            hl.animation({ leaf = "border", enabled = true, speed = 5.39, bezier = "easeOutQuint" })
            hl.animation({ leaf = "windows", enabled = true, speed = 4.79, bezier = "easeOutQuint" })
            hl.animation({ leaf = "windowsIn", enabled = true, speed = 4.1, bezier = "easeOutQuint", style = "popin 95%" })
            hl.animation({ leaf = "windowsOut", enabled = true, speed = 1.49, bezier = "linear", style = "popin 95%" })
            hl.animation({ leaf = "fadeIn", enabled = true, speed = 1.73, bezier = "almostLinear" })
            hl.animation({ leaf = "fadeOut", enabled = true, speed = 1.46, bezier = "almostLinear" })
            hl.animation({ leaf = "fade", enabled = true, speed = 3.03, bezier = "quick" })
            hl.animation({ leaf = "layers", enabled = true, speed = 3.81, bezier = "easeOutQuint" })
            hl.animation({ leaf = "layersIn", enabled = true, speed = 4, bezier = "easeOutQuint", style = "fade" })
            hl.animation({ leaf = "layersOut", enabled = true, speed = 1.5, bezier = "linear", style = "fade" })
            hl.animation({ leaf = "fadeLayersIn", enabled = true, speed = 1.79, bezier = "almostLinear" })
            hl.animation({ leaf = "fadeLayersOut", enabled = true, speed = 1.39, bezier = "almostLinear" })
            hl.animation({ leaf = "workspaces", enabled = true, speed = 1.94, bezier = "almostLinear", style = "slidefade 10%" })
            hl.animation({ leaf = "workspacesIn", enabled = true, speed = 1.21, bezier = "almostLinear", style = "slidefade 10%" })
            hl.animation({ leaf = "workspacesOut", enabled = true, speed = 1.94, bezier = "almostLinear", style = "slidefade 10%" })

            -- Autostart ----------------------------------------
            hl.on("hyprland.start", function()
            	hl.exec_cmd("dbus-update-activation-environment --systemd WAYLAND_DISPLAY XDG_CURRENT_DESKTOP HYPRLAND_INSTANCE_SIGNATURE")
            	hl.exec_cmd("systemctl --user start hyprland-session.target")
            	hl.exec_cmd("waybar")
            	hl.exec_cmd("hypridle")
            	hl.exec_cmd("swaync")
      	      hl.exec_cmd("hyprctl setcursor Bibata-Modern-Ice-Right 24")
            end)

            -- Programs ----------------------------------------
            local p = {
            	terminal = "alacritty",
            	file_manager = "thunar",
            	menu = "pkill rofi || " .. home .. "/.config/rofi/launchers/type-7/launcher.sh",
            	logout_menu = "wlogout -b 5 -T 400 -B 400",
            	toggle_notifications = "swaync-client -t -sw",
            	screen_ocr = home .. "/.local/bin/read-screen",
            }

            -- Binds ----------------------------------------
            local mod = "SUPER"
            local mod_shft = "SUPER + SHIFT"
            local mod_ctrl = "SUPER + CTRL"
            local mod_alt = "SUPER + ALT"

            -- ---------- App launchers / global actions ----------
            hl.bind(mod .. " + Return", hl.dsp.exec_cmd(p.terminal))
            hl.bind(mod .. " + Q", hl.dsp.window.close())
            hl.bind(mod_shft .. " + Q", hl.dsp.exec_cmd("killall zoom"))
            hl.bind(mod .. " + E", hl.dsp.exec_cmd(p.file_manager))
            hl.bind(mod .. " + V", hl.dsp.window.float({ action = "toggle" }))
            hl.bind(mod .. " + F", hl.dsp.window.fullscreen())
            hl.bind(mod .. " + M", hl.dsp.layout("togglesplit")) -- dwindle
            hl.bind(mod .. " + N", hl.dsp.exec_cmd(p.toggle_notifications))
            hl.bind(mod .. " + Space", hl.dsp.exec_cmd(p.menu))
            hl.bind("CTRL + ALT + DELETE", hl.dsp.exec_cmd(p.logout_menu))

            -- ---------- Focus movement (vim) ----------
            hl.bind(mod .. " + H", hl.dsp.focus({ direction = "left" }))
            hl.bind(mod .. " + L", hl.dsp.focus({ direction = "right" }))
            hl.bind(mod .. " + K", hl.dsp.focus({ direction = "up" }))
            hl.bind(mod .. " + J", hl.dsp.focus({ direction = "down" }))

            -- ---------- Move window ----------
            hl.bind(mod_shft .. " + H", hl.dsp.window.move({ direction = "left" }))
            hl.bind(mod_shft .. " + L", hl.dsp.window.move({ direction = "right" }))
            hl.bind(mod_shft .. " + K", hl.dsp.window.move({ direction = "up" }))
            hl.bind(mod_shft .. " + J", hl.dsp.window.move({ direction = "down" }))

            -- ---------- Splitratio (dwindle layoutmsg) ----------
            hl.bind(mod .. " + comma", hl.dsp.layout("splitratio -0.1"))
            hl.bind(mod .. " + period", hl.dsp.layout("splitratio 0.1"))

            -- ---------- Workspaces (Y U I O P -> 1..5) ----------
            local ws_keys = { Y = 1, U = 2, I = 3, O = 4, P = 5 }
            for key, ws in pairs(ws_keys) do
            	hl.bind(mod .. " + " .. key, hl.dsp.focus({ workspace = ws }))
            	hl.bind(mod_shft .. " + " .. key, hl.dsp.window.move({ workspace = ws }))
            end

            -- ---------- Special workspace (scratchpad) ----------
            hl.bind(mod .. " + S", hl.dsp.workspace.toggle_special("magic"))
            hl.bind(mod_shft .. " + S", hl.dsp.window.move({ workspace = "special:magic" }))

            -- ---------- Workspace scroll ----------
            hl.bind(mod .. " + mouse_down", hl.dsp.focus({ workspace = "e+1" }))
            hl.bind(mod .. " + mouse_up", hl.dsp.focus({ workspace = "e-1" }))

            -- ---------- Mouse drag/resize ----------
            hl.bind(mod .. " + mouse:272", hl.dsp.window.drag(), { mouse = true })
            hl.bind(mod .. " + mouse:273", hl.dsp.window.resize(), { mouse = true })

            -- ---------- Multimedia (locked + repeating) ----------
            local el = { locked = true, repeating = true }
            hl.bind("XF86AudioRaiseVolume", hl.dsp.exec_cmd("wpctl set-volume @DEFAULT_AUDIO_SINK@ 5%+"), el)
            hl.bind("XF86AudioLowerVolume", hl.dsp.exec_cmd("wpctl set-volume @DEFAULT_AUDIO_SINK@ 5%-"), el)
            hl.bind("XF86AudioMute", hl.dsp.exec_cmd("wpctl set-mute @DEFAULT_AUDIO_SINK@ toggle"), el)
            hl.bind("XF86AudioMicMute", hl.dsp.exec_cmd("wpctl set-mute @DEFAULT_AUDIO_SOURCE@ toggle"), el)
            hl.bind("XF86MonBrightnessUp", hl.dsp.exec_cmd("brightnessctl s 10%+"), el)
            hl.bind("XF86MonBrightnessDown", hl.dsp.exec_cmd("brightnessctl s 10%-"), el)

            -- ---------- Media (locked, no repeat) ----------
            local l = { locked = true }
            hl.bind("XF86AudioNext", hl.dsp.exec_cmd("playerctl next"), l)
            hl.bind("XF86AudioPause", hl.dsp.exec_cmd("playerctl play-pause"), l)
            hl.bind("XF86AudioPlay", hl.dsp.exec_cmd("playerctl play-pause"), l)
            hl.bind("XF86AudioPrev", hl.dsp.exec_cmd("playerctl previous"), l)

            -- ---------- Screenshots ----------
            hl.bind(mod_shft .. " + 2", hl.dsp.exec_cmd("hyprshot -m output -m DP-1 -o ~/Pictures/Screenshots"))
            hl.bind(mod_shft .. " + 3", hl.dsp.exec_cmd("hyprshot -m window -m active -o ~/Pictures/Screenshots"))
            hl.bind(mod_shft .. " + 4", hl.dsp.exec_cmd("hyprshot -m region -o ~/Pictures/Screenshots"))

            -- ---------- OBS Recording ----------
            hl.bind(mod_shft .. " + 9", hl.dsp.exec_cmd("obs-cmd recording toggle"))
            hl.bind(mod .. " + 9", hl.dsp.exec_cmd("obs-cmd recording toggle-pause"))

            -- Disable animations on the screenshot selection layer
            hl.layer_rule({
            	name = "no-anim-selection",
            	match = { namespace = "selection" },
            	no_anim = true,
            })

            hl.bind(mod_shft .. " + 0", hl.dsp.exec_cmd(p.screen_ocr))

            -- ---------- Lock / suspend ----------
            hl.bind(mod_alt .. " + L", hl.dsp.exec_cmd("hyprlock"))
            hl.bind(mod .. " + ALT + CTRL + L", hl.dsp.exec_cmd("systemctl suspend"))

            -- ---------- Waybar reload ----------
            hl.bind(mod_alt .. " + R", hl.dsp.exec_cmd("/home/jpporta/.config/waybar/scripts/launch.sh"))

            -- ---------- Dictation ----------
            hl.bind(mod .. " + code:71", hl.dsp.exec_cmd("dictate-toggle"))
            hl.bind(mod .. " + code:72", hl.dsp.exec_cmd("dictate-history"))
            hl.bind(mod_shft .. " + code:71", hl.dsp.exec_cmd("dictate-toggle -c"))
            -- ---------- misc ----------
            hl.config({
            	misc = {
            		force_default_wallpaper = 0,
            		disable_hyprland_logo = true,
            	},
            })

            -- ---------- window rules ----------
            -- Zoom Behave -----------
            hl.window_rule({
              match = { class = "^zoom$", title = "^annotate_toolbar$" },
              float = true,
            })
            hl.window_rule({
              match = { class = "^zoom$" },
              no_blur = true,
              border_size = 0,
              no_initial_focus = true,
              no_shadow = true,
            })

            -- Ignore maximize requests from apps.
            hl.window_rule({
            	name = "Ignore Maximize Requests",
            	match = { class = ".*" },
            	suppress_event = "maximize",
            })

            -- Fix some dragging issues with XWayland.
            hl.window_rule({
            	name = "XWayland Drag Fix",
            	match = {
            		xwayland = 1,
            		title = "^$",
            		class = "^$",
            		float = true,
            		fullscreen = false,
            		pin = false,
            	},
            	no_focus = true,
            })

            hl.window_rule({
                    name = "Pinentry Center",
                    match = { class = "^(pinentry-.*)$" },
                    float = true,
                    center = true,
                    stay_focused = true,
            })

            -- Picture-in-Picture: pinned floating mini-player in bottom-right quadrant.
            hl.window_rule({
            	name = "PIP",
            	match = { title = "Picture-in-Picture" },
            	pin = 1,
            	float = 1,
            	size = "(monitor_w/4) (monitor_h/4)",
            	move = "(3*monitor_w/4)-22 (monitor_h-window_h-22)",
            })

            hl.env("QT_QPA_PLATFORMTHEME", "hyprqt6engine")
    '';
  };
}
