/* LuckZoo bet-chip sound hook.
   Audio/UI only: does not place bets, change totals, alter RNG, or touch round flow. */
(()=>{
'use strict';

const SRC='/assets/sounds/chips.wav';
const POOL_SIZE=8;
const pool=[];
let cursor=0;
let lastPlay=0;
const seenBot=new WeakSet();
const playerValue=new WeakMap();

const soundEnabled=()=>localStorage.getItem('lz_sound_enabled')!=='0';

function makeAudio(){
  const a=new Audio(SRC);
  a.preload='auto';
  a.volume=.72;
  try{a.load()}catch(e){}
  return a;
}

for(let i=0;i<POOL_SIZE;i++)pool.push(makeAudio());

function playChip(){
  if(!soundEnabled() || document.hidden)return;
  const now=performance.now();
  // Bot events are already spaced about 95ms apart. This tiny guard only
  // prevents duplicate MutationObserver records for the exact same visual.
  if(now-lastPlay<38)return;
  lastPlay=now;

  const a=pool[cursor++%pool.length];
  try{
    a.pause();
    a.currentTime=0;
    const p=a.play();
    if(p&&p.catch)p.catch(()=>{});
  }catch(e){}
}

function playerChanged(el){
  if(!el || !el.classList?.contains('bet-mark'))return;
  const value=String(el.textContent||'').trim();
  if(!value)return;
  if(playerValue.get(el)===value)return;
  playerValue.set(el,value);
  playChip();
}

function scanAdded(node){
  if(!(node instanceof Element))return;

  if(node.classList.contains('lz-landed-chip') && !seenBot.has(node)){
    seenBot.add(node);
    playChip();
  }
  node.querySelectorAll?.('.lz-landed-chip').forEach(el=>{
    if(seenBot.has(el))return;
    seenBot.add(el);
    playChip();
  });

  if(node.classList.contains('bet-mark'))playerChanged(node);
  node.querySelectorAll?.('.bet-mark').forEach(playerChanged);
}


function clearBettingChips(){
  // Keep THIS player's own stake visible after betting locks, but remove the
  // physical chip appearance. zoo.js already clears #betMarks when the next
  // round starts, so these plain amount labels naturally disappear then.
  document.querySelectorAll('#betMarks .bet-mark').forEach(mark=>{
    const amount=String(mark.dataset.betTotal||mark.textContent||'').trim();
    if(amount)mark.textContent=amount;
    mark.classList.remove('bet-mark');
    mark.classList.add('player-locked-amount');
  });

  // Bot flying/landed chip circles disappear as soon as betting closes.
  // Candidate total badges are intentionally left alone.
  document.querySelectorAll(
    '#lz-bot-overlay .lz-flying-chip,'+
    '#lz-bot-overlay .lz-landed-chip'
  ).forEach(el=>el.remove());
}

function observeBettingClose(){
  const phase=document.getElementById('phase');
  if(!phase)return;
  let wasBetting=false;

  const sync=()=>{
    const p=String(phase.textContent||'').trim().toUpperCase();
    if(p==='BETTING'){
      wasBetting=true;
      return;
    }
    if(wasBetting && (p==='BETTING CLOSED'||p==='DRAWING'||p==='PRIZING')){
      wasBetting=false;
      clearBettingChips();
    }
  };

  new MutationObserver(sync).observe(phase,{childList:true,characterData:true,subtree:true});
  sync();
}

function init(){
  observeBettingClose();

  const observer=new MutationObserver(records=>{
    const playerTargets=new Set();

    for(const m of records){
      m.addedNodes.forEach(scanAdded);

      const el=m.target.nodeType===Node.TEXT_NODE
        ? m.target.parentElement
        : m.target;
      const mark=el?.closest?.('.bet-mark');
      if(mark)playerTargets.add(mark);
    }

    // Mutation batches can contain both append + text update for one bet.
    // Evaluate each player marker once after the batch has settled.
    playerTargets.forEach(playerChanged);
  });

  observer.observe(document.body,{subtree:true,childList:true,characterData:true});

  // Prime the audio pool on the first ordinary user gesture. No audible sound
  // is produced here; this only helps mobile browsers permit later bot sounds.
  const unlock=()=>{
    const a=pool[0];
    const old=a.volume;
    try{
      a.volume=0;
      const p=a.play();
      if(p&&p.then){
        p.then(()=>{a.pause();a.currentTime=0;a.volume=old}).catch(()=>{a.volume=old});
      }else{
        a.pause();a.currentTime=0;a.volume=old;
      }
    }catch(e){a.volume=old}
  };
  ['pointerdown','touchstart','mousedown','keydown'].forEach(evt=>
    document.addEventListener(evt,unlock,{once:true,capture:true,passive:true})
  );
}

if(document.readyState==='loading')document.addEventListener('DOMContentLoaded',init,{once:true});
else init();
})();
