/* ============================================================
   AVALON — hidden-role quest game
   ============================================================ */
const { useState: useAv, useMemo: useMAv } = React;

function buildRoles(players, opts){
  const n=players.length;
  const dist=DATA.AVALON_DIST[n];
  const evil=[], good=[];
  // evil
  evil.push('Assassin');
  if(opts.Morgana) evil.push('Morgana');
  if(opts.Mordred) evil.push('Mordred');
  if(opts.Oberon)  evil.push('Oberon');
  while(evil.length<dist.evil) evil.push('Minion of Mordred');
  // good
  good.push('Merlin');
  if(opts.Percival) good.push('Percival');
  while(good.length<dist.good) good.push('Loyal Servant');
  const all=shuffle([...evil,...good]);
  const roles={}; shuffle(players).forEach((p,i)=>roles[p]=all[i]);
  return roles;
}

function GameAvalon({ game, players, onExit, onHome }){
  const leave=onHome||onExit;
  const n=players.length;
  const dist=DATA.AVALON_DIST[n];
  const sizes=DATA.AVALON_QUESTS[n];
  const twoFailQuest=DATA.AVALON_TWOFAIL[n]; // index needing 2 fails, or undefined

  const [opts,setOpts]=useAv({Percival:n>=6,Morgana:false,Mordred:false,Oberon:false});
  const [phase,setPhase]=useAv('setup'); // setup|deal|night|propose|vote|quest|result|assassin|end
  const [roles,setRoles]=useAv(null);
  const [quests,setQuests]=useAv([]);      // 'good'|'evil'
  const [qIdx,setQIdx]=useAv(0);
  const [leader,setLeader]=useAv(0);
  const [team,setTeam]=useAv([]);
  const [pVotes,setPVotes]=useAv({});
  const [rejects,setRejects]=useAv(0);
  const [lastResult,setLastResult]=useAv(null);
  const [outcome,setOutcome]=useAv(null);

  const evilSlots = dist.evil - 1; // minus Assassin
  const optEvilCount = (opts.Morgana?1:0)+(opts.Mordred?1:0)+(opts.Oberon?1:0);

  const rolesByPlayer = roles||{};
  const evilPlayers = useMAv(()=>roles?Object.keys(roles).filter(p=>DATA.AVALON_ROLES[roles[p]].team==='evil'):[],[roles]);
  const merlin = roles && Object.keys(roles).find(p=>roles[p]==='Merlin');
  const morgana = roles && Object.keys(roles).find(p=>roles[p]==='Morgana');
  const assassin = roles && Object.keys(roles).find(p=>roles[p]==='Assassin');

  const deal=()=>{ setRoles(buildRoles(players,opts)); setQuests([]); setQIdx(0); setLeader(0); setRejects(0); setPhase('deal'); };

  /* knowledge each player sees */
  const knowledge=(p)=>{
    const role=roles[p]; const meta=DATA.AVALON_ROLES[role];
    if(role==='Merlin'){
      const seen=evilPlayers.filter(e=>roles[e]!=='Mordred');
      return {list:seen, label:'Evil players you can see', tone:'evil'};
    }
    if(role==='Percival'){
      const seen=[merlin, morgana].filter(Boolean);
      return {list:shuffle(seen), label: morgana?'One of these is Merlin (the other is Morgana)':'Merlin is', tone:'good'};
    }
    if(meta.team==='evil' && role!=='Oberon'){
      const allies=evilPlayers.filter(e=>e!==p && roles[e]!=='Oberon');
      return {list:allies, label:'Your fellow agents of evil', tone:'evil'};
    }
    return null;
  };

  /* ---------- SETUP ---------- */
  if(phase==='setup'){
    const optRow=(key,label,team,desc,disabled)=>(
      <div className="toggle-row" style={{padding:'11px 14px',opacity:disabled?.5:1}}>
        <span className="token" style={{background:team==='good'?'var(--sky)':'var(--coral)',width:12,height:12}}/>
        <div className="lbl"><b>{label}</b><small>{desc}</small></div>
        <Switch on={opts[key]} onChange={v=>!disabled&&setOpts({...opts,[key]:v})}/>
      </div>
    );
    return (
      <div className="app screen">
        <TopBar onBack={onExit} title="Avalon" color={game.color}/>
        <div className="setup">
          <h2>Avalon</h2>
          <p className="lead">Good vs. Evil. Three winning quests for Good — but the Assassin lurks. {n} players: <b style={{color:'var(--sky)'}}>{dist.good} good</b> · <b style={{color:'var(--coral)'}}>{dist.evil} evil</b>.</p>
          <div className="field"><label>Optional roles</label>
            <div className="col" style={{gap:9}}>
              {optRow('Percival','Percival','good','Knows who Merlin is')}
              {optRow('Morgana','Morgana','evil','Appears as Merlin to Percival', !opts.Morgana && optEvilCount>=evilSlots)}
              {optRow('Mordred','Mordred','evil','Hidden from Merlin', !opts.Mordred && optEvilCount>=evilSlots)}
              {optRow('Oberon','Oberon','evil','Unknown to other evil', !opts.Oberon && optEvilCount>=evilSlots)}
            </div>
            <p className="muted" style={{fontSize:12,marginTop:9}}>{evilSlots} optional evil slot{evilSlots===1?'':'s'} available{opts.Morgana&&!opts.Percival?' · tip: Morgana works best with Percival':''}</p>
          </div>
          <Btn color="grape" size="lg" onClick={deal}>Reveal roles →</Btn>
        </div>
      </div>
    );
  }

  /* ---------- DEAL (private reveal) ---------- */
  if(phase==='deal'){
    return (
      <div className="app screen">
        <TopBar title="Avalon · secret roles" color={game.color}/>
        <PrivateReveal players={players} accent={game.color} doneLabel="On to the night"
          onDone={()=>setPhase('night')}
          getContent={(p)=>{
            const role=roles[p]; const meta=DATA.AVALON_ROLES[role]; const isEvil=meta.team==='evil';
            const k=knowledge(p);
            return (
              <div className="center" style={{gap:14}}>
                <div className="role-card-big" style={{background:isEvil?'var(--coral)':'var(--sky)',color:'#fff'}}>
                  <div className="kicker" style={{color:'rgba(255,255,255,.8)'}}>{isEvil?'agent of evil':'loyal to arthur'}</div>
                  <div className="display" style={{fontSize:34,margin:'8px 0 4px',color:'#fff'}}>{role}</div>
                  <p style={{color:'rgba(255,255,255,.92)',fontSize:14,lineHeight:1.35}}>{meta.desc}</p>
                  {k && (
                    <div style={{marginTop:14,borderTop:'1.5px solid rgba(255,255,255,.3)',paddingTop:12}}>
                      <div className="mono" style={{fontSize:10.5,color:'rgba(255,255,255,.8)',letterSpacing:1,textTransform:'uppercase'}}>{k.label}</div>
                      <div className="wrap" style={{gap:7,justifyContent:'center',marginTop:9}}>
                        {k.list.length?k.list.map(x=><div key={x} className="chip" style={{fontSize:14}}><Avatar name={x} size={20}/>{x}</div>):<span style={{fontStyle:'italic'}}>nobody</span>}
                      </div>
                    </div>
                  )}
                </div>
              </div>
            );
          }}/>
      </div>
    );
  }

  /* ---------- NIGHT NARRATION ---------- */
  if(phase==='night'){
    return <NightPhase opts={opts} game={game} onDone={()=>setPhase('propose')}/>;
  }

  const leaderName=players[leader % n];
  const teamSize=sizes[qIdx];
  const failsNeeded = twoFailQuest===qIdx?2:1;

  /* ---------- PROPOSE ---------- */
  if(phase==='propose'){
    const toggle=(p)=>setTeam(t=>t.includes(p)?t.filter(x=>x!==p):t.length<teamSize?[...t,p]:t);
    return (
      <div className="app screen">
        <TopBar onBack={onExit} title="Avalon · propose a team" color={game.color} right={<QuestDots quests={quests} cur={qIdx}/>}/>
        <div className="setup" style={{paddingTop:14}}>
          <div className="row" style={{gap:10,marginBottom:6}}>
            <span className="tier-pill" style={{background:'var(--grape)',color:'#fff'}}>Quest {qIdx+1}</span>
            <span className="tier-pill" style={{background:'rgba(255,255,255,.08)',color:'#C9BCEC'}}>{teamSize} go {failsNeeded===2?'· needs 2 fails':''}</span>
            {rejects>0 && <span className="tier-pill" style={{background:'var(--coral)',color:'#fff'}}>reject {rejects}/5</span>}
          </div>
          <h2 style={{fontSize:24}}><span style={{color:'var(--gold)'}}>{leaderName}</span> leads</h2>
          <p className="lead">Pick {teamSize} player{teamSize>1?'s':''} for this quest, then everyone votes.</p>
          <div className="wrap" style={{gap:9}}>
            {players.map(p=>(
              <button key={p} className={'chip selectable'+(team.includes(p)?' sel':'')} onClick={()=>toggle(p)} style={{fontSize:15}}>
                <Avatar name={p} size={21}/>{p}{team.includes(p)?' ✓':''}
              </button>
            ))}
          </div>
          <div style={{marginTop:22}}><Btn color="grape" size="lg" disabled={team.length!==teamSize} onClick={()=>{setPVotes({});setPhase('vote');}}>{team.length}/{teamSize} chosen → Vote</Btn></div>
        </div>
      </div>
    );
  }

  /* ---------- PROPOSAL VOTE ---------- */
  if(phase==='vote'){
    const allIn=players.every(p=>pVotes[p]);
    const tally=()=>{
      const approve=players.filter(p=>pVotes[p]==='a').length;
      if(approve*2>n){ setRejects(0); setPhase('quest'); }
      else {
        const r=rejects+1;
        if(r>=5){ setOutcome({winner:'evil',reason:'5 proposals rejected in a row — Evil seizes power.'}); setPhase('end'); }
        else { setRejects(r); setLeader(leader+1); setTeam([]); setPhase('propose'); }
      }
    };
    return (
      <div className="app screen">
        <TopBar title="Avalon · approve this team?" color={game.color}/>
        <div className="setup" style={{paddingTop:14}}>
          <h2 style={{fontSize:23}}>{leaderName}'s team</h2>
          <div className="wrap" style={{gap:7,marginBottom:6}}>{team.map(p=><span key={p} className="chip" style={{fontSize:14}}><Avatar name={p} size={19}/>{p}</span>)}</div>
          <p className="lead">Everyone votes — thumbs up to approve, down to reject. Majority rules.</p>
          <div className="col" style={{gap:9}}>
            {players.map(p=>(
              <div key={p} className="row" style={{gap:12,background:'rgba(255,255,255,.05)',border:'1.5px solid rgba(255,255,255,.1)',borderRadius:14,padding:'9px 12px'}}>
                <Avatar name={p}/><b style={{flex:1,fontSize:16}}>{p}</b>
                <div style={{display:'flex',gap:7}}>
                  <button onClick={()=>setPVotes({...pVotes,[p]:'a'})} style={voteBtn(pVotes[p]==='a','var(--teal)')}>👍</button>
                  <button onClick={()=>setPVotes({...pVotes,[p]:'r'})} style={voteBtn(pVotes[p]==='r','var(--coral)')}>👎</button>
                </div>
              </div>
            ))}
          </div>
          <div style={{marginTop:20}}><Btn color="grape" size="lg" disabled={!allIn} onClick={tally}>{allIn?'Tally the votes →':'Everyone vote'}</Btn></div>
        </div>
      </div>
    );
  }

  /* ---------- QUEST (private success/fail) ---------- */
  if(phase==='quest'){
    return (
      <div className="app screen">
        <TopBar title="Avalon · the quest" color={game.color}/>
        <QuestSubmit team={team} roles={roles} accent={game.color}
          onDone={(fails)=>{
            const result = fails>=failsNeeded ? 'evil':'good';
            const nq=[...quests,result]; setQuests(nq); setLastResult({result,fails,team:[...team]});
            const g=nq.filter(x=>x==='good').length, e=nq.filter(x=>x==='evil').length;
            setLeader(leader+1); setTeam([]);
            if(e>=3){ setOutcome({winner:'evil',reason:'Evil sabotaged three quests.'}); setPhase('end'); }
            else { setPhase('result'); }
          }}/>
      </div>
    );
  }

  /* ---------- QUEST RESULT ---------- */
  if(phase==='result'){
    const success=lastResult.result==='good';
    const goodWins=quests.filter(x=>x==='good').length;
    return (
      <div className="app screen" style={{overflow:'hidden'}}>
        <TopBar title="Avalon" color={game.color} right={<QuestDots quests={quests} cur={qIdx+1}/>}/>
        <div className="center" style={{flex:1,padding:'18px 24px',gap:10}}>
          <div className={'stamp '+(success?'sh-teal':'sh-coral')} style={{fontSize:54}}>{success?'Quest passed':'Sabotaged!'}</div>
          <p className="serif-i" style={{fontSize:21,color:'#FFD79A'}}>{lastResult.fails} fail card{lastResult.fails===1?'':'s'} played</p>
          <div style={{marginTop:8}}><QuestDots quests={quests} cur={quests.length} big/></div>
          <p className="muted mt16">Good {goodWins}/3 · Evil {quests.length-goodWins}/3</p>
          <div style={{width:'100%',maxWidth:320,marginTop:14}}>
            {goodWins>=3
              ? <Btn color="gold" size="lg" onClick={()=>setPhase('assassin')}>Good has 3! The Assassin strikes →</Btn>
              : <Btn color="grape" size="lg" onClick={()=>{setQIdx(qIdx+1);setPhase('propose');}}>Next quest →</Btn>}
          </div>
        </div>
      </div>
    );
  }

  /* ---------- ASSASSIN ---------- */
  if(phase==='assassin'){
    return (
      <div className="app screen">
        <TopBar title="Avalon · assassination" color={game.color}/>
        <div className="setup" style={{paddingTop:16}}>
          <div className="center" style={{gap:6,marginBottom:14}}>
            <div className="stamp sh-coral" style={{fontSize:42}}>One shot.</div>
            <p className="serif-i" style={{fontSize:20,color:'#FFD79A'}}>Assassin ({assassin}), name Merlin</p>
            <p className="muted" style={{maxWidth:300,fontSize:14}}>If you kill Merlin, Evil steals victory. Choose wrong and Good prevails.</p>
          </div>
          <div className="wrap" style={{gap:9,justifyContent:'center'}}>
            {players.filter(p=>DATA.AVALON_ROLES[roles[p]].team==='good').map(p=>(
              <button key={p} className="chip selectable" style={{fontSize:15}}
                onClick={()=>{ const hit=p===merlin; setOutcome({winner:hit?'evil':'good',reason:hit?`The Assassin found Merlin (${merlin}). Evil wins!`:`The Assassin missed — ${p} wasn't Merlin. Good wins!`,target:p}); setPhase('end'); }}>
                <Avatar name={p} size={21}/>{p}
              </button>
            ))}
          </div>
        </div>
      </div>
    );
  }

  /* ---------- END / FULL REVEAL ---------- */
  const goodWon=outcome.winner==='good';
  return (
    <div className="app screen" style={{overflow:'hidden'}}>
      <Burst fire={true} colors={goodWon?['#3D8BFF','#16C2A3','#FFF6E6']:['#FF5A3C','#FF5C9D','#1A1330']}/>
      <TopBar onBack={onExit} title="Avalon · the truth" color={game.color}/>
      <div className="setup" style={{paddingTop:10}}>
        <div className="center" style={{gap:6}}>
          <div className={'stamp '+(goodWon?'sh-sky':'sh-coral')} style={{fontSize:58}}>{goodWon?'Good wins':'Evil wins'}</div>
          <p className="serif-i" style={{fontSize:19,color:'#FFD79A',maxWidth:330,marginTop:6}}>{outcome.reason}</p>
        </div>
        <div className="mt24"><QuestDots quests={quests} cur={-1} big/></div>
        <div className="panel-title" style={{margin:'22px 0 11px'}}>Everyone's true role</div>
        <div className="col" style={{gap:8}}>
          {players.map(p=>{
            const meta=DATA.AVALON_ROLES[roles[p]]; const isEvil=meta.team==='evil';
            return (
              <div key={p} className="row" style={{gap:11,background:'rgba(255,255,255,.05)',border:'1.5px solid rgba(255,255,255,.1)',borderRadius:13,padding:'10px 13px'}}>
                <Avatar name={p}/><b style={{flex:1,fontSize:16}}>{p}</b>
                {p===merlin && <span style={{fontSize:14}}>🧙</span>}
                {p===outcome.target && <span style={{fontSize:13}}>🎯</span>}
                <span className="tier-pill" style={{background:isEvil?'var(--coral)':'var(--sky)',color:'#fff'}}>{roles[p]}</span>
              </div>
            );
          })}
        </div>
        <div className="btn-row" style={{marginTop:22}}>
          <Btn variant="ghost" onClick={leave}>Home</Btn>
          <Btn color="grape" onClick={()=>setPhase('setup')}>Play again ↻</Btn>
        </div>
      </div>
    </div>
  );
}

