// ds-questions.jsx — Assessment question library.
// Self-contained renderer + reviewer for the seven supported question types:
// mcq · multi · tf · numeric · short · fill · match.
// Carved out of screens-assessments.jsx so non-assessment screens (homework, practice)
// can reuse the same input/review surface without copy-pasting.
//
// Loaded after icons.jsx and before screens-assessments.jsx — depends on global Icon, React.

// ─────────────────────────────────────────────────────────────
// QUESTION INPUT — type-aware renderer
// ─────────────────────────────────────────────────────────────
function QuestionInput({ q, value, onChange }) {
  switch (q.type) {
    case 'mcq':     return <MCQInput q={q} value={value} onChange={onChange}/>;
    case 'multi':   return <MultiInput q={q} value={value} onChange={onChange}/>;
    case 'tf':      return <TFInput q={q} value={value} onChange={onChange}/>;
    case 'numeric': return <NumericInput q={q} value={value} onChange={onChange}/>;
    case 'short':   return <ShortInput q={q} value={value} onChange={onChange}/>;
    case 'fill':    return <FillInput q={q} value={value} onChange={onChange}/>;
    case 'match':   return <MatchInput q={q} value={value} onChange={onChange}/>;
    default: return <div className="card" style={{ padding: 14 }}>Unsupported type: {q.type}</div>;
  }
}

function MCQInput({ q, value, onChange }) {
  return (
    <div className="col" style={{ gap: 10 }}>
      {q.opts.map((opt, i) => {
        const sel = value === i;
        return (
          <button key={i} onClick={() => onChange(i)} className="row" style={{
            padding: 14, gap: 12, textAlign: 'left',
            background: sel ? 'var(--p50)' : '#fff',
            border: sel ? '2px solid var(--p600)' : '1px solid var(--n100)',
            borderRadius: 12,
          }}>
            <div style={{ width: 26, height: 26, borderRadius: 99, background: sel ? 'var(--p600)' : 'var(--n50)', color: sel ? '#fff' : 'var(--n700)', display: 'grid', placeItems: 'center', fontSize: 12, fontWeight: 800, flexShrink: 0 }}>{String.fromCharCode(65 + i)}</div>
            <div style={{ flex: 1, fontSize: 14, fontWeight: sel ? 700 : 600, color: sel ? 'var(--p700)' : 'var(--n900)' }}>{opt}</div>
            {sel && <Icon name="check" size={16} style={{ color: 'var(--p600)' }}/>}
          </button>
        );
      })}
    </div>
  );
}

function MultiInput({ q, value, onChange }) {
  const v = Array.isArray(value) ? value : [];
  const toggle = (i) => onChange(v.includes(i) ? v.filter(x => x !== i) : [...v, i].sort((x, y) => x - y));
  return (
    <div className="col" style={{ gap: 10 }}>
      {q.opts.map((opt, i) => {
        const sel = v.includes(i);
        return (
          <button key={i} onClick={() => toggle(i)} className="row" style={{
            padding: 14, gap: 12, textAlign: 'left',
            background: sel ? 'var(--p50)' : '#fff',
            border: sel ? '2px solid var(--p600)' : '1px solid var(--n100)',
            borderRadius: 12,
          }}>
            <div style={{ width: 26, height: 26, borderRadius: 7, background: sel ? 'var(--p600)' : '#fff', color: '#fff', border: sel ? '0' : '2px solid var(--n300)', display: 'grid', placeItems: 'center', flexShrink: 0 }}>
              {sel && <Icon name="check" size={14}/>}
            </div>
            <div style={{ flex: 1, fontSize: 14, fontWeight: sel ? 700 : 600, color: sel ? 'var(--p700)' : 'var(--n900)' }}>{opt}</div>
          </button>
        );
      })}
    </div>
  );
}

function TFInput({ q, value, onChange }) {
  return (
    <div className="row" style={{ gap: 12 }}>
      {[
        { v: true, lab: 'True', icon: 'check', clr: 'var(--success)', bg: 'var(--success-50)', bd: '#A7F3D0' },
        { v: false, lab: 'False', icon: 'x', clr: 'var(--c600)', bg: 'var(--c50)', bd: '#FCA5A5' },
      ].map(opt => {
        const sel = value === opt.v;
        return (
          <button key={opt.lab} onClick={() => onChange(opt.v)} className="col" style={{
            flex: 1, padding: '22px 10px', alignItems: 'center', gap: 10,
            background: sel ? opt.bg : '#fff',
            border: sel ? `2px solid ${opt.clr}` : '1px solid var(--n100)',
            borderRadius: 14,
          }}>
            <div style={{ width: 56, height: 56, borderRadius: 99, background: sel ? opt.clr : 'var(--n50)', color: sel ? '#fff' : 'var(--n400)', display: 'grid', placeItems: 'center' }}>
              <Icon name={opt.icon} size={28}/>
            </div>
            <div style={{ fontSize: 16, fontWeight: 800, color: sel ? opt.clr : 'var(--n900)', letterSpacing: '-.01em' }}>{opt.lab}</div>
          </button>
        );
      })}
    </div>
  );
}

