// Lesson / exercise screens
// - QCM (multiple choice)
// - Drag and drop (classify accounts actif/passif)
// - Journal entry (debit/credit input)
// - Flashcard
// All sit in a "Lesson" container with progress bar + hearts + Milo feedback

function LessonShell({ theme, lang, progress, hearts, onClose, children }) {
  return (
    <div style={{ height: '100%', background: theme.bg, display: 'flex', flexDirection: 'column' }}>
      {/* top bar */}
      <div style={{
        padding: '60px 16px 16px',
        display: 'flex', alignItems: 'center', gap: 12,
      }}>
        <button onClick={onClose} style={{
          width: 36, height: 36, background: 'transparent', border: 'none',
          cursor: 'pointer', padding: 0,
          display: 'flex', alignItems: 'center', justifyContent: 'center',
        }}>
          <svg width="22" height="22" viewBox="0 0 24 24" fill="none" stroke="#AFAFAF" strokeWidth="3" strokeLinecap="round">
            <path d="M6 6l12 12M18 6L6 18"/>
          </svg>
        </button>
        <div style={{ flex: 1 }}>
          <ProgressBar theme={theme} value={progress} color={theme.success} height={16}/>
        </div>
        <div style={{ display: 'flex', alignItems: 'center', gap: 4 }}>
          <HeartIcon size={22}/>
          <span style={{ color: theme.danger, fontWeight: 800, fontSize: 17, fontFamily: theme.fontBody }}>{hearts}</span>
        </div>
      </div>
      <div style={{ flex: 1, overflow: 'auto', padding: '0 20px 20px' }}>{children}</div>
    </div>
  );
}

// ── QCM ─────────────────────────────────────────────
function QCMExercise({ theme, lang, exercise, onAnswer }) {
  const question = loc(exercise.question, lang);
  const options = loc(exercise.options, lang);
  const correct = exercise.correct;
  const prompt = loc(exercise.prompt, lang);
  const explainKO = loc(exercise.explainKO, lang);
  const [picked, setPicked] = React.useState(null);
  const [checked, setChecked] = React.useState(false);
  const isCorrect = picked === correct;

  return (
    <>
      <div style={{ marginTop: 8 }}>
        <div style={{
          fontFamily: theme.fontBody, fontSize: 13, fontWeight: 700,
          color: theme.inkSoft, textTransform: 'uppercase', letterSpacing: 1, marginBottom: 12,
        }}>
          {prompt || (lang==='fr'?'Choisis la bonne r\u00e9ponse':'Select the correct answer')}
        </div>
        <div style={{ display: 'flex', gap: 12, alignItems: 'flex-start', marginBottom: 20 }}>
          <MiloHead size={72} emotion="focused"/>
          <SpeechBubble theme={theme}>
            <div style={{ fontFamily: theme.font, fontSize: 17, fontWeight: 600, lineHeight: 1.35, color: theme.ink }}>
              {question}
            </div>
          </SpeechBubble>
        </div>

        <div style={{ display: 'flex', flexDirection: 'column', gap: 10 }}>
          {options.map((o, i) => {
            const active = picked === i;
            const showCorrect = checked && i === correct;
            const showWrong = checked && active && i !== correct;
            let bg = theme.surface, borderCol = theme.border;
            if (showCorrect) { bg = theme.successSoft; borderCol = theme.success; }
            else if (showWrong) { bg = '#FDE2E2'; borderCol = theme.danger; }
            else if (active) { bg = theme.primarySoft; borderCol = theme.primary; }
            return (
              <button key={i} onClick={() => !checked && setPicked(i)} style={{
                display: 'flex', alignItems: 'center', gap: 14,
                padding: '14px 16px', textAlign: 'left',
                background: bg, border: `2px solid ${borderCol}`,
                borderRadius: 14, cursor: checked ? 'default' : 'pointer',
                boxShadow: `0 2px 0 ${borderCol}`,
                fontFamily: theme.fontBody,
              }}>
                <div style={{
                  width: 28, height: 28, borderRadius: 8,
                  border: `2px solid ${borderCol}`,
                  background: active || showCorrect ? borderCol : 'transparent',
                  color: active || showCorrect ? '#fff' : theme.inkSoft,
                  display: 'flex', alignItems: 'center', justifyContent: 'center',
                  fontWeight: 800, fontSize: 13,
                }}>{String.fromCharCode(65+i)}</div>
                <div style={{ flex: 1, fontSize: 15, fontWeight: 600, color: theme.ink }}>{o}</div>
              </button>
            );
          })}
        </div>
      </div>
      <FeedbackBar
        theme={theme} lang={lang} state={!checked ? 'idle' : isCorrect ? 'correct' : 'wrong'}
        canCheck={picked !== null}
        onCheck={() => setChecked(true)}
        onContinue={() => onAnswer(isCorrect)}
        explain={!isCorrect ? (explainKO || (lang==='fr' ? `La bonne r\u00e9ponse est : ${options[correct]}` : `Correct answer: ${options[correct]}`)) : null}
      />
    </>
  );
}

