const FALLBACK_ART = '/assets/rexr-mark.jpg';

const gameGridEl = document.getElementById('gameGrid');
const modalBackdropEl = document.getElementById('modalBackdrop');
const modalArtEl = document.getElementById('modalArt');
const modalTitleEl = document.getElementById('modalTitle');
const modalTextEl = document.getElementById('modalText');
const closeModalBtn = document.getElementById('closeModal');
const launchBtnEl = document.getElementById('launchBtn');
const qrCopyEl = document.getElementById('qrCopy');
const qrTitleEl = document.getElementById('qrTitle');
const qrBodyEl = document.getElementById('qrBody');
const minimizeBtn = document.getElementById('minimizeBtn');
const fullscreenBtn = document.getElementById('fullscreenBtn');
const closeBtn = document.getElementById('closeBtn');
const modeCard1TitleEl = document.getElementById('modeCard1Title');
const modeCard1BodyEl = document.getElementById('modeCard1Body');
const modeCard2TitleEl = document.getElementById('modeCard2Title');
const modeCard2BodyEl = document.getElementById('modeCard2Body');
const modeCard3TitleEl = document.getElementById('modeCard3Title');
const modeCard3BodyEl = document.getElementById('modeCard3Body');

const STORAGE = {
  room: 'gs_room',
  token: 'gs_token',
  email: 'gs_email',
};

const LOGIN_MESSAGE_KEY = 'rexr_login_message';
const sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));

let config = null;
let libraryConfig = { items: {} };
let signalBase = '';
let signalUrl = '';
let apiBase = '';
let room = '';
let pc = null;
let localStream = null;
let loopStarted = false;
let startCallInFlight = false;
let libraryBusyId = '';
let libraryItems = [];
let activeItemId = '';
let selectedItemId = '';
let modalItemId = '';
let steamState = {
  ok: true,
  installed: false,
  appCount: 0,
  libraryPaths: [],
  apps: {},
};
let auth = {
  mode: 'user',
  email: '',
  token: '',
  credits: null,
  unlimited: false,
  freeLibraryAccess: false,
  ready: false,
};