/* ----- night narration ----- */
function NightPhase({ opts, game, onDone }){
  const steps=useMAv(()=>{
    const s=[{t:'Close your eyes',d:'Everyone, close your eyes and make a fist on the table. The night begins…',e:'🌙'}];
    s.push({t:'Evil, awaken',d:'Minions of Mordred'+(opts.Oberon?' — except Oberon':'')+', open your eyes. Look around and recognise your fellow agents of evil.',e:'😈'});
    s.push({t:'Evil, sleep',d:'Minions of Mordred, close your eyes and lower your heads.',e:'🌙'});
    s.push({t:'Merlin sees evil',d:'Minions of Mordred'+(opts.Mordred?' — except Mordred':'')+', stick out your thumb so Merlin knows your treachery. Merlin, open your eyes.',e:'🧙'});
    s.push({t:'Merlin, sleep',d:'Thumbs down. Merlin, close your eyes.',e:'🌙'});
    if(opts.Percival){
      s.push({t:'Percival sees',d:'Merlin'+(opts.Morgana?' and Morgana':'')+', stick out your thumb. Percival, open your eyes to behold '+(opts.Morgana?'the two of them — but which is the true Merlin?':'Merlin.'),e:'🛡️'});
      s.push({t:'Percival, sleep',d:'Thumbs down. Percival, close your eyes.',e:'🌙'});
    }
    s.push({t:'Dawn',d:'Everyone, open your eyes. The quest for Camelot begins!',e:'☀️'});
    return s;
  },[opts]);
  const [i,setI]=useAv(0);
  const step=steps[i];
  return (
    <div className="app screen">
      <TopBar title="Avalon · the night" color={game.color} right={<span className="mono" style={{fontSize:11,color:'#9082BE'}}>{i+1}/{steps.length}</span>}/>
      <div className="center" style={{flex:1,padding:'20px 26px',gap:8}}>
        <div style={{fontSize:60}}>{step.e}</div>
        <div className="display" style={{fontSize:34,letterSpacing:-1}}>{step.t}</div>
        <div className="night mt16" style={{maxWidth:360}}><p style={{fontSize:17,lineHeight:1.45,color:'#E7DEFA'}}>{step.d}</p></div>
        <p className="tap-hint mt24">read it aloud, then tap</p>
      </div>
      <div className="pad" style={{paddingTop:6}}>
        <Btn color="grape" size="lg" onClick={()=>i+1>=steps.length?onDone():setI(i+1)}>{i+1>=steps.length?'Begin the quests →':'Next →'}</Btn>
      </div>
    </div>
  );
}

