local mainMod = "SUPER"

-- Apps
local terminal = "uwsm app -- kitty"
local term_tmux = "uwsm app -- kitty -e tmux"
local term_tmux_append = "uwsm app -- kitty -e tmux a"
local editor = "uwsm app -- kitty -e nvim"
local alteditor = "uwsm app -- zeditor"
local filemanager = "uwsm app -- nautilus"
local launcher = "uwsm app -- owlry"
local devlauncher = "uwsm app -- owlry --profile dev"
local clipman = "uwsm app -- owlry -m clipboard"
local browser = "uwsm app -- firefox"
local browserprv = "uwsm app -- firefox --private-window"
local browsernewinst = "uwsm app -- firefox --new-instance"
local altbrowser = "uwsm app -- chromium"
local taskman = "uwsm app -- owlry -m uuctl"
local pwdmgr = "uwsm app -- bitwarden-desktop"
local soundctl = "uwsm app -- pwvucontrol"

local notcenter = "uwsm app -- swaync-client -t -sw"
local notdnd = "uwsm app -- swaync-client -d"
local nothide = "uwsm app -- swaync-client --hide-latest"

-- First-class launchers
hl.bind(mainMod .. " + Return",       hl.dsp.exec_cmd(terminal),     { description = "Terminal" })
hl.bind(mainMod .. " + SHIFT + Return", hl.dsp.exec_cmd(term_tmux),  { description = "Terminal (tmux)" })
hl.bind(mainMod .. " + CTRL + Return",  hl.dsp.exec_cmd(term_tmux_append), { description = "Terminal (attach tmux)" })
hl.bind(mainMod .. " + F1",           hl.dsp.exec_cmd("qs ipc call keybinds toggle"), { description = "Show keybinds" })
hl.bind(mainMod .. " + ALT + F1",     hl.dsp.exec_cmd("hypr-show-binds"),  { description = "Show raw binds (owlry)" })
hl.bind(mainMod .. " + E",            hl.dsp.exec_cmd(filemanager),   { description = "File manager" })
hl.bind(mainMod .. " + W",            hl.dsp.exec_cmd(browser),       { description = "Browser" })
hl.bind(mainMod .. " + SHIFT + W",    hl.dsp.exec_cmd(browserprv),    { description = "Browser (private)" })
hl.bind(mainMod .. " + CTRL + W",     hl.dsp.exec_cmd(altbrowser),    { description = "Chromium" })
hl.bind(mainMod .. " + ALT + W",      hl.dsp.exec_cmd(browsernewinst),{ description = "Firefox (new instance)" })
hl.bind(mainMod .. " + Space",        hl.dsp.exec_cmd(launcher),      { description = "App launcher" })
hl.bind(mainMod .. " + D",            hl.dsp.exec_cmd(devlauncher),   { description = "App launcher (dev)" })

-- Secondary launchers
hl.bind(mainMod .. " + SHIFT + E", hl.dsp.exec_cmd(editor),    { description = "Neovim" })
hl.bind(mainMod .. " + CTRL + E",  hl.dsp.exec_cmd(alteditor), { description = "Zed editor" })
hl.bind(mainMod .. " + X",         hl.dsp.exec_cmd(taskman),   { description = "Task manager" })
hl.bind(mainMod .. " + C",         hl.dsp.exec_cmd(clipman),   { description = "Clipboard history" })
hl.bind(mainMod .. " + F4",        hl.dsp.exec_cmd(soundctl),  { description = "Audio mixer" })

-- Quick Workspaces submap
hl.bind(mainMod .. " + A", hl.dsp.submap("quickws"), { description = "Quick workspace jump" })
hl.define_submap("quickws", function()
  hl.bind("z", function() hl.dispatch(hl.dsp.focus({ workspace = 1 })); hl.dispatch(hl.dsp.submap("reset")) end)
  hl.bind("d", function() hl.dispatch(hl.dsp.focus({ workspace = 2 })); hl.dispatch(hl.dsp.submap("reset")) end)
  hl.bind("a", function() hl.dispatch(hl.dsp.focus({ workspace = 3 })); hl.dispatch(hl.dsp.submap("reset")) end)
  hl.bind("x", function() hl.dispatch(hl.dsp.focus({ workspace = 4 })); hl.dispatch(hl.dsp.submap("reset")) end)
  hl.bind("s", function() hl.dispatch(hl.dsp.focus({ workspace = 5 })); hl.dispatch(hl.dsp.submap("reset")) end)
  hl.bind("c", function() hl.dispatch(hl.dsp.focus({ workspace = 6 })); hl.dispatch(hl.dsp.submap("reset")) end)
  hl.bind("Escape", hl.dsp.submap("reset"))
  hl.bind("Return", hl.dsp.submap("reset"))
end)

