/**
 * AURA FARMING — Etapa 22
 * Espectador em tempo real com dados por polling e vídeo P2P via WebRTC.
 */
(() => {
  'use strict';
  const root = document.querySelector('#spectator-app');
  if (!root) return;
  const baseUrl = document.querySelector('meta[name="app-base-url"]')?.content || '';
  const csrf = document.querySelector('meta[name="csrf-token"]')?.content || '';
  const token = root.dataset.token || '';
  const isOwner = root.dataset.isOwner === '1';
  const initialStatus = root.dataset.status || 'em_andamento';
  const webrtcEnabled = root.dataset.webrtc !== '0' && !isOwner && initialStatus === 'em_andamento';
  const ownerId = Number(root.dataset.ownerId || 0);
  const viewerId = Number(root.dataset.viewerId || 0);
  let commentsEnabled = root.dataset.commentsEnabled !== '0';
  let iceServers = [];
  try { iceServers = JSON.parse(root.dataset.iceServers || '[]'); } catch (_) { iceServers = []; }
  const video = document.querySelector('#spectator-video');
  const placeholder = document.querySelector('#spectator-placeholder');
  const toast = document.querySelector('#spectator-toast');
  const ended = document.querySelector('#spectator-ended');
  const likeButton = document.querySelector('#btn-like');
  const superButton = document.querySelector('#btn-superlike');
  const pendingIce = [];
  let pc = null;
  let stateTimer = null;
  let signalTimer = null;
  let stopped = false;
  let lastState = null;
  let commentTimer = null;
  let lastCommentId = 0;
  const commentsSection = document.querySelector('#spectator-comments');
  const commentList = document.querySelector('#spectator-comment-list');
  const commentForm = document.querySelector('#spectator-comment-form');
  const commentInput = document.querySelector('#spectator-comment-input');
  const blockButton = document.querySelector('#btn-block-live-user');
  const diamondBalanceEl = document.querySelector('#viewer-diamonds');
  let viewerDiamonds = Number(diamondBalanceEl?.textContent?.replace(/\D/g, '') || 0);

  const $ = id => document.getElementById(id);
  const fmt = value => Number(value || 0).toLocaleString('pt-BR', { maximumFractionDigits: 2 });
  const time = seconds => {
    const safe = Math.max(0, Math.ceil(Number(seconds) || 0));
    return `${Math.floor(safe / 60).toString().padStart(2, '0')}:${(safe % 60).toString().padStart(2, '0')}`;
  };

  async function jsonFetch(url, options = {}) {
    const response = await fetch(url, { credentials: 'same-origin', ...options });
    const data = await response.json().catch(() => ({}));
    if (!response.ok || !data.ok) throw new Error(data.erro || 'Falha de comunicação.');
    return data;
  }

  function showToast(message, kind = 'ok') {
    toast.textContent = message;
    toast.dataset.kind = kind;
    toast.classList.remove('spectator-toast--show');
    void toast.offsetWidth;
    toast.classList.add('spectator-toast--show');
    window.setTimeout(() => toast.classList.remove('spectator-toast--show'), 2100);
  }

  function updateState(p) {
    lastState = p;
    $('live-viewers').textContent = p.espectadores ?? 0;
    $('live-timer').textContent = time(p.tempo_restante);
    $('live-aura').textContent = fmt(p.aura);
    $('live-progress').style.width = `${Math.min(100, (Number(p.aura || 0) / 1000) * 100)}%`;
    $('live-likes').textContent = p.likes ?? 0;
    $('live-superlikes').textContent = p.superlikes ?? 0;
    $('live-total').textContent = fmt(p.pontuacao_total);
    $('live-combo').textContent = `x${p.combo_atual || 1} • ${p.combo_hits_atual || 0}`;
    root.dataset.auraLevel = String(p.nivel_aura_maximo || 0);
    if (Object.prototype.hasOwnProperty.call(p, 'diamond_balance')) {
      viewerDiamonds = Number(p.diamond_balance || 0);
      if (diamondBalanceEl) diamondBalanceEl.textContent = viewerDiamonds.toLocaleString('pt-BR');
    }
    if (p.diamond_reactions) {
      if (likeButton && p.diamond_reactions.like) likeButton.dataset.cost = String(p.diamond_reactions.like.diamonds || 2);
      if (superButton && p.diamond_reactions.superlike) superButton.dataset.cost = String(p.diamond_reactions.superlike.diamonds || 10);
    }
    if (p.interacoes_usuario) {
      if (p.interacoes_usuario.like) likeButton.disabled = true;
      if (p.interacoes_usuario.superlike) superButton.disabled = true;
    }
    if (!p.pode_interagir) {
      likeButton.disabled = true;
      superButton.disabled = true;
    }
    if (Object.prototype.hasOwnProperty.call(p, 'comments_enabled')) {
      const enabledNow = Boolean(p.comments_enabled);
      if (commentsEnabled !== enabledNow) {
        commentsEnabled = enabledNow;
        if (commentsSection) commentsSection.hidden = !commentsEnabled;
        if (commentsEnabled && !commentTimer) commentTimer = window.setInterval(pollComments, 1800);
        if (!commentsEnabled && commentTimer) { clearInterval(commentTimer); commentTimer = null; }
      }
    }
    if (p.status === 'finalizada' || p.status === 'cancelada' || Number(p.tempo_restante) <= 0) {
      stopLive();
      $('ended-score').textContent = fmt(p.pontuacao_total);
      ended.hidden = false;
    }
  }

  async function pollState() {
    if (stopped) return;
    try {
      const data = await jsonFetch(`${baseUrl}/api/v1/live/state.php?s=${encodeURIComponent(token)}`, {
        method: 'POST', headers: { 'X-CSRF-Token': csrf, 'Content-Type': 'application/json' }, body: '{}',
      });
      updateState(data.partida);
    } catch (error) {
      console.warn(error);
      if (/removido|não está disponível|não encontrada|bloquead/i.test(error.message || '')) {
        stopLive();
        placeholder.classList.remove('spectator-placeholder--connected');
        placeholder.querySelector('strong').textContent = 'ACESSO À TRANSMISSÃO ENCERRADO';
        placeholder.querySelector('span').textContent = error.message;
        showToast(error.message, 'error');
      }
    }
  }

  function appendComment(comment) {
    if (!commentList || document.querySelector(`[data-comment-id="${Number(comment.id)}"]`)) return;
    const article = document.createElement('article');
    article.dataset.commentId = String(Number(comment.id));
    const img = document.createElement('img'); img.src = comment.avatar || ''; img.alt = '';
    const body = document.createElement('div');
    const head = document.createElement('b'); head.textContent = comment.nome || comment.username || 'Jogador';
    const text = document.createElement('p'); text.textContent = comment.body || '';
    body.append(head, text); article.append(img, body);
    if (Number(comment.author_id) !== viewerId) {
      const report = document.createElement('a');
      report.href = `${baseUrl}/pages/denunciar.php?tipo=comment&comentario=${Number(comment.id)}&usuario=${Number(comment.author_id)}`;
      report.textContent = '🚩'; report.title = 'Denunciar comentário'; article.append(report);
    }
    commentList.append(article);
    commentList.scrollTop = commentList.scrollHeight;
    lastCommentId = Math.max(lastCommentId, Number(comment.id) || 0);
  }

  async function pollComments() {
    if (stopped || !commentsEnabled || !commentList) return;
    try {
      const data = await jsonFetch(`${baseUrl}/api/v1/moderation/comments.php?s=${encodeURIComponent(token)}&after=${lastCommentId}`);
      (data.comments || []).forEach(appendComment);
    } catch (error) {
      if (!/desativados/i.test(error.message || '')) console.warn('Comentários', error);
    }
  }

  async function submitComment(event) {
    event.preventDefault();
    const body = String(commentInput?.value || '').trim();
    if (!body) return;
    const button = commentForm?.querySelector('button'); if (button) button.disabled = true;
    try {
      await jsonFetch(`${baseUrl}/api/v1/moderation/comments.php`, {
        method: 'POST', headers: { 'Content-Type': 'application/json', 'X-CSRF-Token': csrf },
        body: JSON.stringify({ s: token, body }),
      });
      commentInput.value = ''; await pollComments();
    } catch (error) { showToast(error.message, 'error'); }
    finally { if (button) button.disabled = false; }
  }

  async function blockOwner() {
    if (!ownerId || !confirm('Bloquear este jogador e encerrar a transmissão?')) return;
    try {
      await jsonFetch(`${baseUrl}/api/v1/moderation/block.php`, {
        method: 'POST', headers: { 'Content-Type': 'application/json', 'X-CSRF-Token': csrf },
        body: JSON.stringify({ user_id: ownerId, action: 'block', reason: 'Bloqueado durante transmissão' }),
      });
      leave(); window.location.href = `${baseUrl}/pages/ao_vivo.php`;
    } catch (error) { showToast(error.message, 'error'); }
  }

  async function sendSignal(tipo, payload = {}) {
    if (stopped) return;
    await jsonFetch(`${baseUrl}/api/v1/live/signal.php`, {
      method: 'POST', headers: { 'Content-Type': 'application/json', 'X-CSRF-Token': csrf },
      body: JSON.stringify({ s: token, tipo, payload }),
    });
  }

  async function flushIce() {
    if (!pc?.remoteDescription) return;
    while (pendingIce.length) {
      try { await pc.addIceCandidate(pendingIce.shift()); } catch (error) { console.warn('ICE recusado', error); }
    }
  }

  async function pollSignals() {
    if (stopped) return;
    try {
      const data = await jsonFetch(`${baseUrl}/api/v1/live/signal.php?s=${encodeURIComponent(token)}`);
      for (const signal of data.sinais || []) {
        if (signal.tipo === 'answer') {
          await pc.setRemoteDescription(signal.payload);
          await flushIce();
        } else if (signal.tipo === 'ice') {
          const candidate = signal.payload?.candidate ? signal.payload : null;
          if (!candidate) continue;
          if (pc.remoteDescription) await pc.addIceCandidate(candidate).catch(() => {});
          else pendingIce.push(candidate);
        } else if (signal.tipo === 'bye') {
          placeholder.classList.remove('spectator-placeholder--connected');
          placeholder.querySelector('strong').textContent = 'TRANSMISSÃO ENCERRADA';
        }
      }
    } catch (error) {
      console.warn('Sinalização WebRTC', error);
    }
  }

  async function startWebRtc() {
    if (!window.RTCPeerConnection) {
      placeholder.querySelector('strong').textContent = 'VÍDEO NÃO SUPORTADO NESTE NAVEGADOR';
      return;
    }
    if (!webrtcEnabled) {
      placeholder.querySelector('strong').textContent = 'DADOS AO VIVO CONECTADOS';
      placeholder.querySelector('span').textContent = isOwner ? 'Use outro aparelho e outra conta para testar o modo espectador.' : 'A transmissão de vídeo está desativada ou encerrada.';
      return;
    }
    pc = new RTCPeerConnection({ iceServers });
    pc.addTransceiver('video', { direction: 'recvonly' });
    pc.ontrack = event => {
      const stream = event.streams?.[0] || new MediaStream([event.track]);
      video.srcObject = stream;
      video.play().catch(() => {});
      placeholder.classList.add('spectator-placeholder--connected');
      root.classList.add('spectator-app--video-live');
    };
    pc.onicecandidate = event => {
      if (event.candidate) sendSignal('ice', event.candidate.toJSON ? event.candidate.toJSON() : event.candidate).catch(console.warn);
    };
    pc.onconnectionstatechange = () => {
      const state = pc.connectionState;
      if (state === 'connected') {
        placeholder.classList.add('spectator-placeholder--connected');
      } else if (['failed', 'disconnected'].includes(state)) {
        placeholder.classList.remove('spectator-placeholder--connected');
        placeholder.querySelector('strong').textContent = 'RECONECTANDO À CÂMERA…';
      }
    };
    const offer = await pc.createOffer({ offerToReceiveVideo: true, offerToReceiveAudio: false });
    await pc.setLocalDescription(offer);
    await sendSignal('offer', { type: offer.type, sdp: offer.sdp });
  }

  async function interact(type, button) {
    if (button.disabled) return;
    const cost = Number(button.dataset.cost || (type === 'superlike' ? 10 : 2));
    if (viewerDiamonds < cost) {
      showToast(`Diamantes insuficientes. Você precisa de ${cost} Diamantes.`, 'error');
      const buy = document.querySelector('.spectator-buy-diamonds');
      if (buy) {
        buy.classList.remove('spectator-buy-diamonds--pulse');
        void buy.offsetWidth;
        buy.classList.add('spectator-buy-diamonds--pulse');
      }
      return;
    }
    button.disabled = true;
    try {
      const data = await jsonFetch(`${baseUrl}/api/v1/live/interact.php`, {
        method: 'POST', headers: { 'Content-Type': 'application/json', 'X-CSRF-Token': csrf },
        body: JSON.stringify({ s: token, tipo: type }),
      });
      updateState(data.partida);
      showToast(data.mensagem || (type === 'superlike' ? 'Super Like enviado com Diamantes!' : 'Like enviado com Diamantes!'));
      root.classList.remove('spectator-app--social-burst');
      void root.offsetWidth;
      root.classList.add('spectator-app--social-burst');
      if (navigator.vibrate) navigator.vibrate(type === 'superlike' ? [70, 35, 100] : 45);
    } catch (error) {
      showToast(error.message, 'error');
      if (!/já enviou/i.test(error.message)) button.disabled = false;
    }
  }

  function stopLive() {
    if (stopped) return;
    if (pc) { try { sendSignal('bye', {}).catch(() => {}); } catch (_) {} }
    stopped = true;
    clearInterval(stateTimer); clearInterval(signalTimer); clearInterval(commentTimer);
    if (pc) pc.close();
  }

  function leave() {
    const body = JSON.stringify({ s: token });
    fetch(`${baseUrl}/api/v1/live/leave.php`, {
      method: 'POST', credentials: 'same-origin', keepalive: true,
      headers: { 'Content-Type': 'application/json', 'X-CSRF-Token': csrf }, body,
    }).catch(() => {});
    stopLive();
  }

  likeButton?.addEventListener('click', () => interact('like', likeButton));
  superButton?.addEventListener('click', () => interact('superlike', superButton));
  commentForm?.addEventListener('submit', submitComment);
  blockButton?.addEventListener('click', blockOwner);
  window.addEventListener('pagehide', leave);
  document.addEventListener('visibilitychange', () => {
    if (document.visibilityState === 'visible' && !stopped) { pollState(); pollSignals(); }
  });

  pollState();
  pollComments();
  startWebRtc().catch(error => {
    console.warn(error);
    placeholder.querySelector('strong').textContent = 'DADOS AO VIVO CONECTADOS';
    placeholder.querySelector('span').textContent = 'A câmera P2P não pôde ser conectada neste aparelho.';
  });
  stateTimer = window.setInterval(pollState, 1500);
  signalTimer = window.setInterval(pollSignals, 800);
  if (commentsEnabled) commentTimer = window.setInterval(pollComments, 1800);
})();