// ── Drag & drop classify ────────────────────────────
function DragDropExercise({ theme, lang, exercise, onAnswer }) {
  const items = exercise.items.map(function (i) {
    return { id: i.id, label: loc(i.label, lang), cat: i.cat };
  });
  const prompt = loc(exercise.prompt, lang);
  const question = loc(exercise.question, lang);
  const explainKO = loc(exercise.explainKO, lang);
  const [placed, setPlaced] = React.useState({}); // id → cat
  const [checked, setChecked] = React.useState(false);

  const placeItem = (id, cat) => {
    if (checked) return;
    setPlaced(p => ({ ...p, [id]: cat }));
  };
  const unplaced = items.filter(i => !placed[i.id]);
  const inZone = (cat) => items.filter(i => placed[i.id] === cat);
  const allPlaced = unplaced.length === 0;
  const isCorrect = items.every(i => placed[i.id] === i.cat);

  return (
    <>
      <div style={{
        fontFamily: theme.fontBody, fontSize: 13, fontWeight: 700,
        color: theme.inkSoft, textTransform: 'uppercase', letterSpacing: 1, marginTop: 8, marginBottom: 12,
      }}>
        {prompt || (lang==='fr'?'Classe les comptes':'Classify accounts')}
      </div>

      <div style={{ display: 'flex', gap: 12, alignItems: 'flex-start', marginBottom: 16 }}>
        <MiloHead size={64} emotion="focused"/>
        <SpeechBubble theme={theme}>
          <div style={{ fontFamily: theme.font, fontSize: 16, fontWeight: 600, color: theme.ink }}>
            {question || (lang==='fr'?'Range chaque compte dans la bonne colonne.':'Drop each account into the right column.')}
          </div>
        </SpeechBubble>
      </div>

      {/* pool */}
      <div style={{
        background: theme.muted, border: `2px dashed ${theme.border}`,
        borderRadius: 14, padding: 12, minHeight: 80,
        display: 'flex', flexWrap: 'wrap', gap: 8, marginBottom: 14,
      }}>
        {unplaced.length === 0 ? (
          <div style={{ width: '100%', textAlign: 'center', color: theme.inkSoft, fontSize: 13, padding: 12 }}>
            {lang==='fr'?'\u2713 Tout est plac\u00e9':'\u2713 All placed'}
          </div>
        ) : unplaced.map(i => (
          <DragChip key={i.id} item={i} theme={theme} onPick={(cat) => placeItem(i.id, cat)}/>
        ))}
      </div>

      {/* zones */}
      <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 10 }}>
        {['actif', 'passif'].map(cat => (
          <div key={cat} style={{
            background: cat === 'actif' ? '#E6F0F5' : '#F5EADF',
            border: `2px solid ${cat === 'actif' ? '#4A7A8C' : '#B8854A'}`,
            borderRadius: 14, padding: 10, minHeight: 200,
            display: 'flex', flexDirection: 'column', gap: 6,
          }}>
            <div style={{
              fontFamily: theme.font, fontSize: 18, fontWeight: 700,
              color: cat === 'actif' ? '#2A5766' : '#6B4423', textAlign: 'center',
              paddingBottom: 6, borderBottom: `1.5px solid ${cat === 'actif' ? '#4A7A8C40' : '#B8854A40'}`,
            }}>
              {cat === 'actif' ? (lang==='fr'?'ACTIF':'ASSETS') : (lang==='fr'?'PASSIF':'LIABILITIES')}
            </div>
            {inZone(cat).map(i => {
              const wrong = checked && i.cat !== cat;
              return (
                <div key={i.id} style={{
                  background: wrong ? '#FDE2E2' : theme.surface,
                  border: `1.5px solid ${wrong ? theme.danger : theme.border}`,
                  borderRadius: 10, padding: '8px 10px',
                  fontFamily: theme.fontBody, fontSize: 13, fontWeight: 600,
                  color: theme.ink,
                  display: 'flex', alignItems: 'center', justifyContent: 'space-between',
                }}>
                  <span>{i.label}</span>
                  {checked && (
                    <span style={{ color: wrong ? theme.danger : theme.success, fontSize: 14 }}>
                      {wrong ? '\u2717' : '\u2713'}
                    </span>
                  )}
                </div>
              );
            })}
          </div>
        ))}
      </div>

      <FeedbackBar
        theme={theme} lang={lang} state={!checked ? 'idle' : isCorrect ? 'correct' : 'wrong'}
        canCheck={allPlaced}
        onCheck={() => setChecked(true)}
        onContinue={() => onAnswer(isCorrect)}
        explain={!isCorrect ? (explainKO || (lang==='fr' ? 'Revois la d\u00e9finition : l\u2019actif, c\u2019est ce que poss\u00e8de l\u2019entreprise.' : 'Recall: assets = what the company owns.')) : null}
      />
    </>
  );
}

