/**
 * Shared mutable state and pure utility functions.
 * All modules import from here — no circular dependencies.
 */
import type { LibraryInfo, VideoItem } from './types';

// ---- Shared mutable state ----
export let library: LibraryInfo | null = null;
export let currentIndex = 0;
export let prefs: Record<string, any> | null = null;
export let suppressTick = false;
export let lastTick = 0;
export let seeking = false;

export function setLibrary(lib: LibraryInfo | null) { library = lib; }
export function setCurrentIndex(idx: number) { currentIndex = idx; }
export function setPrefs(p: Record<string, any> | null) { prefs = p; }
export function setSuppressTick(v: boolean) { suppressTick = v; }
export function setLastTick(v: number) { lastTick = v; }
export function setSeeking(v: boolean) { seeking = v; }

// ---- Cross-module callbacks (set by main.ts) ----
export const cb = {
  loadIndex: null as ((idx: number, tc?: number, pause?: boolean, autoplay?: boolean) => Promise<void>) | null,
  renderList: null as (() => void) | null,
  updateInfoPanel: null as (() => void) | null,
  updateOverall: null as (() => void) | null,
  notify: null as ((msg: string) => void) | null,
  refreshCurrentVideoMeta: null as (() => Promise<void>) | null,
  onLibraryLoaded: null as ((info: LibraryInfo, startScan: boolean) => Promise<void>) | null,
  buildSpeedMenu: null as ((rate: number) => void) | null,
};

// ---- Pure utility functions ----

export function clamp(n: number, a: number, b: number): number {
  return Math.max(a, Math.min(b, n));
}

export function fmtTime(sec: number): string {
  sec = Math.max(0, Math.floor(sec || 0));
  const h = Math.floor(sec / 3600);
  const m = Math.floor((sec % 3600) / 60);
  const s = sec % 60;
  if (h > 0) return `${h}:${String(m).padStart(2, '0')}:${String(s).padStart(2, '0')}`;
  return `${m}:${String(s).padStart(2, '0')}`;
}

export function fmtBytes(n: number): string {
  n = Number(n || 0);
  if (!isFinite(n) || n <= 0) return '-';
  const u = ['B', 'KB', 'MB', 'GB', 'TB'];
  let i = 0;
  while (n >= 1024 && i < u.length - 1) { n /= 1024; i++; }
  return `${n.toFixed(i === 0 ? 0 : 1)} ${u[i]}`;
}

export function fmtDate(ts: number): string {
  if (!ts) return '-';
  try { return new Date(ts * 1000).toLocaleString(); } catch { return '-'; }
}

export function fmtBitrate(bps: number): string | null {
  const n = Number(bps || 0);
  if (!isFinite(n) || n <= 0) return null;
  const kb = n / 1000.0;
  if (kb < 1000) return `${kb.toFixed(0)} kbps`;
  return `${(kb / 1000).toFixed(2)} Mbps`;
}

export function currentItem(): VideoItem | null {
  if (!library || !library.items) return null;
  return library.items[currentIndex] || null;
}

export function computeResumeTime(item: VideoItem | null): number {
  if (!item) return 0.0;
  if (item.finished) return 0.0;
  const pos = Number(item.pos || 0.0);
  const dur = Number(item.duration || 0.0);
  if (dur > 0) return clamp(pos, 0.0, Math.max(0.0, dur - 0.25));
  return Math.max(0.0, pos);
}
