(()=>{
'use strict';

const BASE='/assets/sounds/';
const S={
  bg:BASE+'lobby-background.mp3',
  // The untouched 6-second original wheel recording.
  wheelDrawing:BASE+'wheel-drawing.wav',
  prize:BASE+'prizing.mp3',
  start:[BASE+'betting-start-1.mp3',BASE+'betting-start-2.mp3'],
  closed:[BASE+'betting-closed-1.mp3',BASE+'betting-closed-2.mp3'],
  refer:BASE+'refer.mp3',
  checkin:BASE+'checkin.mp3',
  vip:BASE+'vip.mp3'
};

const soundEnabled=()=>localStorage.getItem('lz_sound_enabled')!=='0';
let unlocked=false;
let lastPhase='';
let wheelToken=0;
let lastPick={start:-1,closed:-1};
let pageVoicePlayed=false;

const bg=new Audio(S.bg);
bg.loop=true;
bg.preload='auto';
bg.volume=.23;

const wheelDrawing=new Audio(S.wheelDrawing);
wheelDrawing.preload='auto';
wheelDrawing.volume=1;

// Exact regions inside the ORIGINAL 6-second recording.
// 0.000..4.555s = fast/continuous body.  The last 1.445s is the natural
// slowdown, matching zoo.js's six final waits (90+125+175+245+340+470).
const WHEEL_FAST_LOOP_START=1.35;
const WHEEL_FAST_LOOP_END=4.50;
const WHEEL_SLOW_START=4.555;
let wheelMode='idle';
let wheelLoopTimer=null;

const prize=new Audio(S.prize);
prize.preload='auto';
prize.volume=.95;

const activeOneShots=new Set();

function play(a){
  if(!soundEnabled())return Promise.resolve(false);
  try{
    const p=a.play();
    if(p&&typeof p.then==='function'){
      return p.then(()=>true).catch(()=>false);
    }
    return Promise.resolve(true);
  }catch(e){
    return Promise.resolve(false);
  }
}

function stop(a,rewind=true){
  try{
    a.pause();
    if(rewind)a.currentTime=0;
  }catch(e){}
}

function setBg(v){bg.volume=Math.max(0,Math.min(1,v));}

function pick(arr,key){
  let i=Math.floor(Math.random()*arr.length);
  if(i===lastPick[key])i=(i+1)%arr.length;
  lastPick[key]=i;
  return arr[i];
}

function oneShot(src,vol=.95,onDone=null){
  if(!soundEnabled())return null;
  const a=new Audio(src);
  a.preload='auto';
  a.volume=vol;
  activeOneShots.add(a);
  let done=false;
  const finish=()=>{
    if(done)return;
    done=true;
    activeOneShots.delete(a);
    if(onDone)onDone();
  };
  a.addEventListener('ended',finish,{once:true});
  a.addEventListener('error',finish,{once:true});
  play(a);
  return a;
}

function ensureBg(){
  if(!soundEnabled())return;
  play(bg);
}

function clearWheelLoopTimer(){
  if(wheelLoopTimer!==null){
    clearInterval(wheelLoopTimer);
    wheelLoopTimer=null;
  }
}

function stopWheelDrawing(rewind=true){
  clearWheelLoopTimer();
  wheelMode='idle';
  wheelDrawing.playbackRate=1;
  stop(wheelDrawing,rewind);
}

function startWheelMotion(){
  // Called explicitly by zoo.js at the exact first visual wheel step.
  // Do NOT require MutationObserver to have already noticed DRAWING; that
  // callback runs asynchronously and used to reject the fast wheel sound.
  if(!soundEnabled())return;

  wheelToken++;
  stopWheelDrawing(true);
  wheelMode='fast';
  wheelDrawing.playbackRate=1;
  wheelDrawing.currentTime=0;
  play(wheelDrawing);

  // Let the original recording run normally. If the RNG route needs more
  // time, repeat ONLY its stable fast section. Never allow the recording to
  // enter its slow tail until zoo.js reaches the final six visual boxes.
  wheelLoopTimer=setInterval(()=>{
    if(wheelMode!=='fast'||lastPhase!=='DRAWING')return;
    try{
      if(wheelDrawing.currentTime>=WHEEL_FAST_LOOP_END){
        wheelDrawing.currentTime=WHEEL_FAST_LOOP_START;
        if(wheelDrawing.paused)play(wheelDrawing);
      }
    }catch(e){}
  },18);
}

function beginWheelSlowdown(durationMs=1445){
  // ONE synchronized slowdown only. Keep using the SAME Audio element:
  // stop looping the fast body and move directly into the original WAV's
  // natural slowdown tail. No pause/restart and no return to the fast loop.
  if(lastPhase!=='DRAWING'||!soundEnabled())return;
  if(wheelMode!=='fast')return;

  clearWheelLoopTimer();
  wheelMode='slow';
  wheelDrawing.playbackRate=1;

  try{
    // The original recording's final ~1.445s is the genuine slowdown section.
    // Seeking the already-playing element here keeps one continuous wheel
    // channel while synchronizing that tail to zoo.js's final six boxes.
    wheelDrawing.currentTime=WHEEL_SLOW_START;
    if(wheelDrawing.paused)play(wheelDrawing);
  }catch(e){}
}

function endWheelAtRngWinner(){
  // The original slow tail has just reached the RNG-selected box.
  wheelToken++;
  stopWheelDrawing(true);

  setTimeout(()=>{
    if(lastPhase==='PRIZING'){
      stop(prize);
      prize.currentTime=0;
      play(prize);
    }
  },180);
}

function applyPhase(raw){
  const p=String(raw||'').trim().toUpperCase();
  if(!p||p===lastPhase)return;

  const previous=lastPhase;
  lastPhase=p;

  if(p==='BETTING'){
    wheelToken++;
    stopWheelDrawing(true);stop(prize);
    setBg(.23);
    ensureBg();
    oneShot(pick(S.start,'start'),.95);
    return;
  }

  if(p==='BETTING CLOSED'){
    wheelToken++;
    stopWheelDrawing(true);
    setBg(.10);
    ensureBg();
    oneShot(pick(S.closed,'closed'),.97);
    return;
  }

  if(p==='DRAWING'){
    setBg(.025);
    ensureBg();
    // zoo.js starts the wheel recording exactly with the first moving box.
    return;
  }

  if(p==='PRIZING'){
    setBg(.06);
    ensureBg();
    if(previous==='DRAWING')endWheelAtRngWinner();
    else{
      stop(prize);prize.currentTime=0;play(prize);
    }
    return;
  }

  setBg(.23);
  ensureBg();
}

function observePhase(){
  const el=document.getElementById('phase');
  if(!el)return;
  const run=()=>applyPhase(el.textContent);
  new MutationObserver(run).observe(el,{childList:true,characterData:true,subtree:true});
  run();
}

function pageKind(){
  const p=location.pathname.toLowerCase();
  if(/\/account\/checkin(?:\.html)?\/?$/.test(p))return 'checkin';
  if(/\/account\/vip(?:\.html)?\/?$/.test(p))return 'vip';
  if(/(?:refer|referral|invite)/.test(p))return 'refer';
  return '';
}

function playPageVoice(){
  if(pageVoicePlayed||!soundEnabled())return;
  const kind=pageKind();
  if(!kind)return;
  pageVoicePlayed=true;

  const old=bg.volume||.23;
  setBg(.055);
  ensureBg();
  oneShot(S[kind],.98,()=>{
    setBg(old);
    ensureBg();
  });
}

async function unlock(){
  if(!soundEnabled())return;
  unlocked=true;

  // Any click/touch/key unlocks audio. The sound button is NOT required.
  const ok=await play(bg);
  if(ok){
    setBg(document.getElementById('phase')?.textContent==='DRAWING'?.025:.23);
    playPageVoice();

    // If browser blocked an earlier phase sound before first gesture,
    // synchronize immediately with the CURRENT phase now.
    const phase=String(document.getElementById('phase')?.textContent||'').trim().toUpperCase();
    if(phase){
      lastPhase='';
      applyPhase(phase);
    }
  }
}

function attemptAutoplay(){
  if(!soundEnabled())return;
  // Works automatically in APK/WebViews or browsers that allow autoplay.
  // Normal desktop/mobile browsers may require the first user interaction.
  play(bg).then(ok=>{
    if(ok){
      unlocked=true;
      playPageVoice();
    }
  });
}

function setEnabled(v){
  localStorage.setItem('lz_sound_enabled',v?'1':'0');
  if(!v){
    wheelToken++;
    clearWheelLoopTimer();
    [bg,wheelDrawing,prize].forEach(a=>stop(a,false));
    activeOneShots.forEach(a=>stop(a));
    activeOneShots.clear();
  }else{
    pageVoicePlayed=false;
    attemptAutoplay();
    unlock();
  }
  updateToggle();
}

function updateToggle(){
  const b=document.getElementById('lzSoundToggle');
  if(!b)return;
  b.textContent=soundEnabled()?'🔊':'🔇';
  b.title=soundEnabled()?'Sound on':'Sound off';
}

function addToggle(){
  if(document.getElementById('lzSoundToggle'))return;
  const b=document.createElement('button');
  b.id='lzSoundToggle';
  b.type='button';
  b.setAttribute('aria-label','Toggle sound');
  b.style.cssText='position:fixed;right:10px;top:10px;z-index:2147483000;width:36px;height:36px;border-radius:50%;border:1px solid #b68a20;background:#07180fdd;color:#ffd34b;font-size:17px;cursor:pointer';
  b.onclick=e=>{
    e.preventDefault();
    e.stopPropagation();
    setEnabled(!soundEnabled());
  };
  document.body.appendChild(b);
  updateToggle();
}

function init(){
  observePhase();

  // Try immediately. APK/WebView can allow this without a gesture.
  attemptAutoplay();

  // Web fallback: ANY normal interaction unlocks all sounds.
  ['pointerdown','touchstart','mousedown','keydown','click'].forEach(evt=>{
    document.addEventListener(evt,unlock,{once:true,capture:true,passive:true});
  });

  // Page voice means "user is INSIDE the page", not "button was clicked".
  // If autoplay is allowed, it plays now. Otherwise it plays on the first
  // ordinary interaction anywhere on that page.
  setTimeout(playPageVoice,120);

  document.addEventListener('visibilitychange',()=>{
    if(document.hidden){
      stop(bg,false);stop(wheelDrawing,false);
    }else{
      attemptAutoplay();
      // Do not restart/rewind wheel audio on visibility return; zoo.js owns
      // the exact motion boundary and will start the next legitimate draw.
    }
  });
}

window.LuckZooAudio={unlock,setEnabled,isEnabled:soundEnabled,playPageVoice,startWheelMotion,beginWheelSlowdown};

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