function escapeHtml(text) {
  return String(text || '')
    .replace(/&/g, '&amp;')
    .replace(/</g, '&lt;')
    .replace(/>/g, '&gt;')
    .replace(/"/g, '&quot;')
    .replace(/'/g, '&#39;');
}

function escapeAttr(text) {
  return escapeHtml(text).replace(/`/g, '&#96;');
}

function normalizeBase(url) {
  return String(url || '').replace(/\s+/g, '').replace(/\/?$/, '/');
}

function deriveApiBaseFromSignalBase(base) {
  return normalizeBase(base).replace(/gamestream\/?$/i, '') + 'api/';
}

function randomCode() {
  const chars = 'ABCDEFGHJKMNPQRSTUVWXYZ23456789';
  let out = '';
  for (let i = 0; i < 6; i += 1) out += chars[Math.floor(Math.random() * chars.length)];
  return out;
}

function hasValidDevKey() {
  return !!(config && config.devKey && !/^CHANGE-ME/i.test(config.devKey));
}

function hasLibraryAccess() {
  if (auth.mode === 'dev') return hasValidDevKey();
  return !!auth.token;
}

function storeAuth() {
  if (auth.token) localStorage.setItem(STORAGE.token, auth.token);
  else localStorage.removeItem(STORAGE.token);

  if (auth.email) localStorage.setItem(STORAGE.email, auth.email);
  else localStorage.removeItem(STORAGE.email);
}

function clearStoredAuth() {
  localStorage.removeItem(STORAGE.token);
  localStorage.removeItem(STORAGE.email);
}

function saveLoginMessage(message) {
  if (!message) return;
  sessionStorage.setItem(LOGIN_MESSAGE_KEY, message);
}

function redirectToLogin(message) {
  if (message) saveLoginMessage(message);
  window.location.replace('/login.html');
}

async function postJson(url, body) {
  const response = await fetch(url, {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify(body || {}),
  });

  let data = null;
  try {
    data = await response.json();
  } catch (error) {
    data = null;
  }

  if (!response.ok && !data) {
    return { ok: false, error: `HTTP ${response.status}` };
  }

  if (data && typeof data === 'object') {
    if (!response.ok && !('ok' in data)) data.ok = false;
    return data;
  }

  return { ok: response.ok };
}

function setSidebarStatus(title, body, isError) {
  if (qrTitleEl) qrTitleEl.textContent = title;
  if (qrBodyEl) qrBodyEl.textContent = body;
  if (qrCopyEl) qrCopyEl.classList.toggle('is-error', !!isError);
}

function syncSidebarWithState() {
  const item = activeItem();
  if (item) {
    setSidebarStatus(
      `${item.title} Live`,
      `Room ${room} is locked to this title. Scan the QR code on your phone, open the viewer, and connect to this stream.`,
      false,
    );
    return;
  }

  if (auth.mode === 'dev') {
    if (!hasValidDevKey()) {
      setSidebarStatus('DEV Key Needed', 'Go back to the desktop login page and finish setting your DEV key before opening the dashboard.', true);
      return;
    }

    setSidebarStatus(`Room ${room}`, 'Developer mode is active. Pick a title, open the launch panel, and pair your phone after the game starts.', false);
    return;
  }

  setSidebarStatus(`Room ${room}`, 'Pick a title from your library, open the launch panel, and then scan the QR code on your phone to connect.', false);
}

function getSteamApps() {
  return steamState && steamState.apps && typeof steamState.apps === 'object' ? steamState.apps : {};
}

function getItemById(gameId) {
  return libraryItems.find((item) => item.id === gameId) || null;
}

function activeItem() {
  return getItemById(activeItemId);
}

function selectedItem() {
  return getItemById(selectedItemId);
}

function clearActiveItem() {
  activeItemId = '';
  if (window.rexrHost && typeof window.rexrHost.clearActiveCapture === 'function') {
    window.rexrHost.clearActiveCapture().catch(() => {});
  }
}

function readyPlayableItems() {
  return libraryItems.filter((item) => item.launchReady && (!item.requiresInstall || item.installed));
}

function launchReadyForConfig(launch) {
  return !!launch && (
    launch.type === 'internal-twitch' ||
    (launch.type === 'url' && typeof launch.url === 'string' && !!launch.url.trim()) ||
    (launch.type === 'command' && typeof launch.command === 'string' && !!launch.command.trim())
  );
}

function buildDetectedSteamLibraryItems(localItems, knownSteamAppIds, steamApps) {
  const local = localItems && typeof localItems === 'object' ? localItems : {};
  const detectedApps = steamApps && typeof steamApps === 'object' ? steamApps : {};

  return Object.values(detectedApps)
    .filter((detectedApp) => detectedApp && detectedApp.appId && !knownSteamAppIds.has(String(detectedApp.appId)))
    .map((detectedApp) => {
      const localMatch = Object.values(local).find((entry) => String(entry && entry.steamAppId || '') === String(detectedApp.appId)) || {};
      const launch = localMatch.launch || {
        type: 'url',
        url: `steam://rungameid/${detectedApp.appId}`,
      };
      const capture = localMatch.capture || {
        sourceType: 'screen',
      };
      return {
        id: `steam-app-${detectedApp.appId}`,
        title: detectedApp.name || `Steam App ${detectedApp.appId}`,
        tag: 'Steam Library',
        kind: 'game',
        platform: 'Steam',
        summary: 'Detected from the user Steam library and ready to launch for free in PocketVR.',
        unlockCostCredits: 0,
        alwaysUnlocked: true,
        unlocked: true,
        managedByCatalog: false,
        launch,
        capture,
        steamAppId: String(detectedApp.appId),
        steamDetected: true,
        requiresInstall: true,
        installed: true,
        installPath: detectedApp.installPath || '',
        libraryPath: detectedApp.libraryPath || '',
        coverUrl: detectedApp.coverUrl || localMatch.coverUrl || FALLBACK_ART,
        bannerUrl: detectedApp.bannerUrl || detectedApp.coverUrl || localMatch.bannerUrl || localMatch.coverUrl || FALLBACK_ART,
        launchReady: launchReadyForConfig(launch),
      };
    })
    .sort((left, right) => left.title.localeCompare(right.title));
}

