/* quiz.jsx — QuizMode, QuizResults */

// Feature flag — AI tutor (Claude) is disabled in self-hosted builds.
// To enable as a Pro/paid feature, see docs/AI_TUTOR_PAID_FEATURE.md
const AI_TUTOR_ENABLED = false;
function shuffle(arr){return[...arr].sort(()=>Math.random()-0.5);}
function normCmd(s){return s.trim().toLowerCase().replace(/\s+/g,' ');}

function DomTag({d}){const dom=(window.DOMAINS||[]).find(x=>x.id===d);return <span className={`tag tag-d${d}`}>{dom?.short||`D${d}`}</span>;}
function DiffTag({diff,ccnp}){if(ccnp)return <span className="tag tag-ccnp">CCNP</span>;return <span className={`tag tag-diff-${diff}`}>{diff===1?'Easy':diff===2?'Med':'Hard'}</span>;}

function Exhibit({text}){
  return(
    <div className="term-win" style={{marginBottom:'16px'}}>
      <div className="term-bar"><div className="term-dots"><span className="term-dot r"/><span className="term-dot y"/><span className="term-dot g"/></div><span className="term-bar-title">IOS Terminal Output</span></div>
      <div className="term-body">{text}</div>
    </div>
  );
}

function OptBtn({opt,state,onClick}){
  const cls=['q-opt',...(state?state.split(' '):[])].filter(Boolean).join(' ');
  return(<button className={cls} onClick={onClick}><span className="ltr">{opt.id.toUpperCase()}</span><span>{opt.t}</span></button>);
}

function MCQ({q,selected,onSelect,submitted}){
  return(<div className="q-options">{q.opts.map(o=>{
    let s='';
    if(submitted){s='disabled';if(q.ans.includes(o.id))s='correct disabled';else if(selected.includes(o.id))s='wrong disabled';}
    else if(selected.includes(o.id))s='selected';
    return <OptBtn key={o.id} opt={o} state={s} onClick={()=>!submitted&&onSelect(o.id)}/>;
  })}</div>);
}

function MSQ({q,selected,onToggle,submitted}){
  return(<div className="q-options">
    <p className="q-multi-note">▲ Select all that apply</p>
    {q.opts.map(o=>{
      let s='';
      if(submitted){const isA=q.ans.includes(o.id),isSel=selected.includes(o.id);s='disabled';if(isA)s='correct disabled';else if(isSel&&!isA)s='wrong disabled';else if(!isSel&&isA)s='missed disabled';}
      else if(selected.includes(o.id))s='selected';
      return <OptBtn key={o.id} opt={o} state={s} onClick={()=>!submitted&&onToggle(o.id)}/>;
    })}
  </div>);
}

function FITBQ({q,vals,onChange,submitted,correctness}){
  return(<div className="fitb-wrap">
    {(q.blanks||[]).map((blank,i)=>{
      const prompt=i===0?q.fitbPrompt:(q.fitbPrompt2||q.fitbPrompt);
      let cls='fitb-input';if(submitted)cls+=correctness[i]?' ok':' err';
      return(<div key={i} className="fitb-line">
        <span className="fitb-prompt">{prompt}</span>
        <input className={cls} value={vals[i]||''} onChange={e=>onChange(i,e.target.value)}
          placeholder="type command…" disabled={submitted} spellCheck={false} autoComplete="off"/>
      </div>);
    })}
    {submitted&&<div style={{fontSize:'11px',color:'var(--fg-mute)',marginTop:'4px'}}>
      {(q.blanks||[]).map((b,i)=>!correctness[i]&&<div key={i}>Line {i+1}: <code style={{color:'var(--green)'}}>{b}</code></div>)}
    </div>}
  </div>);
}

