// MusicRoom - Core module
// Shared state and namespace setup

window.MusicRoom = {
  // Audio element
  audio: new Audio(),
  
  // WebSocket and channel state
  ws: null,
  currentChannelId: null,
  currentTrackId: null,
  currentTitle: null,
  serverTimestamp: 0,
  serverTrackDuration: 0,
  lastServerUpdate: 0,
  serverPaused: true,
  
  // Channels list
  channels: [],
  
  // Sync state
  wantSync: true,   // User intent - do they want to be synced?
  synced: false,    // Actual state - are we currently synced?
  
  // Volume
  preMuteVolume: 1,
  STORAGE_KEY: "blastoise_volume",
  CHANNEL_STORAGE_KEY: "blastoise_channel",
  THEME_STORAGE_KEY: "blastoise_theme",
  
  // Playback state
  localTimestamp: 0,
  queue: [],
  currentIndex: 0,
  playbackMode: "repeat-all",
  
  // User state
  currentUser: null,
  serverStatus: null,
  
  // Library (all discovered tracks)
  library: [],
  
  // Caching state
  prefetchController: null,
  loadingSegments: new Set(),
  trackCaches: new Map(),      // Map of filename -> Set of cached segment indices
  trackBlobs: new Map(),       // Map of filename -> Blob URL for fully cached tracks
  bulkDownloadStarted: new Map(),
  cachedTracks: new Set(),     // Set of track IDs that are fully cached locally
  streamOnly: false,           // When true, skip bulk downloads (still cache played tracks)
  cacheLimit: 100 * 1024 * 1024, // 100MB default cache limit
  
  // Download metrics
  audioBytesPerSecond: 20000,  // Audio bitrate estimate for range requests
  downloadSpeed: 0,            // Actual network download speed
  recentDownloads: [],         // Track recent downloads for speed calculation
  
  // Constants
  SEGMENTS: 20,
  FAST_THRESHOLD: 10 * 1024 * 1024, // 10 MB/s
  
  // UI update tracking (to avoid unnecessary DOM updates)
  lastProgressPct: -1,
  lastTimeCurrent: "",
  lastTimeTotal: "",
  lastBufferPct: -1,
  lastSpeedText: ""
};

(function() {
  const M = window.MusicRoom;
  const CHANNEL_COOKIE_MAX_AGE = 60 * 60 * 24 * 400;

  M.getCookieValue = function(name) {
    const prefix = `${name}=`;
    return document.cookie
      .split(";")
      .map(cookie => cookie.trim())
      .find(cookie => cookie.startsWith(prefix))
      ?.slice(prefix.length) || null;
  };

  M.setCookieValue = function(name, value, maxAge = CHANNEL_COOKIE_MAX_AGE) {
    document.cookie = `${name}=${encodeURIComponent(value)}; Path=/; SameSite=Lax; Max-Age=${maxAge}`;
  };

  M.clearCookieValue = function(name) {
    document.cookie = `${name}=; Path=/; SameSite=Lax; Max-Age=0`;
  };

  M.getSavedChannelId = function() {
    const cookieValue = M.getCookieValue(M.CHANNEL_STORAGE_KEY);
    if (cookieValue) {
      try {
        return decodeURIComponent(cookieValue);
      } catch {
        M.clearRememberedChannel();
      }
    }

    try {
      const storedValue = localStorage.getItem(M.CHANNEL_STORAGE_KEY);
      if (storedValue) {
        M.rememberChannel(storedValue);
        return storedValue;
      }
    } catch {}

    return null;
  };

  M.rememberChannel = function(channelId) {
    if (!channelId) return;
    M.setCookieValue(M.CHANNEL_STORAGE_KEY, channelId);

    try {
      localStorage.setItem(M.CHANNEL_STORAGE_KEY, channelId);
    } catch {}
  };

  M.clearRememberedChannel = function() {
    M.clearCookieValue(M.CHANNEL_STORAGE_KEY);

    try {
      localStorage.removeItem(M.CHANNEL_STORAGE_KEY);
    } catch {}
  };
})();