function mergeLibrary(serverGames, localItems, steamApps) {
  const items = Array.isArray(serverGames) ? serverGames : [];
  const local = localItems && typeof localItems === 'object' ? localItems : {};
  const detectedApps = steamApps && typeof steamApps === 'object' ? steamApps : {};

  const mergedManagedItems = items.map((item) => {
    const localItem = local[item.id] || {};
    const steamAppId = String(localItem.steamAppId || item.steamAppId || '').trim();
    const detectedApp = steamAppId ? detectedApps[steamAppId] || null : null;
    const requiresInstall = !!steamAppId;
    const installed = item.kind === 'app' ? true : !!detectedApp;
    const launch = localItem.launch || (steamAppId ? {
      type: 'url',
      url: `steam://rungameid/${steamAppId}`,
    } : null);
    const capture = localItem.capture || null;
    const baseLaunchReady = launchReadyForConfig(launch);

    return {
      ...item,
      launch,
      capture,
      unlockCostCredits: 0,
      alwaysUnlocked: true,
      unlocked: true,
      managedByCatalog: true,
      steamAppId,
      steamDetected: !!detectedApp,
      requiresInstall,
      installed,
      installPath: detectedApp && detectedApp.installPath ? detectedApp.installPath : '',
      libraryPath: detectedApp && detectedApp.libraryPath ? detectedApp.libraryPath : '',
      coverUrl: (detectedApp && detectedApp.coverUrl) || localItem.coverUrl || item.coverUrl || '',
      bannerUrl: (detectedApp && detectedApp.bannerUrl) || localItem.bannerUrl || item.bannerUrl || localItem.coverUrl || item.coverUrl || '',
      launchReady: baseLaunchReady && (!requiresInstall || installed),
    };
  })
    .filter((item) => item.kind === 'app' || item.installed);

  const knownSteamAppIds = new Set(
    mergedManagedItems
      .map((item) => String(item.steamAppId || '').trim())
      .filter(Boolean),
  );

  return mergedManagedItems.concat(buildDetectedSteamLibraryItems(localItems, knownSteamAppIds, detectedApps));
}

function libraryButtonLabel(item) {
  if (item.requiresInstall && !item.installed) return 'Not Installed';
  if (auth.mode !== 'dev' && !auth.token) return 'Log in to use';
  if (item.kind === 'app') return 'Open App';
  return 'Launch in PocketVR';
}

function libraryButtonDisabled(item) {
  if (libraryBusyId === item.id) return true;
  if (item.requiresInstall && !item.installed) return true;
  if (auth.mode === 'dev') return !item.launchReady || !hasValidDevKey();
  if (!auth.token) return true;
  return !item.launchReady;
}

function libraryHint(item) {
  if (item.managedByCatalog === false) {
    return 'This game was detected in the user Steam library and can launch for free through PocketVR.';
  }
  if (item.requiresInstall && !item.installed) {
    return 'Steam has not reported this title as installed on this PC yet.';
  }
  if (!item.launchReady) return 'This title still needs a local launch target in desktop-app/library.json.';
  if (item.kind === 'app') return 'Built into PocketVR. Open it and then pair your phone.';
  return 'Launch it here first, then connect from your phone or the future PocketVR PWA viewer.';
}

function itemStateInfo(item) {
  const isActive = item.id === activeItemId;
  const missingInstall = item.requiresInstall && !item.installed;
  const detectedOnly = item.managedByCatalog === false;
  const stateLabel = isActive
    ? 'Live'
    : detectedOnly
      ? 'Owned'
    : missingInstall
      ? 'Install Required'
      : 'Ready';
  const copy = isActive
    ? `${item.title} is already live in room ${room}. Open the viewer on your phone to stream it.`
    : detectedOnly
      ? `${item.title} was detected from the local Steam account, and PocketVR is using the real Steam artwork for this library card. Launch it here, then pair your phone or PWA viewer for flat-screen VR streaming.`
    : missingInstall
      ? `${item.title} is in your PocketVR catalog, but Steam has not detected it on this PC yet.`
      : `${item.title} is ready to launch from your PocketVR dashboard.`;

  return {
    isActive,
    missingInstall,
    stateLabel,
    copy,
    artUrl: item.bannerUrl || item.coverUrl || FALLBACK_ART,
    buttonLabel: libraryButtonLabel(item),
    buttonDisabled: libraryButtonDisabled(item),
    hint: libraryHint(item),
  };
}

function roomCardText(item) {
  if (item && item.id === activeItemId) {
    return `Room ${room} is active now. Your phone will join this title when it answers the pairing signal.`;
  }
  return `Room ${room} is standing by. Launch this title first, then pair your phone with the same room.`;
}

function accessCardText(item) {
  if (item.managedByCatalog === false) {
    return 'This title is coming from the local Steam library. Because PocketVR now uses free owned-library access, you can launch it here as long as it is installed on this PC.';
  }
  if (auth.mode === 'dev') {
    return hasValidDevKey()
      ? 'Developer mode is active, so every supported title is available for unlimited testing.'
      : 'This DEV build still needs a valid DEV key before it can launch titles.';
  }
  if (item.kind === 'app') {
    return 'Built-in apps stay available inside PocketVR without any purchase step.';
  }
  return 'Your PocketVR account is connected. Any Steam game you own and have installed can launch for free from this host and pair with the phone viewer in flat-screen VR mode.';
}

