# Plymouth boot splash — Nomarchy-branded (ported from the legacy
# iteration), background tinted from the same theme-state.json that
# drives the desktop (nomarchy.system.stateFile, wired automatically by
# lib.mkFlake). One caveat by design: theme switches are Home
# Manager-only and never touch the initrd, so the splash follows the
# theme as of the last SYSTEM rebuild (`sys-update`), not the last
# `nomarchy-theme-sync apply`.
{ config, lib, pkgs, ... }:

let
  cfg = config.nomarchy.system;

  state =
    if cfg.stateFile != null
    then import ../theme-state-read.nix { inherit lib; } cfg.stateFile
    else { };
  colorOf = key: fallback: lib.removePrefix "#" ((state.colors or { }).${key} or fallback);
  # Fallbacks match the distro default theme (Boreal) when stateFile is null.
  base = colorOf "base" "#21272F";
  # Splash elements are recolored from the palette so they read on any
  # base, light or dark: foreground glyphs → text, field/track boxes →
  # surface (raised from base in both polarities), the progress fill →
  # accent. The shipped art is a fixed navy that vanished on dark themes.
  text = colorOf "text" "#D3DAE0";
  surface = colorOf "surface" "#303A46";
  accent = colorOf "accent" "#B79BE8";
  magick = lib.getExe' pkgs.imagemagick "magick";

  # Plymouth's Window.SetBackgroundTopColor takes three floats in
  # 0.0–1.0; the .plymouth metadata's ConsoleLogBackgroundColor takes a
  # 0xRRGGBB hex. Nix has no float math: multiply, integer-divide, pad.
  byteToFloat = n:
    let
      thousandths = (n * 1000) / 255;
      s = toString thousandths;
      padded =
        if lib.stringLength s == 1 then "00${s}"
        else if lib.stringLength s == 2 then "0${s}"
        else s;
    in "0.${padded}";
  channel = off: byteToFloat (lib.fromHexString (lib.substring off 2 base));

  nomarchy-plymouth = pkgs.stdenv.mkDerivation {
    pname = "nomarchy-plymouth";
    version = "1.0";

    src = ./plymouth;

    nativeBuildInputs = [ pkgs.imagemagick ];

    installPhase = ''
      themedir=$out/share/plymouth/themes/nomarchy
      mkdir -p "$themedir"
      cp * "$themedir/"

      # Recolor the splash art from the palette (flat fill, alpha kept) so
      # it reads on any base instead of the shipped fixed navy.
      recolor() { ${magick} "$themedir/$1" -fill "#$2" -colorize 100 "$themedir/$1"; }
      recolor logo.png         ${text}     # centre monogram
      recolor lock.png         ${text}     # password-prompt padlock
      recolor bullet.png       ${text}     # password dots
      recolor entry.png        ${surface}  # password field box
      recolor progress_box.png ${surface}  # progress track
      recolor progress_bar.png ${accent}   # progress fill

      # Point the .plymouth metadata into the store
      sed -i "s|/usr/share/plymouth/themes/nomarchy|$themedir|g" \
        "$themedir/nomarchy.plymouth"

      # Bake the theme's base color: RGB floats for the script's
      # Window.SetBackground* calls, 0xRRGGBB for ConsoleLogBackground.
      sed -i \
        -e 's|@BG_R@|${channel 0}|g' \
        -e 's|@BG_G@|${channel 2}|g' \
        -e 's|@BG_B@|${channel 4}|g' \
        "$themedir/nomarchy.script"
      sed -i 's|@BG_HEX@|${base}|g' \
        "$themedir/nomarchy.plymouth"
    '';
  };
in
{
  config = lib.mkIf cfg.plymouth.enable {
    # The systemd initrd (boot.initrd.systemd.enable) and console.earlySetup
    # that Plymouth needs are now distro-wide defaults in ./default.nix
    # (they also carry the keyboard layout to the LUKS prompt), so the
    # splash no longer has to turn them on. Just keep the console quiet
    # around the splash.
    boot.initrd.verbose = lib.mkDefault false;
    boot.consoleLogLevel = lib.mkDefault 0;

    boot.plymouth = {
      enable = lib.mkDefault true;
      themePackages = lib.mkDefault [ nomarchy-plymouth ];
      theme = lib.mkDefault "nomarchy";
    };

    # Not mkDefault: kernelParams is a list other modules add to at
    # normal priority — a mkDefault def would be dropped entirely,
    # losing the quiet/splash boot. These merge with the rest.
    boot.kernelParams = [
      "quiet"
      "splash"
      "loglevel=3"
      "rd.systemd.show_status=false"
      "rd.udev.log_level=3"
      "udev.log_priority=3"
      "boot.shell_on_fail"
    ];
  };
}
