/* ============================================================
   WAVELENGTH — spectrum guessing (Classic + Guesser modes)
   ============================================================ */
const { useState: useWv, useRef: useRWv } = React;

function wavelengthScore(target, guess){
  const d=Math.abs(target-guess);
  if(d<=4) return 4;
  if(d<=10) return 3;
  if(d<=18) return 2;
  if(d<=30) return 1;
  return 0;
}

function SpectrumBar({ left, right, value, onChange, showTarget, target, showGuess, guess, interactive }){
  const trackRef=useRWv(null);
  const pct=v=>Math.max(0,Math.min(100,v));

  const setFromClientX=(clientX)=>{
    const el=trackRef.current;
    if(!el||!onChange) return;
    const r=el.getBoundingClientRect();
    const x=Math.max(0,Math.min(r.width,clientX-r.left));
    onChange(Math.round(x/r.width*100));
  };

  const onPointerDown=(e)=>{
    if(!interactive) return;
    e.currentTarget.setPointerCapture(e.pointerId);
    setFromClientX(e.clientX);
  };
  const onPointerMove=(e)=>{
    if(!interactive||!e.currentTarget.hasPointerCapture(e.pointerId)) return;
    setFromClientX(e.clientX);
  };

  return (
    <div className="wavelength-wrap">
      <div className="wavelength-labels">
        <span className="wavelength-pole">{left}</span>
        <span className="wavelength-pole wavelength-pole-r">{right}</span>
      </div>
      <div ref={trackRef} className={'wavelength-track'+(interactive?' interactive':'')}
        onPointerDown={onPointerDown} onPointerMove={onPointerMove}>
        <div className="wavelength-gradient"/>
        {showTarget!=null && showTarget && (
          <div className="wavelength-marker target" style={{left:pct(target)+'%'}}>
            <i/><span>target</span>
          </div>
        )}
        {showGuess!=null && showGuess && (
          <div className="wavelength-marker guess" style={{left:pct(guess)+'%'}}>
            <i/><span>guess</span>
          </div>
        )}
        {value!=null && interactive && (
          <div className="wavelength-thumb" style={{left:pct(value)+'%'}}/>
        )}
      </div>
    </div>
  );
}

function assignQuestions(insiders){
  const pool=shuffle(DATA.WAVELENGTH_QUESTIONS||[]);
  const q={};
  insiders.forEach((p,i)=>{ q[p]=pool[i%pool.length]; });
  return q;
}