function installCardText(item) {
  if (!item.requiresInstall) {
    return 'This is a built-in PocketVR app and does not need Steam installed on this PC.';
  }
  if (item.installed) {
    return item.installPath
      ? `Steam detected this title here: ${item.installPath}`
      : 'Steam detected this title on this PC and it is ready to launch.';
  }
  return 'Steam has not detected this title on this PC yet. Install it through Steam and reopen or rescan the host.';
}

function setModalCard(copyTarget, title, body) {
  if (copyTarget.title) copyTarget.title.textContent = title;
  if (copyTarget.body) copyTarget.body.textContent = body;
}

function orderedLibraryItems() {
  return [...libraryItems].sort((left, right) => {
    const leftState = itemStateInfo(left);
    const rightState = itemStateInfo(right);
    const leftRank = leftState.isActive
      ? 0
      : leftState.missingInstall
        ? 3
        : left.managedByCatalog === false
          ? 1
          : 2;
    const rightRank = rightState.isActive
      ? 0
      : rightState.missingInstall
        ? 3
        : right.managedByCatalog === false
          ? 1
          : 2;
    if (leftRank !== rightRank) return leftRank - rightRank;
    return left.title.localeCompare(right.title);
  });
}

function ensureSelectedItem() {
  const items = orderedLibraryItems();
  const current = selectedItem();
  if (current && items.some((item) => item.id === current.id)) return current;

  const fallback = activeItem() || readyPlayableItems()[0] || items[0] || null;
  selectedItemId = fallback ? fallback.id : '';
  return fallback;
}

function updateGridLayout(itemCount) {
  if (!gameGridEl) return;
  gameGridEl.style.gridTemplateRows = '';
}

function renderGridCard(item) {
  const state = itemStateInfo(item);
  const isSelected = item.id === selectedItemId;

  return [
    `<article class="game-card${isSelected ? ' selected' : ''}${state.isActive ? ' active' : ''}" tabindex="${isSelected ? '0' : '-1'}" data-card-select="${escapeAttr(item.id)}" aria-selected="${isSelected ? 'true' : 'false'}">`,
    `  <div class="game-art" style="background-image:url('${escapeAttr(state.artUrl)}');background-position:center center;"></div>`,
    '  <div class="game-info">',
    `    <h3>${escapeHtml(item.title)}</h3>`,
    '  </div>',
    '</article>',
  ].join('');
}

function renderLibrary() {
  const items = orderedLibraryItems();
  ensureSelectedItem();

  if (!items.length) {
    gameGridEl.innerHTML = '<article class="game-card selected"><div class="game-art" style="background-image:url(\'/assets/logo_hd.png\');background-position:center center;"></div><div class="game-info"><h3>No PocketVR titles found yet</h3></div></article>';
    updateGridLayout(1);
    renderModal();
    return;
  }

  gameGridEl.innerHTML = items.map((item) => renderGridCard(item)).join('');
  updateGridLayout(items.length);
  renderModal();
}

function renderModal() {
  if (!modalBackdropEl) return;

  if (!modalItemId) {
    modalBackdropEl.classList.remove('open');
    return;
  }

  const item = getItemById(modalItemId);
  if (!item) {
    modalItemId = '';
    modalBackdropEl.classList.remove('open');
    return;
  }

  const state = itemStateInfo(item);
  if (modalTitleEl) modalTitleEl.textContent = item.title;
  if (modalTextEl) modalTextEl.textContent = `${state.copy} ${state.hint}`;
  if (modalArtEl) {
    modalArtEl.style.backgroundImage = `url('${state.artUrl.replace(/'/g, "\\'")}')`;
    modalArtEl.style.backgroundPosition = 'center 18%';
  }
  if (launchBtnEl) {
    launchBtnEl.textContent = state.buttonLabel;
    launchBtnEl.disabled = state.buttonDisabled;
  }

  setModalCard(
    { title: modeCard1TitleEl, body: modeCard1BodyEl },
    'Room',
    roomCardText(item),
  );
  setModalCard(
    { title: modeCard2TitleEl, body: modeCard2BodyEl },
    'Access',
    accessCardText(item),
  );
  setModalCard(
    { title: modeCard3TitleEl, body: modeCard3BodyEl },
    'Install',
    installCardText(item),
  );

  modalBackdropEl.classList.add('open');
}

function openGameModal(gameId) {
  const item = getItemById(gameId);
  if (!item) return;
  selectedItemId = item.id;
  modalItemId = item.id;
  renderLibrary();
}

