import { getAuthUserKey } from "./auth"; export type ThemeModePref = "system" | "light" | "dark"; export type EffectiveThemeMode = "light" | "dark"; export const DEFAULT_THEME_MODE: ThemeModePref = "system"; export const THEME_MODE_KEY = "jobtracker.themeMode"; const THEME_KEY_PREFIX = "themeMode:"; export function getUserKeyFromToken(): string { return getAuthUserKey(); } function readThemeMode(key: string): ThemeModePref | null { try { const raw = window.localStorage.getItem(key); return raw === "light" || raw === "dark" || raw === "system" ? raw : null; } catch { return null; } } export function getThemeModePref(): ThemeModePref { const savedMode = readThemeMode(THEME_MODE_KEY); if (savedMode) return savedMode; // Migrate the former account-scoped values once. Theme is a browser UI // preference, so changing auth state must never change the visible scheme. const userKey = getUserKeyFromToken(); const savedUserMode = readThemeMode(`${THEME_KEY_PREFIX}${userKey}`); const legacyMode = savedUserMode ?? (userKey !== "anon" ? readThemeMode(`${THEME_KEY_PREFIX}anon`) : null); if (legacyMode) { try { window.localStorage.setItem(THEME_MODE_KEY, legacyMode); } catch { // The migrated value still applies for this render when storage is unavailable. } return legacyMode; } return DEFAULT_THEME_MODE; } export function setThemeModePref(v: ThemeModePref) { try { window.localStorage.setItem(THEME_MODE_KEY, v); } catch { // Keep the in-memory selection even when storage is unavailable. } } export function resolveEffectiveThemeMode(preference: ThemeModePref, systemPrefersDark: boolean): EffectiveThemeMode { if (preference === "light" || preference === "dark") return preference; return systemPrefersDark ? "dark" : "light"; } export function subscribeToThemePreferenceChanges(sync: () => void) { const onStorage = (event: StorageEvent) => { if (event.key === THEME_MODE_KEY) sync(); }; window.addEventListener("storage", onStorage); return () => { window.removeEventListener("storage", onStorage); }; }