// MusicRoom - UI module
// Progress bar, buffer display, and UI state updates

(function() {
  const M = window.MusicRoom;
  
  // Create buffer segments on load
  for (let i = 0; i < M.SEGMENTS; i++) {
    const seg = document.createElement("div");
    seg.className = "segment";
    M.$("#buffer-bar").appendChild(seg);
  }
  
  // Update general UI state
  M.updateUI = function() {
    const isConnecting = M.wantSync && !M.synced;
    // While connecting, treat as not playing (paused state)
    const isPlaying = M.synced ? !M.serverPaused : (!isConnecting && !M.audio.paused);
    M.$("#btn-sync").classList.toggle("synced", M.wantSync);
    M.$("#btn-sync").classList.toggle("connected", M.synced);
    M.$("#btn-sync").title = M.wantSync ? "Unsync" : "Sync";
    M.$("#status").textContent = M.synced ? "Synced" : (M.wantSync ? "Connecting..." : "Local");
    M.$("#sync-indicator").classList.toggle("visible", M.synced);
    M.$("#progress-bar").classList.toggle("synced", M.synced);
    M.$("#progress-bar").classList.toggle("local", !M.synced);
    M.$("#progress-bar").classList.toggle("muted", M.audio.volume === 0);
    M.$("#btn-mute").textContent = M.audio.volume === 0 ? "🔇" : "🔊";
    M.$("#status-icon").textContent = isPlaying ? "⏸" : "▶";
    
    // Show/hide controls based on permissions
    const hasControl = M.canControl();
    const controlsDisabled = M.synced && !hasControl;
    ["#status-icon", "#btn-prev", "#btn-next", "#btn-mode", "#progress-container"].forEach(sel => {
      const el = M.$(sel);
      if (!el) return;
      el.classList.toggle("control-disabled", controlsDisabled);
      if ("ariaDisabled" in el) el.ariaDisabled = controlsDisabled ? "true" : "false";
    });
    M.$("#status-icon").style.cursor = controlsDisabled ? "not-allowed" : "pointer";
  };
  
  // Update auth-related UI
  M.updateAuthUI = function() {
    if (M.currentUser) {
      M.$("#login-panel").classList.add("hidden");
      M.$("#player-content").classList.add("visible");
      if (M.currentUser.isGuest) {
        M.$("#current-username").textContent = "Guest";
        M.$("#btn-logout").textContent = "Sign In";
        M.$("#btn-logout").classList.add("guest-signin");
      } else {
        M.$("#current-username").textContent = M.currentUser.username;
        M.$("#btn-logout").textContent = "Logout";
        M.$("#btn-logout").classList.remove("guest-signin");
      }
      M.$("#admin-badge").style.display = M.currentUser.isAdmin ? "inline" : "none";
      // Re-render channel list to update rename/delete buttons
      if (M.renderChannelList) M.renderChannelList();
      if (M.updatePermissionUI) M.updatePermissionUI();
    } else {
      M.$("#login-panel").classList.remove("hidden");
      M.$("#player-content").classList.remove("visible");
      // Pause and unsync when login panel is shown
      if (!M.audio.paused) {
        M.localTimestamp = M.audio.currentTime;
        M.audio.pause();
      }
      if (M.synced && M.ws) {
        M.synced = false;
        M.ws.close();
        M.ws = null;
      }
      // Show guest button if server allows guests
      if (M.serverStatus?.allowGuests) {
        M.$("#guest-section").classList.remove("hidden");
      } else {
        M.$("#guest-section").classList.add("hidden");
      }
      if (M.updatePermissionUI) M.updatePermissionUI();
    }
    M.updateUI();
  };
  
  // Progress bar and buffer update loop (250ms interval)
  setInterval(() => {
    if (M.serverTrackDuration <= 0) return;
    let t, dur;
    if (M.synced) {
      t = M.audio.paused ? M.getServerTime() : M.audio.currentTime;
      dur = M.audio.duration || M.serverTrackDuration;
    } else {
      t = M.audio.paused ? M.localTimestamp : M.audio.currentTime;
      dur = M.audio.duration || M.serverTrackDuration;
    }
    const pct = Math.min((t / dur) * 100, 100);
    if (Math.abs(pct - M.lastProgressPct) > 0.1) {
      M.$("#progress-bar").style.width = pct + "%";
      M.lastProgressPct = pct;
    }
    
    const timeCurrent = M.fmt(t);
    const timeTotal = M.fmt(dur);
    if (timeCurrent !== M.lastTimeCurrent) {
      M.$("#time-current").textContent = timeCurrent;
      M.lastTimeCurrent = timeCurrent;
    }
    if (timeTotal !== M.lastTimeTotal) {
      M.$("#time-total").textContent = timeTotal;
      M.lastTimeTotal = timeTotal;
    }

    // Update buffer segments
    const segments = M.$("#buffer-bar").children;
    const segmentDur = dur / M.SEGMENTS;
    let availableCount = 0;
    const trackCache = M.getTrackCache(M.currentTrackId);
    for (let i = 0; i < M.SEGMENTS; i++) {
      const segStart = i * segmentDur;
      const segEnd = (i + 1) * segmentDur;
      let available = trackCache.has(i); // Check our cache first
      if (!available) {
        // Check browser's native buffer
        for (let j = 0; j < M.audio.buffered.length; j++) {
          const bufStart = M.audio.buffered.start(j);
          const bufEnd = M.audio.buffered.end(j);
          if (bufStart <= segStart && bufEnd >= segEnd) {
            available = true;
            // Sync browser buffer to our trackCache
            trackCache.add(i);
            break;
          }
        }
      }
      if (available) availableCount++;
      const isAvailable = segments[i].classList.contains("available");
      const isLoading = segments[i].classList.contains("loading");
      const shouldBeLoading = !available && M.loadingSegments.has(i);
      if (available !== isAvailable) segments[i].classList.toggle("available", available);
      if (shouldBeLoading !== isLoading) segments[i].classList.toggle("loading", shouldBeLoading);
    }
    
    // Check if all segments now cached - trigger full cache
    if (trackCache.size >= M.SEGMENTS && !M.cachedTracks.has(M.currentTrackId)) {
      M.checkAndCacheComplete(M.currentTrackId);
    }
    
    // Update download speed display
    const kbps = M.downloadSpeed > 0 ? M.downloadSpeed * 8 / 1000 : 0;
    const bufferPct = Math.round(availableCount / M.SEGMENTS * 100);
    let speedText = "";
    if (kbps > 0) {
      speedText = kbps >= 1024 ? ` | ${(kbps / 1024).toFixed(1)} Mb/s` : ` | ${Math.round(kbps)} kb/s`;
    }
    if (bufferPct !== M.lastBufferPct || speedText !== M.lastSpeedText) {
      M.$("#download-speed").textContent = `${bufferPct}% buffered${speedText}`;
      M.lastBufferPct = bufferPct;
      M.lastSpeedText = speedText;
    }
  }, 250);
  
  // Prefetch loop (1s interval)
  setInterval(() => {
    if (M.currentTrackId && M.audio.src) {
      M.prefetchSegments();
    }
  }, 1000);
  
  // Cache status check (5s interval) - updates indicators when tracks finish caching
  let lastCacheSize = 0;
  setInterval(async () => {
    const currentSize = M.cachedTracks.size;
    if (currentSize !== lastCacheSize) {
      lastCacheSize = currentSize;
      M.renderQueue();
      M.renderLibrary();
    }
  }, 5000);

  // Mobile tab switching
  M.initMobileTabs = function() {
    const tabs = document.querySelectorAll(".mobile-tab");
    const panels = {
      "channels-panel": M.$("#channels-panel"),
      "library-panel": M.$("#library-panel"),
      "queue-panel": M.$("#queue-panel")
    };
    
    // Restore last active tab
    const savedTab = localStorage.getItem("blastoise_mobile_tab") || "queue-panel";
    
    function setActiveTab(panelId) {
      tabs.forEach(t => t.classList.toggle("active", t.dataset.panel === panelId));
      Object.entries(panels).forEach(([id, panel]) => {
        if (panel) panel.classList.toggle("mobile-active", id === panelId);
      });
      localStorage.setItem("blastoise_mobile_tab", panelId);
    }
    
    tabs.forEach(tab => {
      tab.onclick = () => setActiveTab(tab.dataset.panel);
    });
    
    // Set initial state
    setActiveTab(savedTab);
  };
  
  // Initialize on load
  M.initMobileTabs();
})();