function GameWavelength({ game, players, scoring, scores, addScore, onExit, onHome }){
  const leave=onHome||onExit;
  const [mode,setMode]=useWv('classic');       // classic | guesser
  const [rounds,setRounds]=useWv(1);
  const [cats,setCats]=useWv(()=>new Set(DATA.WAVELENGTH_CATS));
  const [phase,setPhase]=useWv('setup');
  const deckRef=useRWv(null);
  const [order,setOrder]=useWv([]);
  const [turn,setTurn]=useWv(0);
  const [spectrum,setSpectrum]=useWv(null);
  const [target,setTarget]=useWv(50);
  const [guess,setGuess]=useWv(50);
  const [questions,setQuestions]=useWv({});
  const [roundScore,setRoundScore]=useWv(0);
  const [localScores,setLocalScores]=useWv({});

  const toggleCat=(c)=>setCats(s=>{ const n=new Set(s); n.has(c)?n.delete(c):n.add(c); return n; });

  const begin=()=>{
    const pool=DATA.WAVELENGTH.filter(x=>cats.has(x.cat));
    deckRef.current=makeDeck(pool.length?pool:DATA.WAVELENGTH);
    const ord=[];
    for(let r=0;r<rounds;r++) shuffle(players).forEach(p=>ord.push(p));
    setOrder(ord);
    setTurn(0);
    setLocalScores(Object.fromEntries(players.map(p=>[p,0])));
    startRound(ord[0]);
  };

  const startRound=(leadPlayer)=>{
    const spec=deckRef.current.draw();
    const t=Math.floor(Math.random()*101);
    setSpectrum({...spec, lead:leadPlayer});
    setTarget(t);
    setGuess(50);
    setRoundScore(0);
    if(mode==='guesser'){
      const insiders=players.filter(p=>p!==leadPlayer);
      setQuestions(assignQuestions(insiders));
      setPhase('insiderReveal');
    } else {
      setPhase('psychicReveal');
    }
  };

  const lead=order[turn];
  const psychic=lead;
  const guesser=lead;
  const insiders=players.filter(p=>p!==guesser);
  const guessers=players.filter(p=>p!==psychic);

  const applyScore=(pts)=>{
    setRoundScore(pts);
    setLocalScores(s=>{
      const n={...s};
      if(mode==='guesser'){
        n[guesser]=(n[guesser]||0)+pts;
        if(pts>=3) insiders.forEach(p=>{ n[p]=(n[p]||0)+1; });
      } else {
        guessers.forEach(p=>{ n[p]=(n[p]||0)+pts; });
        if(pts===4) n[psychic]=(n[psychic]||0)+1;
      }
      return n;
    });
    if(scoring){
      if(mode==='guesser'){
        addScore(guesser,pts);
        if(pts>=3) insiders.forEach(p=>addScore(p,1));
      } else {
        guessers.forEach(p=>addScore(p,pts));
        if(pts===4) addScore(psychic,1);
      }
    }
    setPhase('reveal');
  };

  const afterReveal=()=>applyScore(wavelengthScore(target,guess));

  const next=()=>{
    if(turn+1>=order.length){ setPhase('done'); }
    else { const t=turn+1; setTurn(t); startRound(order[t]); }
  };

  const setupFields=(
    <>
      <div className="field">
        <label>Game mode</label>
        <Segmented
          options={[
            {value:'classic',label:'Classic'},
            {value:'guesser',label:'The Guesser'},
          ]}
          value={mode}
          onChange={setMode}
          color="var(--grape)"
        />
        <p className="muted" style={{fontSize:12.5,marginTop:10}}>
          {mode==='classic'
            ? 'One psychic sees the target and gives a clue. Everyone else guesses together.'
            : 'Everyone except one sees the target. Each insider answers a question out loud. The guesser places the dial.'}
        </p>
      </div>
      <div className="field">
        <label>Rounds per player</label>
        <Stepper value={rounds} min={1} max={3} onChange={setRounds}/>
      </div>
      <div className="field">
        <label>Categories</label>
        <div className="wrap" style={{gap:8}}>
          {DATA.WAVELENGTH_CATS.map(c=>(
            <button key={c} onClick={()=>toggleCat(c)} className={'chip selectable'+(cats.has(c)?' sel':'')} style={{fontSize:14}}>
              {cats.has(c)?'✓ ':''}{c}
            </button>
          ))}
        </div>
      </div>
    </>
  );

  /* ---- SETUP ---- */
  if(phase==='setup'){
    return (
      <div className="app screen">
        <TopBar onBack={onExit} title="Wavelength" color={game.color}/>
        <div className="setup">
          <h2>Wavelength</h2>
          <p className="lead">Read the spectrum poles. Land your guess on the hidden target. Close = points.</p>
          {setupFields}
          <div style={{marginTop:8}}>
            <Btn color="grape" size="lg" disabled={cats.size===0} onClick={begin}>Start →</Btn>
          </div>
        </div>
      </div>
    );
  }

  /* ========== CLASSIC MODE ========== */

  if(mode==='classic' && phase==='psychicReveal'){
    return (
      <div className="app screen">
        <TopBar onBack={onExit} title="Wavelength · Classic" color={game.color}
          right={<span className="mono" style={{fontSize:11,color:'#9082BE'}}>{turn+1}/{order.length}</span>}/>
        <PrivateReveal
          players={[psychic]}
          accent={game.color}
          doneLabel="I've seen the target"
          getContent={()=>(
            <>
              <div className="kicker">your secret target</div>
              <p className="muted" style={{maxWidth:300,marginBottom:16}}>Memorize where the target sits. You'll give a one-word clue.</p>
              <SpectrumBar left={spectrum.left} right={spectrum.right} showTarget={true} target={target}/>
              <p className="mono" style={{fontSize:11,color:'#9082BE',marginTop:16}}>Only you can see the target dot</p>
            </>
          )}
          onDone={()=>setPhase('clue')}
        />
      </div>
    );
  }

  if(mode==='classic' && phase==='clue'){
    return (
      <div className="app screen">
        <TopBar onBack={onExit} title="Wavelength · give a clue" color={game.color}/>
        <div className="center" style={{flex:1,padding:'14px 26px',gap:14}}>
          <div className="kicker">psychic</div>
          <div className="display" style={{fontSize:36}}>{psychic}</div>
          <SpectrumBar left={spectrum.left} right={spectrum.right}/>
          <p className="muted" style={{maxWidth:320,fontSize:15}}>
            <b style={{color:'var(--cream)'}}>{psychic}</b>, give a one-word (or short) clue for where your target sits on this spectrum. Don't say the poles!
          </p>
          <p className="serif-i" style={{fontSize:18,color:'#FFD79A'}}>Everyone else: discuss after the clue.</p>
        </div>
        <div className="pad" style={{paddingTop:6}}>
          <Btn color="grape" size="lg" onClick={()=>setPhase('guess')}>Clue given — group guesses →</Btn>
        </div>
      </div>
    );
  }

  /* ========== GUESSER MODE ========== */

  if(mode==='guesser' && phase==='insiderReveal'){
    return (
      <div className="app screen">
        <TopBar onBack={onExit} title="Wavelength · The Guesser" color={game.color}
          right={<span className="mono" style={{fontSize:11,color:'#9082BE'}}>{turn+1}/{order.length}</span>}/>
        <PrivateReveal
          players={insiders}
          accent={game.color}
          doneLabel="We've all seen it"
          getContent={(name)=>(
            <>
              <div className="kicker">secret target</div>
              <p className="muted" style={{maxWidth:300,marginBottom:12,fontSize:14}}>
                <b style={{color:'var(--cream)'}}>{guesser}</b> doesn't know this. Memorize the spot.
              </p>
              <SpectrumBar left={spectrum.left} right={spectrum.right} showTarget={true} target={target}/>
              <div className="card" style={{marginTop:18,maxWidth:360,width:'100%',padding:'16px 18px',textAlign:'left'}}>
                <div className="panel-title" style={{marginBottom:8}}>Your question</div>
                <p style={{fontSize:15,fontWeight:600,lineHeight:1.35}}>{questions[name]}</p>
              </div>
              <p className="muted" style={{fontSize:13,marginTop:14,maxWidth:300}}>
                Answer out loud so your answer lands at the target — without saying the number!
              </p>
            </>
          )}
          onDone={()=>setPhase('discuss')}
        />
      </div>
    );
  }

  if(mode==='guesser' && phase==='discuss'){
    return (
      <div className="app screen">
        <TopBar onBack={onExit} title="Wavelength · clues given" color={game.color}/>
        <div className="center" style={{flex:1,padding:'14px 22px',gap:12}}>
          <div className="kicker">everyone answered — now guess</div>
          <div className="display" style={{fontSize:32}}>{guesser}</div>
          <p className="muted" style={{maxWidth:320,fontSize:14}}>
            <b style={{color:'var(--cream)'}}>{guesser}</b> wasn't in the loop. Everyone else gave verbal answers to their questions. Listen to the clues!
          </p>
          <SpectrumBar left={spectrum.left} right={spectrum.right}/>
          <div className="card" style={{maxWidth:360,width:'100%',padding:'14px 16px',textAlign:'left'}}>
            <div className="panel-title" style={{marginBottom:10}}>Questions that were answered</div>
            <div className="col" style={{gap:8}}>
              {insiders.map(p=>(
                <div key={p} className="row" style={{gap:10,alignItems:'flex-start'}}>
                  <Avatar name={p} size={22}/>
                  <div style={{flex:1,fontSize:13,color:'var(--ink)',lineHeight:1.3}}>
                    <b>{p}:</b> {questions[p]}
                  </div>
                </div>
              ))}
            </div>
          </div>
        </div>
        <div className="pad" style={{paddingTop:6}}>
          <Btn color="grape" size="lg" onClick={()=>setPhase('guess')}>{guesser} places the guess →</Btn>
        </div>
      </div>
    );
  }

  /* ---- GUESS (both modes) ---- */
  if(phase==='guess'){
    const isGuesserMode=mode==='guesser';
    return (
      <div className="app screen">
        <TopBar onBack={onExit} title="Wavelength · place the guess" color={game.color}/>
        <div className="center" style={{flex:1,padding:'14px 22px',gap:12}}>
          <div className="kicker">{isGuesserMode?'guesser':'group guess'}</div>
          {isGuesserMode
            ? <p className="muted" style={{maxWidth:320,fontSize:14}}><b style={{color:'var(--cream)'}}>{guesser}</b>, drag the dial to where you think the hidden target is.</p>
            : <p className="muted" style={{maxWidth:320,fontSize:14}}>Discuss as a group. Drag the dial to where you think the target is.</p>}
          <SpectrumBar left={spectrum.left} right={spectrum.right} value={guess} onChange={setGuess} interactive={true}/>
          <div className="mono" style={{fontSize:13,color:'#B6A6E8'}}>guess: {guess}</div>
        </div>
        <div className="pad" style={{paddingTop:6}}>
          <Btn color="grape" size="lg" onClick={afterReveal}>Lock in guess →</Btn>
        </div>
      </div>
    );
  }

  /* ---- REVEAL ---- */
  if(phase==='reveal'){
    const pts=roundScore||wavelengthScore(target,guess);
    const isGuesserMode=mode==='guesser';
    return (
      <div className="app screen" style={{overflow:'hidden'}}>
        <Burst fire={pts>=3} colors={['#9A6CFF','#16C2A3','#FFC22E']}/>
        <TopBar title="Wavelength · reveal" color={game.color}/>
        <div className="center" style={{flex:1,padding:'16px 22px',gap:10}}>
          <div className={'stamp '+(pts>=3?'sh-teal':'sh-grape')} style={{fontSize:54}}>{pts} pt{pts===1?'':'s'}</div>
          <SpectrumBar left={spectrum.left} right={spectrum.right} showTarget={true} target={target} showGuess={true} guess={guess}/>
          <p className="muted" style={{fontSize:13}}>
            Target was at {target}. {isGuesserMode?`${guesser} guessed`:'You guessed'} {guess}.
            {isGuesserMode
              ? (pts>=3?' · +1 to each insider for a strong read!':'')
              : (pts===4?` · +1 bonus for ${psychic}!`:'')}
          </p>
          <div style={{width:'100%',maxWidth:360}}>
            <ScoreBoard scores={localScores} players={players} accent="var(--grape)"/>
          </div>
        </div>
        <div className="pad" style={{paddingTop:6}}>
          <Btn color="grape" size="lg" onClick={next}>
            {turn+1>=order.length?'See final results →'
              : isGuesserMode?`Next guesser: ${order[turn+1]} →`
              :`Next psychic: ${order[turn+1]} →`}
          </Btn>
        </div>
      </div>
    );
  }

  /* ---- DONE ---- */
  return (
    <div className="app screen">
      <TopBar onBack={onExit} title="Wavelength" color={game.color}/>
      <div className="center" style={{flex:1,padding:'20px 24px',gap:14}}>
        <div className="stamp sh-grape" style={{fontSize:50}}>Mind meld complete!</div>
        <div style={{width:'100%',maxWidth:360}}>
          <ScoreBoard scores={localScores} players={players} accent="var(--grape)"/>
        </div>
        <div className="btn-row" style={{width:'100%',maxWidth:360,marginTop:6}}>
          <Btn variant="ghost" onClick={leave}>Home</Btn>
          <Btn color="grape" onClick={()=>setPhase('setup')}>Play again ↻</Btn>
        </div>
      </div>
    </div>
  );
}

window.GameWavelength = GameWavelength;