function MatchQ({q,termSel,defSel,pairs,onTerm,onDef,defs,submitted}){
  return(<div>
    <div className="match-grid">
      <div className="match-col">
        <div className="match-col-label">Terms — click to select</div>
        {q.pairs.map((p,i)=>{const pa=pairs.find(x=>x.ti===i);let cls='match-item';if(termSel===i)cls+=' active';if(pa)cls+=' paired';return(
          <button key={i} className={cls} onClick={()=>!submitted&&!pa&&onTerm(i)} disabled={submitted||!!pa}>
            <span className="match-ltr">{String.fromCharCode(65+i)}.</span>{p.term}
          </button>);
        })}
      </div>
      <div className="match-col">
        <div className="match-col-label">Definitions — click to pair</div>
        {defs.map((def,i)=>{const pa=pairs.find(x=>x.di===i);let cls='match-item';if(defSel===i)cls+=' active';if(pa)cls+=' paired';return(
          <button key={i} className={cls} onClick={()=>!submitted&&!pa&&onDef(i)} disabled={submitted||!!pa}>{def}</button>);
        })}
      </div>
    </div>
    {pairs.length===q.pairs.length&&!submitted&&<p style={{fontSize:'12px',color:'var(--green)',marginTop:'6px'}}>✓ All matched — click Submit</p>}
    {submitted&&<div className="q-feedback" style={{marginTop:'10px'}}>
      <div className="fb-head ok">Match Results</div>
      {q.pairs.map((p,i)=>{const pa=pairs.find(x=>x.ti===i);const ok=pa&&defs[pa.di]===p.def;return(
        <div key={i} style={{display:'grid',gridTemplateColumns:'auto 1fr',gap:'8px',padding:'4px 0',fontSize:'12.5px',color:ok?'var(--green)':'var(--red)'}}>
          <span>{ok?'✓':'✗'}</span><span>{p.term} → {p.def}</span>
        </div>);
      })}
    </div>}
  </div>);
}

function Feedback({q,selected,correct}){
  return(<div className="q-feedback">
    <div className={`fb-head ${correct?'ok':'bad'}`}>{correct?'✓ Correct':'✗ Incorrect'}</div>
    <div className="fb-text">{q.exp}</div>
    {!correct&&q.wrong&&<div className="fb-wrong-list">
      {selected.filter(s=>!q.ans.includes(s)).map(s=>q.wrong[s]&&(
        <div key={s} className="fb-wrong-item"><span className="fb-ltr">{s.toUpperCase()}:</span><span>{q.wrong[s]}</span></div>
      ))}
    </div>}
  </div>);
}