function DragChip({ item, theme, onPick }) {
  // Simple tap-to-place with a tiny menu since drag on mobile is fiddly
  const [open, setOpen] = React.useState(false);
  return (
    <div style={{ position: 'relative' }}>
      <button onClick={() => setOpen(!open)} style={{
        background: theme.surface, border: `2px solid ${theme.border}`,
        borderRadius: 10, padding: '8px 12px',
        fontFamily: theme.fontBody, fontSize: 13, fontWeight: 700,
        color: theme.ink, cursor: 'pointer',
        boxShadow: `0 2px 0 ${theme.border}`,
      }}>{item.label}</button>
      {open && (
        <div style={{
          position: 'absolute', top: '100%', left: 0, marginTop: 4, zIndex: 20,
          background: theme.surface, border: `2px solid ${theme.border}`,
          borderRadius: 10, overflow: 'hidden', boxShadow: `0 4px 16px rgba(0,0,0,0.1)`,
        }}>
          <div onClick={() => { onPick('actif'); setOpen(false); }} style={{
            padding: '8px 14px', fontFamily: theme.fontBody, fontSize: 13, fontWeight: 600,
            color: '#2A5766', cursor: 'pointer', borderBottom: `1px solid ${theme.border}`,
          }}>→ Actif</div>
          <div onClick={() => { onPick('passif'); setOpen(false); }} style={{
            padding: '8px 14px', fontFamily: theme.fontBody, fontSize: 13, fontWeight: 600,
            color: '#6B4423', cursor: 'pointer',
          }}>→ Passif</div>
        </div>
      )}
    </div>
  );
}