function NumericInput({ q, value, onChange }) {
  return (
    <div className="card" style={{ padding: 18 }}>
      <div style={{ fontSize: 9.5, fontWeight: 800, color: 'var(--n500)', letterSpacing: '.1em', fontFamily: 'var(--mono)', marginBottom: 10 }}>YOUR ANSWER</div>
      <div className="row" style={{ gap: 10, alignItems: 'baseline' }}>
        <input
          type="number"
          inputMode="decimal"
          value={value || ''}
          onChange={e => onChange(e.target.value)}
          placeholder="Enter a number"
          style={{
            flex: 1, height: 60, padding: '0 16px', borderRadius: 12,
            border: '2px solid var(--n200)', background: 'var(--n50)',
            fontSize: 28, fontWeight: 800, fontVariantNumeric: 'tabular-nums', letterSpacing: '-.02em',
            color: 'var(--n900)', fontFamily: 'var(--mono)', textAlign: 'center', outline: 'none',
          }}
          onFocus={e => e.target.style.borderColor = 'var(--p600)'}
          onBlur={e => e.target.style.borderColor = 'var(--n200)'}
        />
        {q.unit && <div style={{ fontSize: 14, color: 'var(--n600)', fontWeight: 700 }}>{q.unit}</div>}
      </div>
      {q.tolerance > 0 && (
        <div style={{ fontSize: 10.5, color: 'var(--n500)', marginTop: 8, fontStyle: 'italic' }}>
          Accepts answers within ±{q.tolerance} of the expected value.
        </div>
      )}
    </div>
  );
}

function ShortInput({ q, value, onChange }) {
  return (
    <div className="card" style={{ padding: 18 }}>
      <div style={{ fontSize: 9.5, fontWeight: 800, color: 'var(--n500)', letterSpacing: '.1em', fontFamily: 'var(--mono)', marginBottom: 10 }}>YOUR ANSWER</div>
      <textarea
        value={value || ''}
        onChange={e => onChange(e.target.value)}
        placeholder={q.teacherGraded ? 'Write your response — teacher will grade…' : 'Type your answer…'}
        rows={q.teacherGraded ? 4 : 2}
        style={{
          width: '100%', padding: 14, borderRadius: 12,
          border: '2px solid var(--n200)', background: 'var(--n50)',
          fontSize: 15, fontWeight: 600, color: 'var(--n900)',
          fontFamily: 'inherit', resize: 'none', outline: 'none', boxSizing: 'border-box',
        }}
        onFocus={e => e.target.style.borderColor = 'var(--p600)'}
        onBlur={e => e.target.style.borderColor = 'var(--n200)'}
      />
      {q.teacherGraded && (
        <div className="row" style={{ gap: 6, marginTop: 8, color: 'var(--warning)' }}>
          <Icon name="info" size={12}/>
          <div style={{ fontSize: 10.5, fontWeight: 600 }}>Open-ended — graded by your teacher</div>
        </div>
      )}
    </div>
  );
}

function FillInput({ q, value, onChange }) {
  const v = Array.isArray(value) ? value : Array(q.blanks).fill('');
  const setBlank = (i, txt) => onChange(v.map((s, ix) => ix === i ? txt : s));
  // Split q.q on '___' → text segments interleaved with blanks
  const segments = q.q.split('___');
  let blankIdx = 0;
  return (
    <div className="card" style={{ padding: 18 }}>
      <div style={{ fontSize: 9.5, fontWeight: 800, color: 'var(--n500)', letterSpacing: '.1em', fontFamily: 'var(--mono)', marginBottom: 12 }}>FILL IN THE BLANKS</div>
      <div style={{ fontSize: 16, lineHeight: 2.2, color: 'var(--n900)', fontWeight: 600, letterSpacing: '-.005em' }}>
        {segments.map((seg, i) => (
          <React.Fragment key={i}>
            <span>{seg}</span>
            {i < segments.length - 1 && (() => {
              const bi = blankIdx++;
              const filled = v[bi] && v[bi].trim().length > 0;
              return (
                <input
                  type="text"
                  value={v[bi] || ''}
                  onChange={e => setBlank(bi, e.target.value)}
                  placeholder={`Blank ${bi + 1}`}
                  style={{
                    display: 'inline-block', minWidth: 110, maxWidth: 200, padding: '4px 10px', margin: '0 4px',
                    borderRadius: 8, border: 0, borderBottom: `2px solid ${filled ? 'var(--p600)' : 'var(--n300)'}`,
                    background: filled ? 'var(--p50)' : 'var(--n50)',
                    fontSize: 15, fontWeight: 700, color: filled ? 'var(--p700)' : 'var(--n900)',
                    fontFamily: 'inherit', textAlign: 'center', outline: 'none',
                  }}
                />
              );
            })()}
          </React.Fragment>
        ))}
      </div>
    </div>
  );
}