-- Notifications
hl.bind(mainMod .. " + grave",             hl.dsp.exec_cmd(notcenter), { description = "Notification center" })
hl.bind(mainMod .. " + SHIFT + grave",     hl.dsp.exec_cmd(notdnd),    { description = "Toggle do-not-disturb" })
hl.bind(mainMod .. " + CTRL + grave",      hl.dsp.exec_cmd(nothide),   { description = "Hide latest notification" })

-- Session
hl.bind(mainMod .. " + Pause",             hl.dsp.exec_cmd("hyprlock"),           { description = "Lock screen" })
hl.bind(mainMod .. " + SHIFT + Pause",     hl.dsp.exec_cmd("owlry-power-menu"),   { description = "Power menu" })
hl.bind(mainMod .. " + End",               hl.dsp.exec_cmd("hyprlock"),           { description = "Lock screen" })
hl.bind(mainMod .. " + SHIFT + End",       hl.dsp.exec_cmd("owlry-power-menu"),   { description = "Power menu" })

-- Window management
hl.bind(mainMod .. " + Q",         hl.dsp.window.close(),                        { description = "Close window" })
hl.bind(mainMod .. " + SHIFT + Q", hl.dsp.window.kill(),                         { description = "Kill window" })
hl.bind(mainMod .. " + F",         hl.dsp.window.float(),                        { description = "Toggle float" })
hl.bind(mainMod .. " + SHIFT + F", hl.dsp.window.fullscreen({ action = "toggle" }), { description = "Toggle fullscreen" })
hl.bind(mainMod .. " + P",         hl.dsp.window.pin(),                          { description = "Pin window" })
hl.bind(mainMod .. " + U",         hl.dsp.focus({ urgent_or_last = true }),       { description = "Focus urgent / last" })
hl.bind(mainMod .. " + V",         hl.dsp.window.center(),                       { description = "Center window" })

-- Special workspaces
hl.bind(mainMod .. " + SHIFT + Space", hl.dsp.workspace.toggle_special(),              { description = "Toggle scratchpad" })
hl.bind(mainMod .. " + CTRL + Space",  hl.dsp.window.move({ workspace = "special" }),  { description = "Move to scratchpad" })
hl.bind(mainMod .. " + N",             hl.dsp.workspace.toggle_special("passwordmgr"), { description = "Password manager scratchpad" })

-- Monitor focus
hl.bind(mainMod .. " + I",         hl.dsp.focus({ monitor = "l" }),              { description = "Focus left monitor" })
hl.bind(mainMod .. " + O",         hl.dsp.focus({ monitor = "r" }),              { description = "Focus right monitor" })
hl.bind(mainMod .. " + SHIFT + I", hl.dsp.workspace.move({ monitor = "l" }),     { description = "Move workspace to left monitor" })
hl.bind(mainMod .. " + SHIFT + O", hl.dsp.workspace.move({ monitor = "r" }),     { description = "Move workspace to right monitor" })

-- ─── Workspace layout state ───────────────────────────────────────────────────
-- Shared with layout.lua (the window.active handler reads it for swap layouts).
local ws_layouts     = require("state").ws_layouts
local ws_cycle_order = {
  "master",
  "lua:master-scroll",
  "lua:slave-master-scroll",
  "lua:center-master-scroll",
  "lua:top-master-scroll",
  "lua:center-master-scroll-v",
  "lua:master-swap",
  "lua:slave-master-swap",
  "lua:top-master-swap",
  "scrolling",
  "monocle",
}

local function active_ws_id()
  local w = hl.get_active_window()
  return w and w.workspace and w.workspace.id
end

local function cur_ws_layout()
  local id = active_ws_id()
  return (id and ws_layouts[id]) or "master"