// ── Journal entry (debit/credit) ────────────────────
function JournalExercise({ theme, lang, exercise, onAnswer }) {
  const accounts = exercise.accounts.map(function (a) {
    return { code: a.code, name: loc(a.name, lang) };
  });
  const expected = exercise.expected;
  const scenarioText = loc(exercise.scenario, lang);
  const promptText = loc(exercise.prompt, lang);
  const hintText = loc(exercise.hint, lang);
  const explainKO = loc(exercise.explainKO, lang);

  const [lines, setLines] = React.useState(expected.map(function () {
    return { account: '', debit: '', credit: '' };
  }));
  const [checked, setChecked] = React.useState(false);

  const totalDebit = lines.reduce((s, l) => s + (parseFloat(l.debit) || 0), 0);
  const totalCredit = lines.reduce((s, l) => s + (parseFloat(l.credit) || 0), 0);
  const balanced = totalDebit > 0 && totalDebit === totalCredit;

  const matchesExpected = function (line, exp) {
    if (line.account !== exp.account) return false;
    var amt = parseFloat(exp.side === 'debit' ? line.debit : line.credit);
    var other = parseFloat(exp.side === 'debit' ? line.credit : line.debit);
    return amt === exp.amount && (isNaN(other) || other === 0);
  };
  const correct = expected.every(function (exp) {
    return lines.some(function (l) { return matchesExpected(l, exp); });
  });

  const lineExpectedAt = function (i) {
    return expected[i] || null;
  };
  const isLineWrong = function (i, l) {
    if (!checked) return false;
    var exp = lineExpectedAt(i);
    if (!exp) return l.account || l.debit || l.credit ? true : false;
    return !matchesExpected(l, exp);
  };

  const update = (i, k, v) => {
    setLines(ls => ls.map((l, idx) => idx === i ? { ...l, [k]: v } : l));
  };

  return (
    <>
      <div style={{
        fontFamily: theme.fontBody, fontSize: 13, fontWeight: 700,
        color: theme.inkSoft, textTransform: 'uppercase', letterSpacing: 1, marginTop: 8, marginBottom: 12,
      }}>
        {promptText || (lang==='fr'?'Saisis l\u2019\u00e9criture comptable':'Record the journal entry')}
      </div>

      <div style={{ display: 'flex', gap: 12, alignItems: 'flex-start', marginBottom: 16 }}>
        <MiloHead size={64} emotion="focused" accessory="glasses"/>
        <SpeechBubble theme={theme}>
          <div style={{ fontFamily: theme.font, fontSize: 15, fontWeight: 600, color: theme.ink, lineHeight: 1.4 }}>
            {scenarioText}
          </div>
        </SpeechBubble>
      </div>

      {/* journal header */}
      <div style={{
        background: theme.surface, borderRadius: 14, border: `1px solid ${theme.border}`,
        overflow: 'hidden', marginBottom: 14,
      }}>
        <div style={{
          display: 'grid', gridTemplateColumns: '1.6fr 1fr 1fr',
          background: theme.muted, padding: '8px 12px',
          fontFamily: theme.fontBody, fontSize: 11, fontWeight: 800,
          textTransform: 'uppercase', letterSpacing: 0.5, color: theme.inkSoft,
        }}>
          <div>{lang==='fr'?'Compte':'Account'}</div>
          <div style={{ textAlign: 'right' }}>{lang==='fr'?'D\u00e9bit':'Debit'}</div>
          <div style={{ textAlign: 'right' }}>{lang==='fr'?'Cr\u00e9dit':'Credit'}</div>
        </div>
        {lines.map((l, i) => {
          const lineWrong = isLineWrong(i, l);
          return (
            <div key={i} style={{
              display: 'grid', gridTemplateColumns: '1.6fr 1fr 1fr',
              padding: '10px 12px', borderTop: `1px solid ${theme.border}`,
              background: lineWrong ? '#FDE2E2' : 'transparent',
              alignItems: 'center',
            }}>
              <AccountPicker theme={theme} value={l.account} accounts={accounts} onChange={v => update(i, 'account', v)} disabled={checked}/>
              <CellInput theme={theme} value={l.debit} onChange={v => update(i, 'debit', v)} align="right" disabled={checked}/>
              <CellInput theme={theme} value={l.credit} onChange={v => update(i, 'credit', v)} align="right" disabled={checked}/>
            </div>
          );
        })}
        {/* totals */}
        <div style={{
          display: 'grid', gridTemplateColumns: '1.6fr 1fr 1fr',
          padding: '10px 12px', borderTop: `2px solid ${theme.border}`,
          background: balanced ? theme.successSoft : theme.muted,
          fontFamily: theme.fontBody, fontSize: 14, fontWeight: 800,
        }}>
          <div style={{ color: theme.inkSoft, textTransform: 'uppercase', fontSize: 11, letterSpacing: 0.5 }}>
            {lang==='fr'?'Totaux':'Totals'} {balanced && '✓'}
          </div>
          <div style={{ textAlign: 'right', color: theme.ink }}>{totalDebit.toFixed(2)} €</div>
          <div style={{ textAlign: 'right', color: theme.ink }}>{totalCredit.toFixed(2)} €</div>
        </div>
      </div>

      {hintText && (
        <div style={{
          fontFamily: theme.fontBody, fontSize: 12, color: theme.inkSoft,
          padding: '0 4px', lineHeight: 1.5,
        }}>💡 {hintText}</div>
      )}

      <FeedbackBar
        theme={theme} lang={lang} state={!checked ? 'idle' : correct ? 'correct' : 'wrong'}
        canCheck={balanced && lines.every(l => l.account)}
        onCheck={() => setChecked(true)}
        onContinue={() => onAnswer(correct)}
        explain={!correct ? explainKO : null}
      />
    </>
  );
}