/* ----- quest success/fail private submit ----- */
function QuestSubmit({ team, roles, accent, onDone }){
  const [idx,setIdx]=useAv(0);
  const [shown,setShown]=useAv(false);
  const [fails,setFails]=useAv(0);
  const name=team[idx];

  if(idx>=team.length){
    return <div className="center" style={{flex:1,gap:14,padding:30}}>
      <p className="muted">All quest cards are in.</p>
      <Btn color="grape" size="lg" onClick={()=>onDone(fails)} style={{maxWidth:300}}>Reveal the result →</Btn>
    </div>;
  }
  if(!shown){
    return (
      <div className="reveal-screen screen" key={'p'+idx}>
        <div className="kicker">quest card · pass to</div>
        <div className="display wiggle mt16" style={{fontSize:48}}>{name}</div>
        <p className="muted mt16">Others, look away 👀</p>
        <div style={{width:'100%',maxWidth:340,marginTop:26}}><Btn color="grape" size="lg" onClick={()=>setShown(true)}>Tap to play your card</Btn></div>
        <div className="mono mt24" style={{fontSize:12,color:'#7E70AE'}}>{idx+1}/{team.length} on the quest</div>
      </div>
    );
  }
  const isEvil=DATA.AVALON_ROLES[roles[name]].team==='evil';
  const next=(didFail)=>{ if(didFail) setFails(f=>f+1); setShown(false); setIdx(idx+1); };
  return (
    <div className="reveal-screen screen" key={'s'+idx}>
      <div className="kicker">{name}, play your quest card</div>
      <div className="bigchoice" style={{width:'100%',maxWidth:340,marginTop:20}}>
        <button className="choice-btn" style={{background:'var(--teal)',color:'#06281f'}} onClick={()=>next(false)}>✓ Success</button>
        {isEvil
          ? <button className="choice-btn" style={{background:'var(--coral)',color:'#fff'}} onClick={()=>next(true)}>✗ Fail (sabotage)</button>
          : <div className="mono" style={{fontSize:12,color:'#8A7CB8',textAlign:'center',padding:'4px'}}>Loyal servants must play Success.</div>}
      </div>
    </div>
  );
}

function QuestDots({ quests, cur, big }){
  const sz=big?46:0;
  if(big){
    return <div className="questline">{[0,1,2,3,4].map(i=>{
      const r=quests[i];
      return <div key={i} className={'questnode'+(r==='good'?' good':r==='evil'?' evil':'')+(i===cur?' cur':'')}>{i+1}</div>;
    })}</div>;
  }
  return <div className="pips">{[0,1,2,3,4].map(i=>{
    const r=quests[i];
    return <span key={i} className={'pip'+(r==='good'?' done':r==='evil'?' fail':'')+(i===cur?' cur':'')}/>;
  })}</div>;
}

window.GameAvalon = GameAvalon;