end

local function set_ws_layout(layout)
  local id = active_ws_id()
  hl.notification.create({ text = "Layout: " .. layout, timeout = 1800, icon = "info" })
  if not id then return end
  ws_layouts[id] = layout
  hl.workspace_rule({ workspace = tostring(id), layout = layout })
end

local function ws_toggle_ms()
  local cur = cur_ws_layout()
  -- Any master variant → scrolling; scrolling/monocle → master
  local next_layout = (cur == "scrolling" or cur == "monocle") and "master" or "scrolling"
  set_ws_layout(next_layout)
end

local function ws_cycle()
  local cur = cur_ws_layout()
  local next_layout = ws_cycle_order[1]
  for i, v in ipairs(ws_cycle_order) do
    if v == cur then
      next_layout = ws_cycle_order[(i % #ws_cycle_order) + 1]
      break
    end
  end
  set_ws_layout(next_layout)
end

local function move_window(dir)
  return function()
    local cur = cur_ws_layout()
    if cur == "scrolling" and (dir == "l" or dir == "r") then
      hl.dispatch(hl.dsp.layout("swapcol " .. dir))
    elseif cur ~= "monocle" then
      hl.dispatch(hl.dsp.window.move({ direction = dir }))
    end
  end
end

local function nav(dir)
  return function()
    local cur = cur_ws_layout()
    if cur == "scrolling" then
      hl.dispatch(hl.dsp.layout("focus " .. dir))
    elseif cur == "master" and dir == "d" then
      hl.dispatch(hl.dsp.layout("addmaster"))
    elseif cur == "master" and dir == "u" then
      hl.dispatch(hl.dsp.layout("removemaster"))
    else
      hl.dispatch(hl.dsp.focus({ direction = dir }))
    end
  end
end

local function resize_h(sign)
  return function()
    local cur = cur_ws_layout()
    if cur == "scrolling" then
      hl.dispatch(hl.dsp.layout("colresize " .. sign .. "0.1"))
    elseif cur ~= "monocle" then
      hl.dispatch(hl.dsp.window.resize({ x = sign == "+" and 25 or -25, y = 0, relative = true }))
    end
  end
end

-- Layout
hl.bind(mainMod .. " + comma",  ws_toggle_ms, { description = "Toggle master/scroll layout" })
hl.bind(mainMod .. " + period", ws_cycle,     { description = "Cycle workspace layout" })

-- Split ratio (ALT+1-9 = 10%-90%, ALT+0 = 95%)
-- mfact exact for master/custom layouts, colresize for built-in scrolling
local mfact_layouts = {
  ["master"]                     = true,
  ["lua:master-scroll"]          = true,
  ["lua:slave-master-scroll"]    = true,
  ["lua:center-master-scroll"]   = true,
  ["lua:top-master-scroll"]      = true,
  ["lua:center-master-scroll-v"] = true,
  ["lua:master-swap"]            = true,
  ["lua:slave-master-swap"]      = true,
  ["lua:top-master-swap"]        = true,
}
local function layout_ratio(ratio)
  return function()
    local cur = cur_ws_layout()
    if mfact_layouts[cur] then
      hl.dispatch(hl.dsp.layout("mfact exact " .. ratio))
    elseif cur == "scrolling" then
      hl.dispatch(hl.dsp.layout("colresize " .. ratio))
    end
  end
end
local function layout_ratio_delta(delta)
  return function()
    local cur = cur_ws_layout()
    local sign = delta > 0 and "+" or ""
    if mfact_layouts[cur] then
      hl.dispatch(hl.dsp.layout("mfact " .. sign .. delta))
    elseif cur == "scrolling" then
      hl.dispatch(hl.dsp.layout("colresize " .. sign .. delta))
    end
  end
end
for i = 1, 9 do
  hl.bind(mainMod .. " + ALT + " .. i, layout_ratio(i / 10), { description = "Split ratio " .. (i * 10) .. "%" })
end
hl.bind(mainMod .. " + ALT + 0",      layout_ratio(0.95),       { description = "Split ratio 95%" })
hl.bind(mainMod .. " + ALT + comma",  layout_ratio_delta(-0.05), { description = "Split ratio -5%" })
hl.bind(mainMod .. " + ALT + period", layout_ratio_delta(0.05),  { description = "Split ratio +5%" })

-- Scrolling layout: resize ALL columns
for i = 1, 9 do
  local ratio = i / 10
  hl.bind(mainMod .. " + CTRL + ALT + " .. i, function()
    if cur_ws_layout() == "scrolling" then
      hl.dispatch(hl.dsp.layout("colresize all " .. ratio))
    end
  end, { description = "All columns " .. (i * 10) .. "% (scrolling)" })
end
hl.bind(mainMod .. " + CTRL + ALT + 0", function()
  if cur_ws_layout() == "scrolling" then
    hl.dispatch(hl.dsp.layout("colresize all 0.95"))
  end
end, { description = "All columns 95% (scrolling)" })

-- Smart Gaps Toggle
hl.bind(mainMod .. " + SHIFT + G", function()
  local gapsIn = hl.get_config("general.gaps_in")
  local current = type(gapsIn) == "table" and (gapsIn.top or 0) or (gapsIn or 0)
  if current ~= 0 then
    hl.config({ general = { gaps_in = 0, gaps_out = 0 } })
    hl.notification.create({ text = "Gaps: OFF", timeout = 2000, icon = "info" })
  else
    hl.config({ general = { gaps_in = 5, gaps_out = 5 } })
    hl.notification.create({ text = "Gaps: ON", timeout = 2000, icon = "ok" })
  end
end, { description = "Toggle gaps" })

-- Vim-like navigation
hl.bind(mainMod .. " + H", hl.dsp.focus({ direction = "l" }), { description = "Focus left" })
hl.bind(mainMod .. " + L", hl.dsp.focus({ direction = "r" }), { description = "Focus right" })
hl.bind(mainMod .. " + K", hl.dsp.focus({ direction = "u" }), { description = "Focus up" })
hl.bind(mainMod .. " + J", hl.dsp.focus({ direction = "d" }), { description = "Focus down" })

-- Move window (layout-aware)
hl.bind(mainMod .. " + SHIFT + H", move_window("l"), { description = "Move window left" })
hl.bind(mainMod .. " + SHIFT + L", move_window("r"), { description = "Move window right" })
hl.bind(mainMod .. " + SHIFT + K", move_window("u"), { description = "Move window up" })
hl.bind(mainMod .. " + SHIFT + J", move_window("d"), { description = "Move window down" })

-- Resize submap
hl.bind(mainMod .. " + R", hl.dsp.submap("resize"), { description = "Resize mode" })
hl.define_submap("resize", function()
  hl.bind("h",         hl.dsp.window.resize({ x = -25, y = 0,  relative = true }), { repeating = true })
  hl.bind("l",         hl.dsp.window.resize({ x = 25,  y = 0,  relative = true }), { repeating = true })
  hl.bind("k",         hl.dsp.window.resize({ x = 0,   y = -25, relative = true }), { repeating = true })
  hl.bind("j",         hl.dsp.window.resize({ x = 0,   y = 25,  relative = true }), { repeating = true })
  hl.bind("SHIFT + h", hl.dsp.window.resize({ x = -60, y = 0,  relative = true }), { repeating = true })
  hl.bind("SHIFT + l", hl.dsp.window.resize({ x = 60,  y = 0,  relative = true }), { repeating = true })
  hl.bind("SHIFT + k", hl.dsp.window.resize({ x = 0,   y = -60, relative = true }), { repeating = true })
  hl.bind("SHIFT + j", hl.dsp.window.resize({ x = 0,   y = 60,  relative = true }), { repeating = true })
  hl.bind("Escape", hl.dsp.submap("reset"))
  hl.bind("Return", hl.dsp.submap("reset"))
end)

-- Zoom submap
hl.bind(mainMod .. " + M", hl.dsp.submap("zoom"), { description = "Zoom mode" })
hl.define_submap("zoom", function()
  hl.bind("equal",  hl.dsp.exec_cmd("hypr-zoom-step +0.2"))
  hl.bind("minus",  hl.dsp.exec_cmd("hypr-zoom-step -0.2"))
  hl.bind("0",      hl.dsp.exec_cmd("hypr-zoom-step reset"))
  hl.bind("Escape", hl.dsp.submap("reset"))
  hl.bind("Return", hl.dsp.submap("reset"))
end)

-- Workspace cycling
hl.bind(mainMod .. " + Tab",         hl.dsp.focus({ workspace = "m+1" }), { description = "Next workspace" })
hl.bind(mainMod .. " + SHIFT + Tab", hl.dsp.focus({ workspace = "m-1" }), { description = "Previous workspace" })

-- Switch Workspaces 1-10 (IDs 21-30 in setup)
for i = 1, 9 do
  hl.bind(mainMod .. " + " .. i,         hl.dsp.focus({ workspace = 20 + i }),       { description = "Workspace " .. i })
  hl.bind(mainMod .. " + SHIFT + " .. i, hl.dsp.window.move({ workspace = 20 + i }), { description = "Move to workspace " .. i })
end
hl.bind(mainMod .. " + 0",         hl.dsp.focus({ workspace = 30 }),       { description = "Workspace 10" })
hl.bind(mainMod .. " + SHIFT + 0", hl.dsp.window.move({ workspace = 30 }), { description = "Move to workspace 10" })

-- Groups
local function smart_group(dir)
  local w = hl.get_active_window()
  local grouped = w and type(w.grouped) == "table" and #w.grouped > 0
  if grouped then
    hl.dispatch(hl.dsp.window.move({ out_of_group = true }))
  else
    hl.dispatch(hl.dsp.window.move({ into_or_create_group = dir }))
  end
end

hl.bind(mainMod .. " + G",               hl.dsp.group.toggle(),                        { description = "Toggle group" })
hl.bind(mainMod .. " + CTRL + G",        hl.dsp.window.move({ out_of_group = true }),   { description = "Leave group" })
hl.bind(mainMod .. " + CTRL + H",        hl.dsp.group.prev(),                          { description = "Group: previous tab" })
hl.bind(mainMod .. " + CTRL + L",        hl.dsp.group.next(),                          { description = "Group: next tab" })
hl.bind(mainMod .. " + CTRL + J",        hl.dsp.group.move_window({ forward = true }),  { description = "Group: move tab forward" })
hl.bind(mainMod .. " + CTRL + K",        hl.dsp.group.move_window({ forward = false }), { description = "Group: move tab back" })
hl.bind(mainMod .. " + CTRL + SHIFT + H", function() smart_group("l") end, { description = "Smart group left" })
hl.bind(mainMod .. " + CTRL + SHIFT + J", function() smart_group("d") end, { description = "Smart group down" })
hl.bind(mainMod .. " + CTRL + SHIFT + K", function() smart_group("u") end, { description = "Smart group up" })
hl.bind(mainMod .. " + CTRL + SHIFT + L", function() smart_group("r") end, { description = "Smart group right" })
hl.bind(mainMod .. " + Z",               hl.dsp.group.next(),                          { description = "Group: next tab" })
hl.bind(mainMod .. " + SHIFT + Z",       hl.dsp.group.prev(),                          { description = "Group: previous tab" })

-- Layout-aware navigation
hl.bind(mainMod .. " + ALT + H",           nav("l"),       { description = "Nav left (layout-aware)" })
hl.bind(mainMod .. " + ALT + L",           nav("r"),       { description = "Nav right (layout-aware)" })
hl.bind(mainMod .. " + ALT + J",           nav("d"),       { description = "Nav down / add master" })
hl.bind(mainMod .. " + ALT + K",           nav("u"),       { description = "Nav up / remove master" })
hl.bind(mainMod .. " + ALT + Tab",         nav("r"),       { description = "Nav right (layout-aware)" })
hl.bind(mainMod .. " + ALT + SHIFT + Tab", nav("l"),       { description = "Nav left (layout-aware)" })
hl.bind(mainMod .. " + ALT + SHIFT + J",   resize_h("-"),  { description = "Shrink split" })
hl.bind(mainMod .. " + ALT + SHIFT + K",   resize_h("+"),  { description = "Grow split" })

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

-- master-scroll slave scrolling (mouse wheel + bracket fallback)
-- Guard by layout name: built-in and swap layouts error on unknown scroll messages.
local scroll_layouts = {
  ["lua:master-scroll"]          = true,
  ["lua:slave-master-scroll"]    = true,
  ["lua:center-master-scroll"]   = true,
  ["lua:top-master-scroll"]      = true,
  ["lua:center-master-scroll-v"] = true,
}
local function layout_scroll(dir)
  return function()
    if scroll_layouts[cur_ws_layout()] then
      hl.dispatch(hl.dsp.layout(dir))
    end
  end
end
hl.bind(mainMod .. " + mouse_down",   layout_scroll("scrollup"))
hl.bind(mainMod .. " + mouse_up",     layout_scroll("scrolldown"))
hl.bind(mainMod .. " + bracketright", layout_scroll("scrolldown"), { description = "Scroll slave pane down" })
hl.bind(mainMod .. " + bracketleft",  layout_scroll("scrollup"),   { description = "Scroll slave pane up" })

-- Screenshots
hl.bind("Print",               hl.dsp.exec_cmd("grimblast --notify copy screen"),   { description = "Screenshot: full screen" })
hl.bind(mainMod .. " + Print", hl.dsp.exec_cmd("owlry-screenshot-menu"),            { description = "Screenshot menu" })
hl.bind("SHIFT + Print",       hl.dsp.exec_cmd("uwsm app -- kitty --class=scrrec -e wf-recorder -f ~/Videos/scrrec.mkv -y -g \"$(slurp)\""), { description = "Screen record selection" })

-- Multimedia
hl.bind("XF86AudioRaiseVolume",         hl.dsp.exec_cmd("wpctl set-volume @DEFAULT_AUDIO_SINK@ 5%+"),    { repeating = true, description = "Volume up" })
hl.bind("XF86AudioLowerVolume",         hl.dsp.exec_cmd("wpctl set-volume @DEFAULT_AUDIO_SINK@ 5%-"),    { repeating = true, description = "Volume down" })
hl.bind("XF86AudioMute",                hl.dsp.exec_cmd("wpctl set-mute @DEFAULT_AUDIO_SINK@ toggle"),   { locked = true,    description = "Mute" })
hl.bind("SHIFT + XF86AudioRaiseVolume", hl.dsp.exec_cmd("wpctl set-volume @DEFAULT_AUDIO_SOURCE@ 5%+"), { repeating = true, description = "Mic volume up" })
hl.bind("SHIFT + XF86AudioLowerVolume", hl.dsp.exec_cmd("wpctl set-volume @DEFAULT_AUDIO_SOURCE@ 5%-"), { repeating = true, description = "Mic volume down" })
hl.bind("SHIFT + XF86AudioMute",        hl.dsp.exec_cmd("wpctl set-mute @DEFAULT_AUDIO_SOURCE@ toggle"),{ locked = true,    description = "Mic mute" })
hl.bind("XF86AudioPlay",  hl.dsp.exec_cmd("playerctl play-pause"), { locked = true, description = "Play/pause" })
hl.bind("XF86AudioPause", hl.dsp.exec_cmd("playerctl play-pause"), { locked = true, description = "Play/pause" })
hl.bind("XF86AudioNext",  hl.dsp.exec_cmd("playerctl next"),       { locked = true, description = "Next track" })
hl.bind("XF86AudioPrev",  hl.dsp.exec_cmd("playerctl previous"),   { locked = true, description = "Previous track" })

-- Brightness — let brightnessctl do the math, then push the new percentage to
-- the Quickshell OSD (field 4 of `-m` output is the percentage, e.g. "70%").
local function brightness_step(arg)
  -- Single brightnessctl call: `-m s` sets and prints the machine line
  -- (device,class,current,percent,max); field 4 is the new percentage.
  return hl.dsp.exec_cmd(
    "qs ipc call osd brightness \"$(brightnessctl -e4 -n2 -m s " .. arg .. " | cut -d, -f4 | tr -d %)\""
  )
end
hl.bind("XF86MonBrightnessUp",           brightness_step("1%+"), { locked = true, repeating = true, description = "Brightness up (1%)" })
hl.bind("XF86MonBrightnessDown",         brightness_step("1%-"), { locked = true, repeating = true, description = "Brightness down (1%)" })
hl.bind("SHIFT + XF86MonBrightnessUp",   brightness_step("5%+"), { locked = true, repeating = true, description = "Brightness up (5%)" })
hl.bind("SHIFT + XF86MonBrightnessDown", brightness_step("5%-"), { locked = true, repeating = true, description = "Brightness down (5%)" })
hl.bind("CTRL + XF86MonBrightnessUp",    brightness_step("70%"), { locked = true, description = "Brightness 70%" })
hl.bind("CTRL + XF86MonBrightnessDown",  brightness_step("20%"), { locked = true, description = "Brightness 20%" })

-- Blue light filter manual override
-- TODO: Temporary workaround until `hyprctl hyprsunset reset` is supported in local packages.
-- Once supported, replace `get_scheduled_temperature` and `systemctl`/`hyprctl` workaround with `hyprctl hyprsunset reset`.
local function get_scheduled_temperature()
  local time = os.date("*t")
  local mins = time.hour * 60 + time.min
  -- Profiles matching ~/.config/hypr/hyprsunset.conf:
  -- Day: 07:00 (420 mins) -> identity
  -- Evening: 19:30 (1170 mins) -> 4500
  -- Night: 22:30 (1350 mins) -> 3200
  if mins >= 1350 or mins < 420 then
    return 3200
  elseif mins >= 1170 and mins < 1350 then
    return 4500
  else
    return "identity"
  end
end

local bluelight_enabled = true
local function toggle_bluelight()
  bluelight_enabled = not bluelight_enabled
  if bluelight_enabled then
    local target = get_scheduled_temperature()
    if target == "identity" then
      hl.dispatch(hl.dsp.exec_cmd("hyprctl hyprsunset identity"))
      hl.notification.create({ text = "Blue Light Filter: Auto (OFF/Day)", timeout = 1500, icon = "info" })
    else
      hl.dispatch(hl.dsp.exec_cmd("hyprctl hyprsunset temperature " .. tostring(target)))
      hl.notification.create({ text = "Blue Light Filter: Auto (" .. tostring(target) .. "K)", timeout = 1500, icon = "ok" })
    end
  else
    hl.dispatch(hl.dsp.exec_cmd("hyprctl hyprsunset identity"))
    hl.notification.create({ text = "Blue Light Filter: OFF", timeout = 1500, icon = "info" })
  end
end
hl.bind(mainMod .. " + SHIFT + B", toggle_bluelight, { description = "Toggle blue light filter" })

{{- if (index .chezmoi.config.data.tags "laptop") }}

-- ─── Surface Type Cover ──────────────────────────────────────────────────────
local tc_touchpad = "microsoft-surface-type-cover-touchpad"
local tc_keyboard = "microsoft-surface-type-cover-keyboard"

local function device_enabled(name)
  -- Reads live state; falls back to true on any error so toggles still work.
  local ok, v = pcall(hl.get_config, "device[" .. name .. "]:enabled")
  if not ok then return true end
  if v == nil then return true end
  return v ~= false and v ~= 0 and v ~= "false"
end

local function set_device(name, enabled)
  hl.device({ name = name, enabled = enabled })
end

-- SUPER+T: toggle touchpad based on live state (no local-cache desync)
hl.bind(mainMod .. " + T", function()
  local new_state = not device_enabled(tc_touchpad)
  set_device(tc_touchpad, new_state)
  hl.notification.create({
    text = "Touchpad: " .. (new_state and "ON" or "OFF"),
    timeout = 1500,
    icon = new_state and "ok" or "info",
  })
end, { description = "Toggle touchpad" })

-- Tablet-mode switch: fold cover back → disable kb+touchpad, unfold → re-enable
hl.bind("switch:on:Microsoft Surface Type Cover Tablet Mode Switch", function()
  set_device(tc_touchpad, false)
  set_device(tc_keyboard, false)
  hl.notification.create({ text = "Tablet mode", timeout = 1500, icon = "info" })
end, { description = "Tablet mode: disable Type Cover" })

hl.bind("switch:off:Microsoft Surface Type Cover Tablet Mode Switch", function()
  set_device(tc_touchpad, true)
  set_device(tc_keyboard, true)
  hl.notification.create({ text = "Laptop mode", timeout = 1500, icon = "ok" })
end, { description = "Laptop mode: enable Type Cover" })
{{- end }}