function HintPanel({q,hintsShown,onHint,chatLog,chatIn,setChatIn,onAsk,loading}){
  const logRef=React.useRef(null);
  React.useEffect(()=>{if(logRef.current)logRef.current.scrollTop=logRef.current.scrollHeight;},[chatLog,loading]);
  const maxHints=q.hints?.length||0;
  return(
    <div className="hint-panel">
      <div className="hp-head"><span className="hp-title">{AI_TUTOR_ENABLED?'AI Tutor':'Hints'}</span>{AI_TUTOR_ENABLED&&<span className="hp-pill">Claude</span>}</div>
      {hintsShown>0&&<div className="hints-list">
        {q.hints.slice(0,hintsShown).map((h,i)=><div key={i} className="hint-item"><span className="hint-num">Hint {i+1}/{maxHints}</span>{h}</div>)}
      </div>}
      {hintsShown<maxHints&&<div style={{marginBottom:'8px'}}>
        <button className="btn btn-sm btn-ghost" onClick={onHint}>+ Reveal hint ({hintsShown}/{maxHints})</button>
      </div>}
      {AI_TUTOR_ENABLED && <div className="chat-area">
        <div className="chat-log" ref={logRef}>
          {chatLog.length===0&&<div style={{color:'var(--fg-mute)',fontSize:'11px',padding:'6px 0'}}>Ask me anything… I won't reveal the answer until you submit.</div>}
          {chatLog.map((m,i)=><div key={i} className={`chat-msg ${m.r}`}>{m.c}</div>)}
          {loading&&<div className="chat-msg bot thinking">thinking…</div>}
        </div>
        <div className="chat-row">
          <textarea className="chat-in" rows={2} value={chatIn} onChange={e=>setChatIn(e.target.value)}
            onKeyDown={e=>{if(e.key==='Enter'&&!e.shiftKey){e.preventDefault();if(chatIn.trim())onAsk();}}}
            placeholder="Ask Claude… (Enter to send)" disabled={loading}/>
          <button className="btn btn-sm btn-primary" onClick={onAsk} disabled={!chatIn.trim()||loading}>Ask</button>
        </div>
      </div>}
    </div>
  );
}

function QuizMode({session,onComplete,onAnswer,onExit}){
  const{questions}=session;const total=questions.length;
  const[idx,setIdx]=React.useState(0);
  const[selected,setSelected]=React.useState([]);
  const[fitbVals,setFitbVals]=React.useState([]);
  const[fitbCorrect,setFitbCorrect]=React.useState([]);
  const[shuffDefs,setShuffDefs]=React.useState([]);
  const[matchPairs,setMatchPairs]=React.useState([]);
  const[termSel,setTermSel]=React.useState(null);
  const[defSel,setDefSel]=React.useState(null);
  const[submitted,setSubmitted]=React.useState(false);
  const[answers,setAnswers]=React.useState({});
  const[hintsShown,setHintsShown]=React.useState({});
  const[chatLogs,setChatLogs]=React.useState({});
  const[chatIn,setChatIn]=React.useState('');
  const[loading,setLoading]=React.useState(false);
  const[timeLeft,setTimeLeft]=React.useState(session.timerEnabled?session.timerDuration*60:null);
  const[learnTopicId,setLearnTopicId]=React.useState(null);

  const q=questions[idx];
  const chatLog=chatLogs[q?.id]||[];
  const hShown=hintsShown[q?.id]||0;

  React.useEffect(()=>{
    if(!session.timerEnabled||timeLeft===null||timeLeft<=0)return;
    const t=setTimeout(()=>setTimeLeft(tl=>tl-1),1000);return()=>clearTimeout(t);
  },[timeLeft,session.timerEnabled]);

  React.useEffect(()=>{
    setSelected([]);setFitbVals([]);setFitbCorrect([]);setMatchPairs([]);
    setTermSel(null);setDefSel(null);setSubmitted(false);setChatIn('');
    if(q?.type==='match')setShuffDefs(shuffle(q.pairs.map(p=>p.def)));
  },[idx]);

  function toggle(id){setSelected(prev=>q.type==='ms'?(prev.includes(id)?prev.filter(x=>x!==id):[...prev,id]):[id]);}
  function handleMatchTerm(ti){if(defSel!==null){setMatchPairs(p=>[...p,{ti,di:defSel}]);setTermSel(null);setDefSel(null);}else setTermSel(ti);}
  function handleMatchDef(di){if(termSel!==null){setMatchPairs(p=>[...p,{ti:termSel,di}]);setTermSel(null);setDefSel(null);}else setDefSel(di);}

  function canSubmit(){
    if(submitted)return false;
    if(q.type==='mc'||q.type==='exhibit')return selected.length===1;
    if(q.type==='ms')return selected.length>=1;
    if(q.type==='fitb')return(q.blanks||[]).every((_,i)=>(fitbVals[i]||'').trim().length>0);
    if(q.type==='match')return matchPairs.length===q.pairs.length;
    return false;
  }

  function doSubmit(){
    let correct=false;let fc=[];
    if(q.type==='mc'||q.type==='exhibit')correct=selected.length===q.ans.length&&selected.every(s=>q.ans.includes(s));
    else if(q.type==='ms')correct=selected.length===q.ans.length&&selected.every(s=>q.ans.includes(s));
    else if(q.type==='fitb'){fc=(q.blanks||[]).map((b,i)=>normCmd(fitbVals[i]||'')===normCmd(b));correct=fc.every(Boolean);setFitbCorrect(fc);}
    else if(q.type==='match')correct=matchPairs.length===q.pairs.length&&matchPairs.every(({ti,di})=>shuffDefs[di]===q.pairs[ti].def);
    setSubmitted(true);
    setAnswers(prev=>({...prev,[q.id]:{correct,selected:[...selected]}}));
    if(onAnswer)onAnswer(q,correct);
  }

  function doNext(){if(idx<total-1)setIdx(i=>i+1);else onComplete(answers);}
  function handleSkip(){doNext();}

  async function doAsk(){
    if(!chatIn.trim()||loading)return;
    const msg=chatIn.trim();setChatIn('');
    const prev=chatLogs[q.id]||[];
    const newLog=[...prev,{r:'user',c:msg}];
    setChatLogs(p=>({...p,[q.id]:newLog}));
    setLoading(true);
    try{
      const sys=`You are a concise CCNA/CCNP exam tutor. Topic: ${q.topic}. Question: "${q.stem}".${!submitted?' Do NOT reveal the correct answer option. Give Socratic guidance — ask leading questions, don\'t state the answer directly.':' Student submitted. Explain fully.'} Max 3 sentences.`;
      const msgs=newLog.map(m=>({role:m.r==='bot'?'assistant':'user',content:m.c}));
      const reply=await window.claude.complete({system:sys,messages:msgs});
      setChatLogs(p=>({...p,[q.id]:[...newLog,{r:'bot',c:reply}]}));
    }catch(e){setChatLogs(p=>({...p,[q.id]:[...newLog,{r:'bot',c:'Claude unavailable — check your connection.'}]}));}
    setLoading(false);
  }

  const isCorrect=answers[q?.id]?.correct;
  const fmtTime=s=>`${Math.floor(s/60)}:${String(s%60).padStart(2,'0')}`;

  if(!q)return null;

  // ===== CLI QUESTION TYPE =====
  if(q.type==='cli'){
    return(
      <div>
        <div className="q-meta">
          <span>CLI {idx+1} / {total}</span>
          <span style={{color:'var(--fg-mute)'}}>{session.label}</span>
          <button className="btn btn-sm btn-ghost" onClick={onExit} style={{marginLeft:'auto'}}>✕ Exit</button>
        </div>
        <div className="q-prog"><div className="q-prog-fill" style={{width:`${(idx/total)*100}%`}}/></div>
        <div className="q-tags"><DomTag d={q.d}/><DiffTag diff={q.diff} ccnp={q.ccnp}/><span style={{fontSize:'11px',color:'var(--fg-mute)',marginLeft:'4px'}}>{q.topic}</span></div>
        <window.CLISimulator question={q}
          onComplete={(correct)=>{setAnswers(prev=>({...prev,[q.id]:{correct,selected:[]}}));setSubmitted(true);if(onAnswer)onAnswer(q,correct);}}
          submitted={submitted}
          onSkip={!submitted?handleSkip:null}
          onLearnTopic={q.conceptId ? ()=>setLearnTopicId(q.conceptId) : null}/>
        <div className="q-actions">
          {submitted&&<button className="btn btn-primary" onClick={doNext}>{idx<total-1?'Next →':'See Results'}</button>}
          {!submitted&&<div style={{fontSize:'11px',color:'var(--fg-mute)',marginLeft:'auto'}}>↑↓ history · ? help</div>}
        </div>
        {learnTopicId&&<window.ConceptDrawer topicId={learnTopicId} hintHeadings={q.hintHeadings} onClose={()=>setLearnTopicId(null)}/>}
      </div>
    );
  }

  return(
    <div>
      <div className="q-meta">
        <span>Q {idx+1} / {total}</span>
        <span style={{color:'var(--fg-mute)'}}>{session.label}</span>
        {session.timerEnabled&&timeLeft!==null&&<span className="timer-badge" style={{color:timeLeft<120?'var(--red)':'var(--cyan)'}}>{fmtTime(timeLeft)}</span>}
        <button className="btn btn-sm btn-ghost" onClick={onExit} style={{marginLeft:'auto'}}>✕ Exit</button>
      </div>
      <div className="q-prog"><div className="q-prog-fill" style={{width:`${(idx/total)*100}%`}}/></div>
      <div className="quiz-layout">
        <div>
          <div className="q-tags"><DomTag d={q.d}/><DiffTag diff={q.diff} ccnp={q.ccnp}/><span style={{fontSize:'11px',color:'var(--fg-mute)',marginLeft:'4px'}}>{q.topic}</span></div>
          <div className="q-stem">{q.stem}</div>
          {q.exhibit&&<Exhibit text={q.exhibit}/>}
          {(q.type==='mc'||q.type==='exhibit')&&<MCQ q={q} selected={selected} onSelect={toggle} submitted={submitted}/>}
          {q.type==='ms'&&<MSQ q={q} selected={selected} onToggle={toggle} submitted={submitted}/>}
          {q.type==='fitb'&&<FITBQ q={q} vals={fitbVals} onChange={(i,v)=>setFitbVals(p=>{const n=[...p];n[i]=v;return n;})} submitted={submitted} correctness={fitbCorrect}/>}
          {q.type==='match'&&<MatchQ q={q} termSel={termSel} defSel={defSel} pairs={matchPairs} onTerm={handleMatchTerm} onDef={handleMatchDef} defs={shuffDefs} submitted={submitted}/>}
          <div className="q-actions">
            {!submitted
              ?<button className="btn btn-primary" onClick={doSubmit} disabled={!canSubmit()}>Submit Answer</button>
              :<button className="btn btn-primary" onClick={doNext}>{idx<total-1?'Next Question →':'See Results'}</button>}
            {!submitted&&<button className="btn btn-ghost btn-sm" onClick={()=>setHintsShown(p=>({...p,[q.id]:Math.min((p[q.id]||0)+1,q.hints?.length||0)}))}>Hint</button>}
            {!submitted&&<button className="btn btn-ghost btn-sm" onClick={handleSkip} style={{marginLeft:'auto'}}>Skip →</button>}
          </div>
          {submitted&&<Feedback q={q} selected={selected} correct={isCorrect}/>}
        </div>
        <HintPanel q={q} hintsShown={hShown}
          onHint={()=>setHintsShown(p=>({...p,[q.id]:Math.min((p[q.id]||0)+1,q.hints?.length||0)}))}
          chatLog={chatLog} chatIn={chatIn} setChatIn={setChatIn} onAsk={doAsk} loading={loading}/>
      </div>
    </div>
  );
}

function QuizResults({session,finalAnswers,onHome,onRetry}){
  const{questions}=session;
  const correct=questions.filter(q=>finalAnswers[q.id]?.correct).length;
  const answered=questions.filter(q=>finalAnswers[q.id]).length;
  const skipped=questions.length-answered;
  const pct=answered>0?Math.round((correct/answered)*100):0;
  const pass=pct>=70;
  const ds={};window.DOMAINS.forEach(d=>ds[d.id]={c:0,t:0});
  questions.forEach(q=>{ds[q.d].t++;if(finalAnswers[q.id]?.correct)ds[q.d].c++;});
  return(
    <div>
      <div className="q-meta" style={{marginBottom:'16px'}}>
        <span style={{color:'var(--fg-hi)',fontWeight:600}}>Session Complete</span>
        <button className="btn btn-sm btn-ghost" onClick={onHome} style={{marginLeft:'auto'}}>← Home</button>
      </div>
      <div className="results-grid">
        <div className="score-card">
          <div style={{fontSize:'11px',color:'var(--fg-mute)',textTransform:'uppercase',letterSpacing:'0.1em'}}>Final Score</div>
          <div className={`score-pct ${pass?'pass':'fail'}`}>{pct}%</div>
          <div className="score-verdict">{correct}/{answered} correct{skipped>0?` · ${skipped} skipped`:''} · {pass?'✓ Pass':'Keep studying'}</div>
          <div className="score-bars">
            {window.DOMAINS.map(d=>{const s=ds[d.id];if(!s.t)return null;const p=Math.round((s.c/s.t)*100);return(
              <div key={d.id} className="sb-row">
                <span className="sb-label" title={d.name}>{d.short}</span>
                <div className="sb-bar"><div className="sb-fill" style={{width:`${p}%`,background:`var(--d${d.id})`}}/></div>
                <span className="sb-pct">{p}%</span>
              </div>);})}
          </div>
          <div style={{display:'flex',gap:'8px',marginTop:'16px',justifyContent:'center'}}>
            <button className="btn btn-primary btn-sm" onClick={onRetry}>Retry Session</button>
            <button className="btn btn-sm" onClick={onHome}>Home</button>
          </div>
        </div>
        <div>
          <div className="sec-label">Question Review</div>
          <div className="review-list">
            {questions.map((q,i)=>{const ans=finalAnswers[q.id];const pipCls=ans?.correct?'ok':ans?'bad':'skip';return(
              <div key={q.id} className="ri">
                <div className={`ri-pip ${pipCls}`}/>
                <span className="ri-text">Q{i+1}. {q.stem.slice(0,68)}{q.stem.length>68?'…':''}</span>
                <span className={`ri-dom tag tag-d${q.d}`}>{q.topic.split(' ')[0]}</span>
              </div>);})}
          </div>
        </div>
      </div>
    </div>
  );
}

Object.assign(window,{QuizMode,QuizResults});
