/* global WPGCL, jQuery */
(function($){
  if (!WPGCL || !WPGCL.currentUser) return;
  const state = { room: new URLSearchParams(window.location.search).get('room') || WPGCL.defaultRoom || 'main', peers: {}, users: {}, currentRemote: null, sinceSignal: '1970-01-01 00:00:00', sinceMsgId: 0, localStream: null };
  function el(id){ return document.getElementById(id); }
  function labelFor(id){ const u = state.users[id]; return u ? (u.display + ' (#' + id + ')') : ('#' + id); }
  function setRemoteStatus(t){ const s=el('wpgc-remote-status'); if (s) s.textContent=t; }
  function setRemoteName(t){ const s=el('wpgc-remote-name'); if (s) s.textContent=t; }
  async function initMedia(){ try{ state.localStream = await navigator.mediaDevices.getUserMedia({video:true,audio:true}); const me=el('wpgc-local'); me.srcObject=state.localStream; me.muted=true; me.playsInline=true; await me.play().catch(()=>{});}catch(e){ console.error(e); alert('Could not access camera/microphone.'); } }
  function clearRemoteVideo(){ const rv=el('wpgc-remote'); if (rv){ rv.srcObject=null; rv.load(); } }
  function closeAllPeers(){ Object.values(state.peers).forEach(pc=>{ try{ pc.getSenders().forEach(s=>pc.removeTrack(s)); pc.close(); }catch(e){} }); state.peers={}; state.currentRemote=null; clearRemoteVideo(); setRemoteStatus('Not connected'); setRemoteName('—'); }
  function createPC(remoteId){ const servers=[{urls:'stun:stun.l.google.com:19302'}]; if (WPGCL.turn && Array.isArray(WPGCL.turn.urls) && WPGCL.turn.urls.length){ const t={urls:WPGCL.turn.urls}; if (WPGCL.turn.username) t.username=WPGCL.turn.username; if (WPGCL.turn.credential) t.credential=WPGCL.turn.credential; servers.push(t);} const pc=new RTCPeerConnection({iceServers:servers}); state.localStream.getTracks().forEach(tr=>pc.addTrack(tr,state.localStream)); pc.ontrack=(ev)=>{ const v=el('wpgc-remote'); const stream=ev.streams&&ev.streams[0]?ev.streams[0]:new MediaStream([ev.track]); if (v.srcObject!==stream){ v.srcObject=stream; } v.playsInline=true; const tryPlay=()=>v.play().catch(()=>setTimeout(tryPlay,250)); tryPlay(); setRemoteStatus('Connected'); setRemoteName(labelFor(remoteId)); }; pc.onicecandidate=(ev)=>{ if(ev.candidate) post('signal',{room:state.room,type:'candidate',payload:ev.candidate,target_id:remoteId}); }; return pc; }
  async function connectToUser(remoteId){ if (remoteId===WPGCL.currentUser) return; if (state.currentRemote===remoteId && state.peers[remoteId]) return; closeAllPeers(); state.currentRemote=remoteId; setRemoteStatus('Connecting...'); setRemoteName(labelFor(remoteId)); const pc=createPC(remoteId); state.peers[remoteId]=pc; const offer=await pc.createOffer({offerToReceiveAudio:true,offerToReceiveVideo:true}); await pc.setLocalDescription(offer); await post('signal',{room:state.room,type:'offer',payload:offer,target_id:remoteId}); }
  async function handleSignal(sig){ const from=sig.user_id, type=sig.type, payload=JSON.parse(sig.payload); if (type==='offer'){ closeAllPeers(); state.currentRemote=from; setRemoteStatus('Answering...'); setRemoteName(labelFor(from)); let pc=createPC(from); state.peers[from]=pc; await pc.setRemoteDescription(payload); const answer=await pc.createAnswer(); await pc.setLocalDescription(answer); await post('signal',{room:state.room,type:'answer',payload:answer,target_id:from}); } else if (type==='answer'){ let pc=state.peers[from]; if(pc){ await pc.setRemoteDescription(payload); } } else if (type==='candidate'){ let pc=state.peers[from]; if(pc){ try{ await pc.addIceCandidate(payload);}catch(e){ console.warn(e);} } } }
  function post(path,data){ return $.ajax({url:WPGCL.rest+path,method:'POST',headers:{'X-WP-Nonce':WPGCL.nonce},data:JSON.stringify(data),contentType:'application/json'}); }
  function get(path,params){ return $.ajax({url:WPGCL.rest+path+(params?('?' + new URLSearchParams(params)):''),method:'GET',headers:{'X-WP-Nonce':WPGCL.nonce}}); }
  async function pollSignals(){ try{ const resp=await get('signal/fetch',{room:state.room,since:state.sinceSignal}); state.sinceSignal=resp.now; (resp.signals||[]).forEach(handleSignal);}catch(e){} setTimeout(pollSignals,2000); }
  async function presenceLoop(){ try{ await post('presence',{room:state.room}); const list=await get('presence/list',{room:state.room}); const ul=el('wpgc-users'); ul.innerHTML=''; const map={}; (list||[]).forEach(u=>{ map[u.user_id]=u; }); state.users=map; (list||[]).forEach(u=>{ const li=document.createElement('li'); li.textContent=u.display+' (#'+u.user_id+')'; li.dataset.uid=u.user_id; li.style.cursor='pointer'; li.addEventListener('click',()=>connectToUser(u.user_id)); ul.appendChild(li); }); if (state.currentRemote) setRemoteName(labelFor(state.currentRemote)); }catch(e){} setTimeout(presenceLoop,5000); }
  async function chatLoop(){ try{ const resp=await get('message/fetch',{room:state.room,since_id:state.sinceMsgId}); (resp.messages||[]).forEach(m=>{ state.sinceMsgId=Math.max(state.sinceMsgId,m.id); const row=document.createElement('div'); row.className='wpgc-chat-row'; row.innerHTML='<strong>'+(m.display_name||'User')+':</strong> '+m.message; const log=el('wpgc-chat-log'); if (log){ log.appendChild(row); log.scrollTop=log.scrollHeight; } }); }catch(e){} setTimeout(chatLoop,1500); }
  function bindUI(){ const mic=el('wpgc-btn-mic'), cam=el('wpgc-btn-cam'); if(mic) mic.addEventListener('click',()=>{ const t=state.localStream?.getAudioTracks()[0]; if(t){ t.enabled=!t.enabled; mic.classList.toggle('muted'); } }); if(cam) cam.addEventListener('click',()=>{ const t=state.localStream?.getVideoTracks()[0]; if(t){ t.enabled=!t.enabled; cam.classList.toggle('off'); } }); const disc=el('wpgc-btn-disconnect'); if(disc) disc.addEventListener('click',()=>closeAllPeers()); const form=el('wpgc-chat-form'); if(form) form.addEventListener('submit',async(e)=>{ e.preventDefault(); const t=el('wpgc-chat-text'); const msg=t.value.trim(); if(!msg) return; t.value=''; await post('message',{room:state.room,message:msg}); }); }
  async function start(){ const rn=el('wpgc-room-name'); if(rn) rn.textContent=state.room; setRemoteStatus('Not connected'); setRemoteName('—'); await initMedia(); bindUI(); pollSignals(); presenceLoop(); chatLoop(); const c=document.getElementById('wpgc-credit'); if(c && WPGCL.credit) c.textContent=WPGCL.credit; }
  document.addEventListener('DOMContentLoaded', start);
})(jQuery);