function MatchInput({ q, value, onChange }) {
  // value is an array of right-side indices, indexed by left-side position.
  // Tap a left row to cycle through the available right options.
  const v = Array.isArray(value) && value.length === q.pairs.length ? value : q.pairs.map(() => null);
  const cycleAt = (leftIdx) => {
    const cur = v[leftIdx];
    const next = cur === null ? 0 : cur === q.pairs.length - 1 ? null : cur + 1;
    onChange(v.map((x, i) => i === leftIdx ? next : x));
  };
  return (
    <div className="card" style={{ padding: 14 }}>
      <div style={{ fontSize: 9.5, fontWeight: 800, color: 'var(--n500)', letterSpacing: '.1em', fontFamily: 'var(--mono)', marginBottom: 10 }}>TAP THE RIGHT-SIDE PILL TO CYCLE PAIRS</div>
      <div className="col" style={{ gap: 8 }}>
        {q.pairs.map((p, i) => {
          const picked = v[i];
          const right = picked === null ? null : q.pairs[picked].right;
          return (
            <div key={i} className="row" style={{ gap: 10, padding: 10, background: 'var(--n50)', borderRadius: 11 }}>
              <div style={{ width: 28, height: 28, borderRadius: 8, background: '#fff', color: 'var(--n700)', display: 'grid', placeItems: 'center', fontSize: 12, fontWeight: 800, fontFamily: 'var(--mono)', flexShrink: 0 }}>{i + 1}</div>
              <div style={{ flex: 1, fontSize: 13.5, fontWeight: 700, color: 'var(--n900)' }}>{p.left}</div>
              <Icon name="chev-r" size={14} style={{ color: 'var(--n400)' }}/>
              <button onClick={() => cycleAt(i)} className="row" style={{
                gap: 6, padding: '8px 12px', borderRadius: 9,
                background: picked === null ? '#fff' : 'var(--p600)',
                color: picked === null ? 'var(--n500)' : '#fff',
                border: picked === null ? '1.5px dashed var(--n300)' : '0',
                fontSize: 12, fontWeight: 700, minWidth: 130, justifyContent: 'space-between',
              }}>
                <span style={{ flex: 1, textAlign: 'left' }}>{right || 'Pick a match'}</span>
                <Icon name="chev-d" size={12}/>
              </button>
            </div>
          );
        })}
      </div>
      <div style={{ fontSize: 10.5, color: 'var(--n500)', marginTop: 10, fontStyle: 'italic', lineHeight: 1.5 }}>
        All rights: {q.pairs.map(p => p.right).join(' · ')}
      </div>
    </div>
  );
}