function closeModal() {
  modalItemId = '';
  if (modalBackdropEl) modalBackdropEl.classList.remove('open');
}

function selectItem(gameId, options) {
  const item = getItemById(gameId);
  if (!item) return;

  selectedItemId = item.id;
  renderLibrary();

  if (options && options.focusCard && gameGridEl) {
    const card = gameGridEl.querySelector(`[data-card-select="${escapeAttr(item.id)}"]`);
    if (card) {
      try {
        card.focus({ preventScroll: true });
      } catch (error) {
        card.focus();
      }
      card.scrollIntoView({
        behavior: 'smooth',
        block: 'nearest',
        inline: 'nearest',
      });
    }
  }
}

function moveSelection(deltaX, deltaY) {
  if (modalItemId) return;

  const items = orderedLibraryItems();
  if (!items.length) return;

  let currentIndex = items.findIndex((item) => item.id === selectedItemId);
  if (currentIndex < 0) currentIndex = 0;

  const columns = Number(getComputedStyle(gameGridEl).getPropertyValue('--grid-columns').trim()) || 4;
  let nextIndex = currentIndex;
  if (deltaY) nextIndex += deltaY * columns;
  if (deltaX) nextIndex += deltaX;
  nextIndex = Math.max(0, Math.min(items.length - 1, nextIndex));

  const nextItem = items[nextIndex];
  if (!nextItem) return;
  selectItem(nextItem.id, { focusCard: true });
}

async function loadSteamLibrary(forceRefresh) {
  if (!window.rexrHost || typeof window.rexrHost.getSteamLibrary !== 'function') {
    steamState = {
      ok: false,
      installed: false,
      error: 'The desktop host bridge is unavailable.',
      appCount: 0,
      libraryPaths: [],
      apps: {},
    };
    return steamState;
  }

  try {
    steamState = forceRefresh && typeof window.rexrHost.rescanSteamLibrary === 'function'
      ? await window.rexrHost.rescanSteamLibrary()
      : await window.rexrHost.getSteamLibrary();
  } catch (error) {
    steamState = {
      ok: false,
      installed: false,
      error: error.message,
      appCount: 0,
      libraryPaths: [],
      apps: {},
    };
  }

  return steamState;
}

async function refreshLibrary() {
  const body = {};
  if (auth.mode === 'dev') {
    if (hasValidDevKey()) body.devKey = config.devKey;
  } else if (auth.token) {
    body.token = auth.token;
  }

  const data = await postJson(apiBase + 'games.php', body);
  if (!data.ok) throw new Error(data.error || 'Could not load the PocketVR library.');

  if (auth.mode === 'user') {
    auth.credits = null;
    auth.unlimited = !!data.unlimited;
    auth.freeLibraryAccess = !!data.freeLibraryAccess;
    auth.ready = !!auth.token;
  } else {
    auth.unlimited = !!data.unlimited;
    auth.freeLibraryAccess = true;
    auth.ready = hasValidDevKey();
  }

  libraryItems = mergeLibrary(data.games || [], libraryConfig.items || {}, getSteamApps());
  if (!getItemById(activeItemId)) activeItemId = '';
  if (!getItemById(selectedItemId)) selectedItemId = '';
  if (modalItemId && !getItemById(modalItemId)) modalItemId = '';
  renderLibrary();
  syncSidebarWithState();
}

async function validateSessionOrRedirect() {
  auth.email = (localStorage.getItem(STORAGE.email) || '').trim().toLowerCase();
  auth.token = (localStorage.getItem(STORAGE.token) || '').trim();

  if (auth.mode === 'dev') {
    if (!hasValidDevKey()) {
      redirectToLogin('This DEV build still needs a valid DEV key before you can open the dashboard.');
      throw new Error('Missing DEV key.');
    }
    auth.ready = true;
    auth.unlimited = true;
    return;
  }

  if (!auth.token) {
    redirectToLogin('Log in before opening the PocketVR dashboard.');
    throw new Error('Missing saved session.');
  }

  const data = await postJson(apiBase + 'account.php', { token: auth.token });
  if (!data.ok) {
    clearStoredAuth();
    redirectToLogin('Your saved desktop session expired. Please sign in again.');
    throw new Error('Saved session expired.');
  }

  auth.email = data.email || auth.email;
  auth.credits = null;
  auth.unlimited = !!data.unlimited;
  auth.freeLibraryAccess = !!data.freeLibraryAccess;
  auth.ready = true;
  storeAuth();
}