function AccountPicker({ theme, value, accounts, onChange, disabled }) {
  const [open, setOpen] = React.useState(false);
  const cur = accounts.find(a => a.code === value);
  return (
    <div style={{ position: 'relative' }}>
      <button disabled={disabled} onClick={() => setOpen(!open)} style={{
        width: '100%', textAlign: 'left',
        background: 'transparent', border: 'none', padding: 0,
        fontFamily: theme.fontBody, fontSize: 13, fontWeight: 600,
        color: cur ? theme.ink : theme.inkSoft,
        cursor: disabled ? 'default' : 'pointer',
      }}>
        {cur ? (
          <span><span style={{ color: theme.primary, fontWeight: 800 }}>{cur.code}</span> · {cur.name}</span>
        ) : '— choisir —'}
      </button>
      {open && !disabled && (
        <div style={{
          position: 'absolute', top: '100%', left: -8, marginTop: 4, zIndex: 40,
          width: 260, maxHeight: 200, overflow: 'auto',
          background: theme.surface, border: `2px solid ${theme.border}`,
          borderRadius: 10, boxShadow: `0 4px 16px rgba(0,0,0,0.12)`,
        }}>
          {accounts.map(a => (
            <div key={a.code} onClick={() => { onChange(a.code); setOpen(false); }} style={{
              padding: '8px 12px', cursor: 'pointer',
              fontFamily: theme.fontBody, fontSize: 13,
              borderBottom: `1px solid ${theme.border}`,
              display: 'flex', gap: 8,
            }}>
              <span style={{ color: theme.primary, fontWeight: 800, minWidth: 48 }}>{a.code}</span>
              <span style={{ color: theme.ink }}>{a.name}</span>
            </div>
          ))}
        </div>
      )}
    </div>
  );
}

function CellInput({ theme, value, onChange, align, disabled }) {
  return (
    <input value={value} onChange={e => onChange(e.target.value)} disabled={disabled}
      placeholder="—"
      style={{
        width: '100%', border: 'none', background: 'transparent',
        fontFamily: theme.fontBody, fontSize: 15, fontWeight: 700,
        color: theme.ink, textAlign: align, outline: 'none',
    }}/>
  );
}

// ── Feedback bar ────────────────────────────────────
function FeedbackBar({ theme, lang, state, canCheck, onCheck, onContinue, explain }) {
  const correct = state === 'correct';
  const wrong = state === 'wrong';
  return (
    <div style={{ marginTop: 20, position: 'sticky', bottom: 0, background: theme.bg, paddingTop: 8 }}>
      {(correct || wrong) && (
        <div style={{
          background: correct ? theme.successSoft : '#FDE2E2',
          border: `2px solid ${correct ? theme.success : theme.danger}`,
          borderRadius: 14, padding: '12px 14px', marginBottom: 10,
          display: 'flex', gap: 10, alignItems: 'flex-start',
        }}>
          <div style={{
            width: 32, height: 32, borderRadius: '50%', flexShrink: 0,
            background: correct ? theme.success : theme.danger,
            display: 'flex', alignItems: 'center', justifyContent: 'center',
          }}>
            {correct ? (
              <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="#fff" strokeWidth="3" strokeLinecap="round"><path d="M5 12l5 5L20 7"/></svg>
            ) : (
              <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="#fff" strokeWidth="3" strokeLinecap="round"><path d="M6 6l12 12M18 6L6 18"/></svg>
            )}
          </div>
          <div style={{ fontFamily: theme.fontBody, color: correct ? theme.success : theme.danger }}>
            <div style={{ fontWeight: 800, fontSize: 16 }}>
              {correct ? (lang==='fr'?'Bravo !':'Nice!') : (lang==='fr'?'Presque !':'Almost!')}
            </div>
            {explain && <div style={{ fontSize: 13, marginTop: 2, opacity: 0.9 }}>{explain}</div>}
          </div>
        </div>
      )}
      {state === 'idle' ? (
        <Button theme={theme} full size="lg"
          variant={canCheck ? 'success' : 'outline'}
          onClick={() => canCheck && onCheck()}
          style={{ opacity: canCheck ? 1 : 0.5 }}
        >{lang==='fr'?'V\u00e9rifier':'Check'}</Button>
      ) : (
        <Button theme={theme} full size="lg"
          variant={correct ? 'success' : 'danger'}
          onClick={onContinue}
        >{lang==='fr'?'Continuer':'Continue'}</Button>
      )}
    </div>
  );
}

Object.assign(window, { LessonShell, QCMExercise, DragDropExercise, JournalExercise, FeedbackBar });
