/**
 * Local playback preferences (this browser only), read synchronously at store
 * creation so the audio engine never runs a frame with the wrong values.
 */

export const PLAYBACK_PREF_KEYS = {
  prefetchNext: 'muzick.settings.prefetchNext',
  crossfadeMs: 'muzick.settings.crossfadeMs',
  lastTrack: 'muzick.playback.lastTrack',
} as const;

/** Longest fade the UI offers. Also the longest early-advance lead. */
export const MAX_CROSSFADE_MS = 3000;

/** How far before the end of a track the next one starts buffering. */
export const PREFETCH_LEAD_SECONDS = 20;

/**
 * How far into a track the next one starts buffering, whichever comes first
 * with PREFETCH_LEAD_SECONDS. A phone that sleeps mid-track gets the whole
 * remaining song to pull the next one down instead of a 20 second window.
 */
export const PREFETCH_START_SECONDS = 15;

export const PLAYBACK_PREF_DEFAULTS = {
  prefetchNext: true,
  /** Short by default: enough to hide the Vibe replan round-trip, short enough
   * that it reads as a join rather than a mix. */
  crossfadeMs: 400,
} as const;

export function readStoredPrefetchNext(): boolean {
  try {
    const stored = localStorage.getItem(PLAYBACK_PREF_KEYS.prefetchNext);
    if (stored === 'true') return true;
    if (stored === 'false') return false;
  } catch { /* ignore */ }
  return PLAYBACK_PREF_DEFAULTS.prefetchNext;
}

export function readStoredCrossfadeMs(): number {
  try {
    const stored = localStorage.getItem(PLAYBACK_PREF_KEYS.crossfadeMs);
    if (stored !== null) {
      const parsed = Number(stored);
      if (Number.isFinite(parsed)) return clampCrossfadeMs(parsed);
    }
  } catch { /* ignore */ }
  return PLAYBACK_PREF_DEFAULTS.crossfadeMs;
}

export function clampCrossfadeMs(value: number): number {
  if (!Number.isFinite(value)) return 0;
  return Math.min(MAX_CROSSFADE_MS, Math.max(0, Math.round(value)));
}

export function storePrefetchNext(value: boolean): void {
  try { localStorage.setItem(PLAYBACK_PREF_KEYS.prefetchNext, String(value)); } catch { /* ignore */ }
}

export function storeCrossfadeMs(value: number): void {
  try { localStorage.setItem(PLAYBACK_PREF_KEYS.crossfadeMs, String(value)); } catch { /* ignore */ }
}

/**
 * The last track loaded into the player, so a fresh tab shows what was playing
 * rather than an empty bar. Restored paused — never autoplayed.
 * ponytail: stores the whole track object. It is one small row and it saves a
 * fetch on boot; if the shape drifts, the parse simply fails and the bar is empty.
 */
export function readStoredLastTrack<T>(): T | null {
  try {
    const stored = localStorage.getItem(PLAYBACK_PREF_KEYS.lastTrack);
    return stored ? (JSON.parse(stored) as T) : null;
  } catch { return null; }
}

export function storeLastTrack(track: unknown): void {
  try {
    if (track) localStorage.setItem(PLAYBACK_PREF_KEYS.lastTrack, JSON.stringify(track));
    else localStorage.removeItem(PLAYBACK_PREF_KEYS.lastTrack);
  } catch { /* ignore */ }
}
