# Greeter — greetd/tuigreet, themed from the same theme-state.json that
# drives the desktop (nomarchy.system.stateFile; the Plymouth model:
# baked at SYSTEM rebuild, so it follows the theme as of the last
# sys-update, not the last instant apply).
#
# tuigreet draws on the virtual console with the 16 ANSI slots, so the
# theming is two-part:
#   1. console.colors — the VT palette becomes the theme's ansi[] hexes
#      (which also themes raw ttys and the LUKS passphrase prompt: the
#      same JSON reaches every pre-session surface).
#   2. --theme — tuigreet components on NAMED slots (its parser is
#      ratatui Color::from_str; names map to the standard indexes, e.g.
#      blue=4, gray=7, white=15, so the palette above hands them the
#      theme's colors). ANSI "black" stays dark even in light themes —
#      the greeter reads terminal-dark there, the same convention every
#      terminal applies to ANSI colors.
{ config, lib, pkgs, ... }:

let
  cfg = config.nomarchy.system;
  distroName = config.system.nixos.distroName;

  state =
    if cfg.stateFile != null
    then builtins.fromJSON (builtins.readFile cfg.stateFile)
    else { };
  # A sparse/hand-rolled state without a proper ansi block just skips the
  # theming (stock tuigreet grey) — never an eval error.
  ansi = state.ansi or [ ];
  themed = builtins.isList ansi && builtins.length ansi == 16;

  tuigreetTheme = lib.concatStringsSep ";" [
    "container=black" # ansi[0] — the theme's terminal background
    "border=blue"     # ansi[4] — the accent family in every shipped palette
    "title=cyan"
    "greet=cyan"
    "prompt=green"
    "input=white"     # ansi[15] — bright foreground
    "action=blue"
    "button=yellow"
    "time=cyan"
    "text=gray"       # ansi[7] — muted foreground
  ];
in
{
  config = {
    # VT palette from the theme (RRGGBB, no #; lands as vt.default_* kernel
    # params). mkDefault so a downstream console.colors wins.
    console.colors = lib.mkIf themed (lib.mkDefault (map (lib.removePrefix "#") ansi));

    services.greetd = lib.mkIf cfg.greeter.enable {
      enable = lib.mkDefault true;
      settings = {
        default_session = {
          # start-hyprland is Hyprland 0.55's watchdog launcher; running
          # the bare binary makes every session print a warning.
          command = lib.mkDefault ("${pkgs.tuigreet}/bin/tuigreet --time --remember --greeting 'Welcome to ${distroName}'"
            + lib.optionalString themed " --theme '${tuigreetTheme}'"
            + " --cmd start-hyprland");
          user = "greeter";
        };
        # Boot straight into the session once; logout → normal greeter.
        initial_session = lib.mkIf (cfg.greeter.autoLogin != null) {
          command = "start-hyprland";
          user = cfg.greeter.autoLogin;
        };
      };
    };
  };
}