async function handleLibraryAction(gameId) {
  const item = getItemById(gameId);
  if (!item) return;

  selectedItemId = item.id;
  libraryBusyId = gameId;
  renderLibrary();

  try {
    const latestItem = getItemById(gameId) || item;
    if (!latestItem.launchReady) {
      setSidebarStatus('Launch Not Ready', `${latestItem.title} still needs a local launch target in desktop-app/library.json.`, true);
      return;
    }

    if (!window.rexrHost || typeof window.rexrHost.launchLibraryItem !== 'function') {
      setSidebarStatus('Host Bridge Missing', 'The desktop host bridge is unavailable, so this title cannot launch.', true);
      return;
    }

    setSidebarStatus('Launching Title', `Opening ${latestItem.title} inside PocketVR and locking room ${room} to this stream.`, false);
    const result = await window.rexrHost.launchLibraryItem({
      id: latestItem.id,
      title: latestItem.title,
      launch: latestItem.launch,
      capture: latestItem.capture,
    });

    if (!result || !result.ok) {
      setSidebarStatus('Launch Failed', (result && result.error) || `Could not launch ${latestItem.title}.`, true);
      return;
    }

    activeItemId = latestItem.id;
    selectedItemId = latestItem.id;
    closeModal();
    renderLibrary();
    syncSidebarWithState();
  } catch (error) {
    setSidebarStatus('Launch Failed', error.message || 'Could not launch the selected title.', true);
  } finally {
    libraryBusyId = '';
    renderLibrary();
  }
}

async function ensureCapture() {
  if (localStream && localStream.getTracks().some((track) => track.readyState === 'live')) {
    return localStream;
  }

  localStream = await navigator.mediaDevices.getDisplayMedia({
    video: { frameRate: 30 },
    audio: false,
  });

  localStream.getTracks().forEach((track) => {
    track.addEventListener('ended', () => {
      localStream = null;
      clearActiveItem();
      renderLibrary();
      setSidebarStatus('Capture Stopped', 'Windows ended display capture. Launch a title again when you want to reconnect your phone.', true);
    });
  });

  return localStream;
}

async function sig(action, extra, body) {
  const url = `${signalUrl}?action=${action}&room=${room}${extra || ''}`;
  if (body) return postJson(url, body);
  const response = await fetch(url);
  return response.json();
}

async function checkStreamAccess(item) {
  if (!item) return { ok: false, error: 'Launch a library item first.' };

  if (auth.mode === 'dev') {
    if (!hasValidDevKey()) return { ok: false, error: 'Developer mode is missing a valid DEV key.' };
    return postJson(apiBase + 'stream-access.php', {
      devKey: config.devKey,
      gameId: item.id,
      title: item.title,
      steamAppId: item.steamAppId || '',
    });
  }

  if (!auth.token) return { ok: false, error: 'Please log in before pairing your phone.' };

  const data = await postJson(apiBase + 'stream-access.php', {
    token: auth.token,
    gameId: item.id,
    title: item.title,
    steamAppId: item.steamAppId || '',
  });
  if (!data.ok && /not logged in/i.test(data.error || '')) {
    clearStoredAuth();
    redirectToLogin('Your desktop session expired while streaming. Please sign in again.');
  }

  if (data.ok) {
    auth.credits = null;
    auth.unlimited = !!data.unlimited;
    auth.freeLibraryAccess = !!data.freeLibraryAccess;
    auth.ready = auth.mode === 'dev' ? hasValidDevKey() : !!auth.token;
  }

  return data;
}

function canStartCall() {
  if (auth.mode === 'dev') return !!activeItem();
  return !!(hasLibraryAccess() && activeItem());
}

function currentPcBusy() {
  return !!(pc && ['new', 'connecting', 'connected'].includes(pc.connectionState));
}

async function waitIce(peer) {
  return new Promise((resolve) => {
    if (peer.iceGatheringState === 'complete') {
      resolve();
      return;
    }

    const timeoutId = setTimeout(resolve, 3000);
    peer.addEventListener('icegatheringstatechange', () => {
      if (peer.iceGatheringState === 'complete') {
        clearTimeout(timeoutId);
        resolve();
      }
    });
  });
}

