# hyprlock + hypridle — screen locking and idle management, themed from
# theme-state.json. One concern, one file: hypridle drives WHEN (idle
# lock, display off, suspend, lock-before-sleep), hyprlock is the
# themed lock screen itself (also behind the power menu's Lock entry).
{ config, lib, pkgs, ... }:

let
  cfg = config.nomarchy;
  t = cfg.theme;
  c = t.colors;
  inherit (config.nomarchy.lib) rgb;

  # Exits 0 when running on AC: a mains adapter reports `online` 1 (battery
  # supplies have no `online` node, so they never match). Used as
  # `${onAc} || <action>` so the action is skipped while plugged in.
  onAc = pkgs.writeShellScript "nomarchy-on-ac" ''
    for f in /sys/class/power_supply/*/online; do
      [ -r "$f" ] && [ "$(cat "$f")" = "1" ] && exit 0
    done
    exit 1
  '';
in
{
  config = lib.mkIf cfg.idle.enable {
    programs.hyprlock = {
      enable = true;
      settings = {
        general.hide_cursor = true;

        background = [{
          monitor = "";
          color = rgb c.base;
        }];

        input-field = [{
          monitor = "";
          size = "300, 50";
          outline_thickness = t.ui.borderSize;
          dots_size = 0.25;
          outer_color = rgb c.accent;
          inner_color = rgb c.surface;
          font_color = rgb c.text;
          check_color = rgb c.warn;
          fail_color = rgb c.bad;
          rounding = t.ui.rounding;
          placeholder_text = "<i>password…</i>";
        }];

        label = [{
          monitor = "";
          text = "$TIME";
          color = rgb c.text;
          font_size = 64;
          font_family = t.fonts.ui;
          position = "0, 120";
          halign = "center";
          valign = "center";
        }];
      };
    };

    services.hypridle = {
      enable = true;
      settings = {
        general = {
          lock_cmd = "pidof hyprlock || hyprlock";
          # No before_sleep_cmd here: locking before sleep is driven
          # system-side so it can fire for suspend but skip an encrypted
          # hibernate — whose LUKS resume already gates the machine, so a
          # hyprlock on top is a second password (and a Wayland session-lock
          # can't be safely dropped after the fact — killing the locker trips
          # its "go to a tty" crash failsafe). See nomarchy-lock-before-sleep
          # in modules/nixos/default.nix.
          after_sleep_cmd = "hyprctl dispatch dpms on";
        };
        listener = [
          # Lock and screen-off are the same on either power source —
          # they're about privacy and the panel, not battery.
          { timeout = 300; on-timeout = "loginctl lock-session"; }
          {
            timeout = 600;
            on-timeout = "hyprctl dispatch dpms off";
            on-resume = "hyprctl dispatch dpms on";
          }
          # Suspend only on battery, and sooner than the old fixed 30 min
          # (it now only fires unplugged). Plugged in, the machine stays
          # up — long builds, media, presentations aren't killed mid-idle.
          # Closing the lid still suspends on AC (logind's default): that's
          # an explicit "I'm done", distinct from sitting idle.
          { timeout = 900; on-timeout = "${onAc} || systemctl suspend"; }
        ];
      };
    };
  };
}