// ─────────────────────────────────────────────────────────────
// REVIEW ANSWER — type-aware comparison ("you said vs correct")
// ─────────────────────────────────────────────────────────────
function ReviewAnswer({ q, userAns, isCorrect, wasSkipped }) {
  if (q.type === 'mcq') {
    return (
      <div className="col" style={{ gap: 6 }}>
        {q.opts.map((opt, oi) => {
          const isUser = oi === userAns;
          const isAns = oi === q.correct;
          let bg = 'var(--n50)', bd = '1px solid var(--n100)', col = 'var(--n700)', icon = null;
          if (isAns) { bg = 'var(--success-50)'; bd = '1px solid #A7F3D0'; col = 'var(--success)'; icon = 'check'; }
          if (isUser && !isAns) { bg = 'var(--c50)'; bd = '1px solid #FCA5A5'; col = 'var(--c600)'; icon = 'x'; }
          return (
            <div key={oi} className="row" style={{ padding: '9px 12px', gap: 10, background: bg, border: bd, borderRadius: 9 }}>
              <div style={{ width: 20, height: 20, borderRadius: 99, background: '#fff', color: 'var(--n700)', display: 'grid', placeItems: 'center', fontSize: 10, fontWeight: 800, flexShrink: 0 }}>{String.fromCharCode(65 + oi)}</div>
              <div style={{ flex: 1, fontSize: 12.5, fontWeight: isAns || isUser ? 700 : 500, color: col }}>{opt}</div>
              {icon && <Icon name={icon} size={14} style={{ color: col }}/>}
              {isUser && <span style={{ fontSize: 9.5, fontWeight: 800, color: col, fontFamily: 'var(--mono)', letterSpacing: '.06em' }}>YOUR PICK</span>}
            </div>
          );
        })}
      </div>
    );
  }

  if (q.type === 'multi') {
    const userSet = new Set(Array.isArray(userAns) ? userAns : []);
    const correctSet = new Set(q.correct);
    return (
      <div className="col" style={{ gap: 6 }}>
        {q.opts.map((opt, oi) => {
          const isUser = userSet.has(oi);
          const isAns = correctSet.has(oi);
          let bg = 'var(--n50)', bd = '1px solid var(--n100)', col = 'var(--n700)', icon = null;
          if (isAns && isUser) { bg = 'var(--success-50)'; bd = '1px solid #A7F3D0'; col = 'var(--success)'; icon = 'check'; }
          else if (isAns)      { bg = 'var(--success-50)'; bd = '1px dashed var(--success)'; col = 'var(--success)'; icon = 'check'; }
          else if (isUser)     { bg = 'var(--c50)';        bd = '1px solid #FCA5A5'; col = 'var(--c600)'; icon = 'x'; }
          return (
            <div key={oi} className="row" style={{ padding: '9px 12px', gap: 10, background: bg, border: bd, borderRadius: 9 }}>
              <div style={{ width: 20, height: 20, borderRadius: 5, background: isAns ? 'var(--success)' : '#fff', color: '#fff', border: isAns ? '0' : '1.5px solid var(--n300)', display: 'grid', placeItems: 'center', flexShrink: 0 }}>
                {isAns && <Icon name="check" size={11}/>}
              </div>
              <div style={{ flex: 1, fontSize: 12.5, fontWeight: isAns || isUser ? 700 : 500, color: col }}>{opt}</div>
              {icon && <Icon name={icon} size={14} style={{ color: col }}/>}
            </div>
          );
        })}
      </div>
    );
  }

  if (q.type === 'tf') {
    return (
      <div className="row" style={{ gap: 8 }}>
        {[true, false].map(v => {
          const isUser = userAns === v;
          const isAns = q.correct === v;
          const lab = v ? 'True' : 'False';
          let bg = 'var(--n50)', bd = '1px solid var(--n100)', col = 'var(--n700)';
          if (isAns) { bg = 'var(--success-50)'; bd = '1px solid #A7F3D0'; col = 'var(--success)'; }
          if (isUser && !isAns) { bg = 'var(--c50)'; bd = '1px solid #FCA5A5'; col = 'var(--c600)'; }
          return (
            <div key={lab} className="row" style={{ flex: 1, padding: '10px 12px', gap: 8, background: bg, border: bd, borderRadius: 9, justifyContent: 'center' }}>
              <Icon name={v ? 'check' : 'x'} size={14} style={{ color: col }}/>
              <span style={{ fontSize: 12.5, fontWeight: 700, color: col }}>{lab}</span>
              {isUser && <span style={{ fontSize: 9.5, fontWeight: 800, color: col, fontFamily: 'var(--mono)' }}>YOU</span>}
            </div>
          );
        })}
      </div>
    );
  }

  if (q.type === 'numeric' || q.type === 'short') {
    const accepted = q.type === 'numeric' ? `${q.correct}${q.unit ? ' ' + q.unit : ''}${q.tolerance > 0 ? ` (±${q.tolerance})` : ''}` : (q.correct.length ? q.correct.join(' / ') : '— teacher graded —');
    return (
      <div className="col" style={{ gap: 6 }}>
        <div style={{ padding: '10px 12px', borderRadius: 9, background: wasSkipped ? 'var(--n50)' : (isCorrect ? 'var(--success-50)' : 'var(--c50)'), border: `1px solid ${wasSkipped ? 'var(--n100)' : (isCorrect ? '#A7F3D0' : '#FCA5A5')}` }}>
          <div style={{ fontSize: 9.5, fontWeight: 800, letterSpacing: '.08em', fontFamily: 'var(--mono)', color: wasSkipped ? 'var(--n500)' : (isCorrect ? 'var(--success)' : 'var(--c600)') }}>YOUR ANSWER</div>
          <div style={{ fontSize: 14, fontWeight: 700, color: 'var(--n900)', marginTop: 3, fontFamily: q.type === 'numeric' ? 'var(--mono)' : 'inherit' }}>
            {wasSkipped ? '— skipped —' : (userAns || '—')}
          </div>
        </div>
        {!q.teacherGraded && (
          <div style={{ padding: '10px 12px', borderRadius: 9, background: 'var(--success-50)', border: '1px solid #A7F3D0' }}>
            <div style={{ fontSize: 9.5, fontWeight: 800, letterSpacing: '.08em', fontFamily: 'var(--mono)', color: 'var(--success)' }}>ACCEPTED</div>
            <div style={{ fontSize: 14, fontWeight: 700, color: 'var(--n900)', marginTop: 3, fontFamily: q.type === 'numeric' ? 'var(--mono)' : 'inherit' }}>{accepted}</div>
          </div>
        )}
      </div>
    );
  }

  if (q.type === 'fill') {
    const v = Array.isArray(userAns) ? userAns : Array(q.blanks).fill('');
    const segments = q.q.split('___');
    let bi = -1;
    return (
      <div style={{ padding: '12px 14px', borderRadius: 10, background: 'var(--n50)', border: '1px solid var(--n100)', fontSize: 14, lineHeight: 2.1, fontWeight: 600, color: 'var(--n900)' }}>
        {segments.map((seg, si) => (
          <React.Fragment key={si}>
            <span>{seg}</span>
            {si < segments.length - 1 && (() => {
              bi += 1;
              const accepted = q.correct[bi];
              const acceptedText = Array.isArray(accepted) ? accepted[0] : accepted;
              const userPick = v[bi];
              const isThisOk = userPick && (Array.isArray(accepted)
                ? accepted.some(c => String(c).toLowerCase() === String(userPick).trim().toLowerCase())
                : String(accepted).toLowerCase() === String(userPick).trim().toLowerCase());
              return (
                <span style={{ display: 'inline-flex', alignItems: 'center', gap: 4, margin: '0 4px' }}>
                  <span style={{
                    padding: '2px 8px', borderRadius: 6, fontWeight: 800,
                    background: isThisOk ? 'var(--success-50)' : userPick ? 'var(--c50)' : 'var(--n100)',
                    color: isThisOk ? 'var(--success)' : userPick ? 'var(--c600)' : 'var(--n500)',
                    textDecoration: !isThisOk && userPick ? 'line-through' : 'none',
                  }}>{userPick || '—'}</span>
                  {!isThisOk && (
                    <span style={{ padding: '2px 8px', borderRadius: 6, fontWeight: 800, background: 'var(--success-50)', color: 'var(--success)' }}>{acceptedText}</span>
                  )}
                </span>
              );
            })()}
          </React.Fragment>
        ))}
      </div>
    );
  }

  if (q.type === 'match') {
    const v = Array.isArray(userAns) ? userAns : q.pairs.map(() => null);
    return (
      <div className="col" style={{ gap: 6 }}>
        {q.pairs.map((p, i) => {
          const picked = v[i];
          const ok = picked === i;
          const userRight = picked === null ? '— skipped —' : q.pairs[picked].right;
          return (
            <div key={i} className="row" style={{ padding: '9px 12px', gap: 10, borderRadius: 9, background: ok ? 'var(--success-50)' : (picked === null ? 'var(--n50)' : 'var(--c50)'), border: `1px solid ${ok ? '#A7F3D0' : (picked === null ? 'var(--n100)' : '#FCA5A5')}` }}>
              <div style={{ flex: 1, fontSize: 12.5, fontWeight: 700, color: 'var(--n900)' }}>{p.left}</div>
              <Icon name={ok ? 'check' : 'x'} size={13} style={{ color: ok ? 'var(--success)' : 'var(--c600)' }}/>
              <div style={{ fontSize: 12, fontWeight: 700, color: ok ? 'var(--success)' : 'var(--c600)', textDecoration: ok ? 'none' : 'line-through' }}>{userRight}</div>
              {!ok && (
                <div style={{ fontSize: 12, fontWeight: 700, color: 'var(--success)' }}>→ {p.right}</div>
              )}
            </div>
          );
        })}
      </div>
    );
  }

  return null;
}

Object.assign(window, {
  QuestionInput, MCQInput, MultiInput, TFInput,
  NumericInput, ShortInput, FillInput, MatchInput,
  ReviewAnswer,
});