async function startCall() {
  if (startCallInFlight || currentPcBusy()) return;
  if (!canStartCall()) {
    setSidebarStatus('Launch A Title First', 'Pick a title from the dashboard and launch it before pairing your phone.', true);
    return;
  }

  const item = activeItem();
  startCallInFlight = true;
  setSidebarStatus('Phone Detected', `Preparing ${item.title} for room ${room}.`, false);

  try {
    const stream = await ensureCapture();

    if (pc) {
      try {
        pc.close();
      } catch (error) {
        // Ignore cleanup issues from the previous peer.
      }
    }

    pc = new RTCPeerConnection({ iceServers: config.iceServers || [] });
    const callPc = pc;
    let accessChecked = false;

    stream.getTracks().forEach((track) => callPc.addTrack(track, stream));

    callPc.onconnectionstatechange = async () => {
      if (pc !== callPc) return;

      const state = callPc.connectionState;
      if (state === 'connected' && !accessChecked) {
        accessChecked = true;
        setSidebarStatus('Viewer Connected', `Verifying access for ${item.title} before the stream goes live.`, false);

        try {
          const access = await checkStreamAccess(item);
          if (!access.ok) {
            const detail = access.error || 'The website rejected this library item.';
            setSidebarStatus('Access Rejected', detail, true);
            callPc.close();
            return;
          }

          const accessSummary = access.unlimited
            ? 'Developer access active.'
            : 'Owned-library access confirmed. Open the future PocketVR PWA in side-by-side mode to play in flat-screen VR.';
          setSidebarStatus('Streaming Live', `${item.title} is now live to your phone. ${accessSummary}`, false);
        } catch (error) {
          setSidebarStatus('Access Check Failed', `Could not verify library access: ${error.message}`, true);
          callPc.close();
        }
        return;
      }

      if (state === 'failed') {
        setSidebarStatus('Connection Failed', `${item.title} could not stay connected to the viewer.`, true);
      }
    };

    await callPc.setLocalDescription(await callPc.createOffer());
    await waitIce(callPc);
    await sig('send', '&to=client', { type: 'offer', sdp: callPc.localDescription });
    setSidebarStatus('Offer Sent', `Waiting for your phone to answer room ${room} for ${item.title}.`, false);
  } catch (error) {
    setSidebarStatus('Streaming Error', `Could not start streaming: ${error.message}`, true);
  } finally {
    startCallInFlight = false;
  }
}

async function loop() {
  if (loopStarted) return;
  loopStarted = true;

  for (;;) {
    try {
      const messages = await sig('recv', '&for=host');
      for (const message of messages) {
        if (message.type === 'ready') {
          await startCall();
        } else if (message.type === 'answer' && pc) {
          await pc.setRemoteDescription(message.sdp);
        }
      }
    } catch (error) {
      setSidebarStatus('Signal Retry', `The phone signaling channel had an error: ${error.message}`, true);
    }

    await sleep(pc && pc.connectionState === 'connected' ? 3000 : 1200);
  }
}

function isTypingTarget(target) {
  return !!(target && target.tagName && /^(INPUT|TEXTAREA|SELECT)$/i.test(target.tagName));
}

async function toggleFullscreen() {
  if (!window.rexrHost || typeof window.rexrHost.toggleFullscreen !== 'function') return;
  try {
    await window.rexrHost.toggleFullscreen();
  } catch (error) {
    setSidebarStatus('Fullscreen Error', `Could not change fullscreen mode: ${error.message}`, true);
  }
}

async function exitFullscreen() {
  if (!window.rexrHost || typeof window.rexrHost.setFullscreen !== 'function') return;
  try {
    await window.rexrHost.setFullscreen(false);
  } catch (error) {
    setSidebarStatus('Fullscreen Error', `Could not exit fullscreen mode: ${error.message}`, true);
  }
}

async function minimizeWindow() {
  if (!window.rexrHost || typeof window.rexrHost.minimizeWindow !== 'function') return;
  try {
    await window.rexrHost.minimizeWindow();
  } catch (error) {
    setSidebarStatus('Window Error', `Could not minimize the desktop host: ${error.message}`, true);
  }
}

async function closeWindow() {
  if (!window.rexrHost || typeof window.rexrHost.closeWindow !== 'function') return;
  try {
    await window.rexrHost.closeWindow();
  } catch (error) {
    setSidebarStatus('Window Error', `Could not close the desktop host: ${error.message}`, true);
  }
}

async function rescanAndRefresh() {
  setSidebarStatus('Scanning Steam', 'Refreshing the Steam libraries on this PC and rebuilding your PocketVR dashboard.', false);
  await loadSteamLibrary(true);
  await refreshLibrary();
}

