# Automatic timezone detection (opt-in) — the system timezone, and so the
# Waybar clock, follows your location, so travelling to another zone updates
# the time on its own. Geoclue feeds `automatic-timezoned`, which drives
# /etc/localtime at runtime.
#
# In-flake state, menu-driven (the keyboard/night-light philosophy): the on/off
# flag lives in the same theme-state.json under `settings.autoTimezone`
# (git-tracked, reproducible), written by the System-menu toggle
# (nomarchy-autotimezone). Because this is a SYSTEM service — not a user unit it
# can start/stop instantly like night-light — the toggle drives a system rebuild
# (plus a home switch for the Waybar-refresh watcher in timezone.nix home-side).
{ config, lib, pkgs, ... }:

let
  cfg = config.nomarchy.system;

  # Read the same state file the rest of the system side uses (Plymouth too),
  # wired by lib.mkFlake. The flag defaults off when stateFile is null;
  # a set-but-missing/invalid path fails closed via theme-state-read.nix.
  state =
    if cfg.stateFile != null
    then import ../theme-state-read.nix { inherit lib; } cfg.stateFile
    else { };
  stateEnabled = (state.settings or { }).autoTimezone or false;

  sync = lib.getExe pkgs.nomarchy-theme-sync;

  # Menu/CLI toggle. Runs as the normal user (it owns the flake checkout +
  # writes the state); sudos only the system switch, like sys-update. Writes
  # the in-flake flag, then rebuilds: the system rebuild bakes the service +
  # the time.timeZone override, the home switch installs/removes the Waybar
  # refresh watcher — both read the same flag we just wrote.
  nomarchy-autotimezone = pkgs.writeShellScriptBin "nomarchy-autotimezone" ''
    set -e
    if [ "$(id -u)" -eq 0 ]; then
      echo "nomarchy-autotimezone: run as your normal user (it sudos the rebuild itself)" >&2
      exit 1
    fi
    flake="''${NOMARCHY_PATH:-$HOME/.nomarchy}"

    cur=$(${sync} get settings.autoTimezone 2>/dev/null) || cur=false
    case "''${1:-toggle}" in
      on)        new=true ;;
      off)       new=false ;;
      toggle)    case "$cur" in true|True) new=false ;; *) new=true ;; esac ;;
      status)    echo "$cur"; exit 0 ;;
      *) echo "usage: nomarchy-autotimezone [toggle|on|off|status]" >&2; exit 64 ;;
    esac

    ${sync} --quiet set settings.autoTimezone "$new" --no-switch

    if [ "$new" = true ]; then
      notify-send "Auto timezone" "Enabling — rebuilding the system…" 2>/dev/null || true
    else
      notify-send "Auto timezone" "Disabling — rebuilding the system…" 2>/dev/null || true
    fi

    sudo nixos-rebuild switch --flake "$flake#default"
    home-manager switch --flake "$flake"

    if [ "$new" = true ]; then
      notify-send "Auto timezone on" "The clock now follows your location." 2>/dev/null || true
    else
      notify-send "Auto timezone off" "Back to the fixed timezone in system.nix." 2>/dev/null || true
    fi
  '';
in
{
  config = lib.mkMerge [
    {
      # Shipped unconditionally so the menu can enable the feature even while
      # it's off. Track the in-flake flag; mkDefault so a hand-set
      # nomarchy.system.autoTimezone.enable in system.nix still wins.
      environment.systemPackages = [ nomarchy-autotimezone ];
      nomarchy.system.autoTimezone.enable = lib.mkDefault stateEnabled;
    }

    (lib.mkIf cfg.autoTimezone.enable {
      services.geoclue2.enable = true;
      services.automatic-timezoned.enable = true;
      # A runtime timezone needs /etc/localtime writable. automatic-timezoned
      # sets time.timeZone = null itself, but the installer writes a static
      # value at normal priority, which would collide (a hard eval error) —
      # mkForce null overrides both and resolves cleanly.
      time.timeZone = lib.mkForce null;
    })
  ];
}