async function init() {
  if (closeModalBtn) closeModalBtn.addEventListener('click', closeModal);
  if (launchBtnEl) {
    launchBtnEl.addEventListener('click', () => {
      if (modalItemId) handleLibraryAction(modalItemId);
    });
  }

  if (modalBackdropEl) {
    modalBackdropEl.addEventListener('click', (event) => {
      if (event.target === modalBackdropEl) closeModal();
    });
  }

  if (gameGridEl) {
    gameGridEl.addEventListener('click', (event) => {
      const card = event.target.closest('[data-card-select]');
      if (!card) return;
      const gameId = card.getAttribute('data-card-select');
      if (!gameId) return;

      if (selectedItemId === gameId) {
        openGameModal(gameId);
        return;
      }

      selectItem(gameId, { focusCard: true });
    });

    gameGridEl.addEventListener('dblclick', (event) => {
      const card = event.target.closest('[data-card-select]');
      if (!card) return;
      const gameId = card.getAttribute('data-card-select');
      if (gameId) openGameModal(gameId);
    });

    gameGridEl.addEventListener('focusin', (event) => {
      const card = event.target.closest('[data-card-select]');
      if (!card) return;
      const gameId = card.getAttribute('data-card-select');
      if (gameId && gameId !== selectedItemId) {
        selectItem(gameId, { focusCard: true });
      }
    });
  }

  if (minimizeBtn) minimizeBtn.addEventListener('click', () => minimizeWindow());
  if (fullscreenBtn) fullscreenBtn.addEventListener('click', () => toggleFullscreen());
  if (closeBtn) closeBtn.addEventListener('click', () => closeWindow());

  document.addEventListener('keydown', (event) => {
    if (event.key === 'F11') {
      event.preventDefault();
      toggleFullscreen();
      return;
    }

    if (event.key === 'Enter' && event.altKey) {
      event.preventDefault();
      toggleFullscreen();
      return;
    }

    if (event.key === 'F5' || event.key.toLowerCase() === 'r') {
      if (!isTypingTarget(event.target)) {
        event.preventDefault();
        rescanAndRefresh().catch((error) => setSidebarStatus('Steam Scan Failed', error.message, true));
      }
      return;
    }

    if (modalItemId) {
      if (event.key === 'Escape') {
        event.preventDefault();
        closeModal();
        return;
      }

      if (event.key === 'Enter' && launchBtnEl && !launchBtnEl.disabled) {
        event.preventDefault();
        handleLibraryAction(modalItemId);
        return;
      }
    }

    if (isTypingTarget(event.target)) return;

    if (event.key === 'ArrowLeft') {
      event.preventDefault();
      moveSelection(-1, 0);
      return;
    }

    if (event.key === 'ArrowRight') {
      event.preventDefault();
      moveSelection(1, 0);
      return;
    }

    if (event.key === 'ArrowUp') {
      event.preventDefault();
      moveSelection(0, -1);
      return;
    }

    if (event.key === 'ArrowDown') {
      event.preventDefault();
      moveSelection(0, 1);
      return;
    }

    if (event.key === 'Enter') {
      event.preventDefault();
      const item = ensureSelectedItem();
      if (item) openGameModal(item.id);
      return;
    }

    if (event.key === 'Escape') {
      exitFullscreen();
    }
  });

  window.addEventListener('resize', () => updateGridLayout(orderedLibraryItems().length));

  try {
    config = await fetch('/config.json').then((response) => response.json());
  } catch (error) {
    redirectToLogin('The desktop app could not read config.json. Fix the app package and try again.');
    return;
  }

  try {
    libraryConfig = await fetch('/library.json').then((response) => response.json());
  } catch (error) {
    libraryConfig = { items: {} };
  }

  auth.mode = /^dev$/i.test(config.appMode || '') ? 'dev' : 'user';
  signalBase = normalizeBase(config.signalBase);
  apiBase = normalizeBase(config.apiBase || deriveApiBaseFromSignalBase(signalBase));
  signalUrl = signalBase + 'signal.php';

  if (!signalBase || signalBase.includes('YOUR-DOMAIN')) {
    redirectToLogin('signalBase is still using the placeholder value. Update the desktop app config first.');
    return;
  }

  room = localStorage.getItem(STORAGE.room);
  if (!room) {
    room = randomCode();
    localStorage.setItem(STORAGE.room, room);
  }

  await validateSessionOrRedirect();
  await loadSteamLibrary(false);
  await refreshLibrary();

  try {
    await sig('reset');
  } catch (error) {
    setSidebarStatus('Signal Offline', `Cannot reach signal.php. Check signalBase in config.json. (${error.message})`, true);
    return;
  }

  syncSidebarWithState();
  loop().catch((error) => setSidebarStatus('Signal Loop Stopped', error.message, true));
}

init().catch((error) => {
  if (!/Missing saved session|Saved session expired|Missing DEV key/.test(error.message || '')) {
    setSidebarStatus('Dashboard Error', error.message || 'The PocketVR dashboard failed to start.', true);
  }
});
