// Activities 1–5: flashcards, matching, spelling, sentence builder, gap fill
const { useState, useEffect, useRef, useMemo } = React;

// ---------- 1. Learn the Words (flashcards) ----------
function WordsActivity({ onComplete, earn }) {
  const [heard, setHeard] = useState({});
  const allHeard = Object.keys(heard).length >= VOCAB.length;
  const doneRef = useRef(false);

  function tapCard(v, e) {
    SFX.click();
    speak(v.word);
    if (!heard[v.id]) {
      const next = { ...heard, [v.id]: true };
      setHeard(next);
      if (Object.keys(next).length === VOCAB.length && !doneRef.current) {
        doneRef.current = true;
        earn(2);
        SFX.star();
      }
    }
  }

  return (
    <ActivityShell stepNo="1" title="Learn the words"
      instructions="Tap every card and listen. Say the word out loud!">
      <div className="cards-grid">
        {VOCAB.map((v) => (
          <button key={v.id} type="button"
            className={'word-card' + (heard[v.id] ? ' word-card-heard' : '')}
            onClick={(e) => tapCard(v, e)}>
            <PhotoSlot label={v.word} />
            <div className="word-card-label">{v.word}</div>
            {heard[v.id] && <div className="heard-stamp">★</div>}
          </button>
        ))}
      </div>
      <div className="activity-foot">
        <span className="foot-hint">{allHeard ? 'Great listening! ★★' : (Object.keys(heard).length + ' / ' + VOCAB.length + ' words')}</span>
        <NextBtn onClick={onComplete} disabled={!allHeard} />
      </div>
    </ActivityShell>
  );
}

// ---------- 2. Matching (word ↔ picture) ----------
const MATCH_IDS = ['beach', 'icecream', 'kite', 'watermelon', 'sandcastle', 'bike'];
function MatchActivity({ onComplete, earn }) {
  const pairs = useMemo(() => VOCAB.filter((v) => MATCH_IDS.includes(v.id)), []);
  const photos = useMemo(() => shuffleArr(pairs), [pairs]);
  const [selWord, setSelWord] = useState(null);
  const [matched, setMatched] = useState({});
  const [shakeId, setShakeId] = useState(null);
  const allDone = Object.keys(matched).length === pairs.length;

  function tapWord(id) {
    if (matched[id]) return;
    SFX.click();
    setSelWord(id === selWord ? null : id);
  }
  function tapPhoto(id, e) {
    if (matched[id] || !selWord) return;
    if (id === selWord) {
      SFX.correct();
      earn(1);
      starPop(e.clientX, e.clientY);
      const next = { ...matched, [id]: true };
      setMatched(next);
      setSelWord(null);
      if (Object.keys(next).length === pairs.length) {
        setTimeout(() => { SFX.win(); burstConfetti(24); }, 300);
      }
    } else {
      SFX.wrong();
      setShakeId(id);
      setTimeout(() => setShakeId(null), 500);
    }
  }

  return (
    <ActivityShell stepNo="2" title="Match!"
      instructions="Tap a word, then tap its picture.">
      <div className="match-board">
        <div className="match-col">
          {pairs.map((v) => (
            <button key={v.id} type="button"
              className={'match-word' + (matched[v.id] ? ' match-ok' : '') + (selWord === v.id ? ' match-sel' : '')}
              onClick={() => tapWord(v.id)} disabled={!!matched[v.id]}>
              {v.word}
            </button>
          ))}
        </div>
        <div className="match-col">
          {photos.map((v) => (
            <button key={v.id} type="button"
              className={'match-photo' + (matched[v.id] ? ' match-ok' : '') + (shakeId === v.id ? ' shake' : '')}
              onClick={(e) => tapPhoto(v.id, e)} disabled={!!matched[v.id]}>
              <PhotoSlot label={v.word} size={64} />
              {matched[v.id] && <span className="match-check">&#10003;</span>}
            </button>
          ))}
        </div>
      </div>
      <div className="activity-foot">
        <span className="foot-hint">{allDone ? 'Amazing! All matched!' : (Object.keys(matched).length + ' / ' + pairs.length + ' matched')}</span>
        <NextBtn onClick={onComplete} disabled={!allDone} />
      </div>
    </ActivityShell>
  );
}

// ---------- 3. Spell It ----------
const SPELL_WORDS = ['kite', 'swim', 'bike', 'beach'];
function SpellActivity({ onComplete, earn }) {
  const [idx, setIdx] = useState(0);
  const [picked, setPicked] = useState([]); // indices into letters
  const [wrongFlash, setWrongFlash] = useState(false);
  const [solved, setSolved] = useState(0);
  const word = SPELL_WORDS[idx] || null;
  const letters = useMemo(() => {
    if (!word) return [];
    let l = shuffleArr(word.split(''));
    if (l.join('') === word) l = l.reverse();
    return l;
  }, [word]);

  useEffect(() => { if (word) speak(word); }, [word]);

  function tapLetter(i) {
    if (picked.includes(i) || !word) return;
    SFX.click();
    const next = [...picked, i];
    setPicked(next);
    if (next.length === word.length) {
      const attempt = next.map((n) => letters[n]).join('');
      if (attempt === word) {
        SFX.correct(); earn(1);
        setSolved(solved + 1);
        setTimeout(() => {
          setPicked([]);
          if (idx + 1 >= SPELL_WORDS.length) { SFX.win(); burstConfetti(20); setIdx(idx + 1); }
          else setIdx(idx + 1);
        }, 700);
      } else {
        SFX.wrong();
        setWrongFlash(true);
        setTimeout(() => { setWrongFlash(false); setPicked([]); }, 650);
      }
    }
  }
  function undo() {
    if (!picked.length) return;
    SFX.click();
    setPicked(picked.slice(0, -1));
  }

  const finished = idx >= SPELL_WORDS.length;
  return (
    <ActivityShell stepNo="3" title="Spell it!"
      instructions="Look at the picture, listen, and tap the letters in order.">
      {!finished ? (
        <div className="spell-wrap">
          <div className="spell-photo">
            <PhotoSlot label={word} size={120} />
            <ListenBtn text={word} />
          </div>
          <div className={'spell-boxes' + (wrongFlash ? ' shake' : '')}>
            {word.split('').map((_, i) => (
              <div key={i} className={'spell-box' + (picked[i] !== undefined ? ' spell-box-filled' : '')}>
                {picked[i] !== undefined ? letters[picked[i]] : ''}
              </div>
            ))}
          </div>
          <div className="spell-letters">
            {letters.map((l, i) => (
              <button key={i} type="button" className="letter-tile"
                onClick={() => tapLetter(i)} disabled={picked.includes(i)}>
                {l}
              </button>
            ))}
            <button type="button" className="letter-undo" onClick={undo}>&#8592;</button>
          </div>
          <div className="foot-hint">Word {idx + 1} of {SPELL_WORDS.length}</div>
        </div>
      ) : (
        <div className="mini-done">
          <div className="mini-done-big">★ {solved} / {SPELL_WORDS.length}</div>
          <p>Super spelling!</p>
        </div>
      )}
      <div className="activity-foot">
        <span></span>
        <NextBtn onClick={onComplete} disabled={!finished} />
      </div>
    </ActivityShell>
  );
}

// ---------- 4. Build Sentences ----------
const SENTENCES = [
  ['I', 'want', 'to', 'eat', 'ice cream'],
  ['I', 'want', 'to', 'fly', 'a', 'kite'],
  ['I', 'want', 'to', 'swim', 'in', 'the', 'sea'],
  ['I', 'want', 'to', 'have', 'a', 'picnic'],
];
function BuildActivity({ onComplete, earn }) {
  const [idx, setIdx] = useState(0);
  const [placed, setPlaced] = useState([]); // array of bank indices
  const [wrongFlash, setWrongFlash] = useState(false);
  const target = SENTENCES[idx] || null;
  const bank = useMemo(() => {
    if (!target) return [];
    let b = shuffleArr(target.map((w, i) => ({ w, i })));
    if (b.map((x) => x.w).join(' ') === target.join(' ')) b = b.reverse();
    return b;
  }, [target]);

  function tapBank(bi) {
    if (placed.includes(bi)) return;
    SFX.click();
    setPlaced([...placed, bi]);
  }
  function tapPlaced(pos) {
    SFX.click();
    setPlaced(placed.filter((_, i) => i !== pos));
  }
  function check(e) {
    const attempt = placed.map((bi) => bank[bi].w).join(' ');
    if (attempt === target.join(' ')) {
      SFX.correct(); earn(1);
      starPop(e.clientX, e.clientY);
      speak(target.join(' '));
      setTimeout(() => {
        setPlaced([]);
        if (idx + 1 >= SENTENCES.length) { SFX.win(); burstConfetti(24); }
        setIdx(idx + 1);
      }, 900);
    } else {
      SFX.wrong();
      setWrongFlash(true);
      setTimeout(() => setWrongFlash(false), 600);
    }
  }

  const finished = idx >= SENTENCES.length;
  return (
    <ActivityShell stepNo="4" title="Build the sentence"
      instructions="Tap the words in order. Tap a word again to take it back.">
      {!finished ? (
        <div className="build-wrap">
          <div className={'build-line' + (wrongFlash ? ' shake' : '')}>
            {placed.length === 0 && <span className="build-ghost">Tap words below&#8230;</span>}
            {placed.map((bi, pos) => (
              <button key={pos} type="button" className="chip chip-placed" onClick={() => tapPlaced(pos)}>
                {bank[bi].w}
              </button>
            ))}
            {placed.length > 0 && <span className="build-dot">.</span>}
          </div>
          <div className="build-bank">
            {bank.map((item, bi) => (
              <button key={bi} type="button" className="chip" onClick={() => tapBank(bi)}
                disabled={placed.includes(bi)}
                style={{ visibility: placed.includes(bi) ? 'hidden' : 'visible' }}>
                {item.w}
              </button>
            ))}
          </div>
          <div className="build-actions">
            <span className="foot-hint">Sentence {idx + 1} of {SENTENCES.length}</span>
            <button type="button" className="btn btn-check" disabled={placed.length !== target.length}
              onClick={check}>Check &#10003;</button>
          </div>
        </div>
      ) : (
        <div className="mini-done">
          <div className="mini-done-big">★★★★</div>
          <p>You are a sentence builder!</p>
        </div>
      )}
      <div className="activity-foot">
        <span></span>
        <NextBtn onClick={onComplete} disabled={!finished} />
      </div>
    </ActivityShell>
  );
}

// ---------- 5. Fill the Gaps ----------
const GAPS = [
  { before: 'In summer, it is', after: '.', options: ['hot', 'cold', 'snowy'], answer: 'hot' },
  { before: 'I', after: 'to the beach.', options: ['fly', 'go', 'eat'], answer: 'go' },
  { before: 'I', after: 'ice cream.', options: ['ride', 'build', 'eat'], answer: 'eat' },
  { before: 'I', after: 'a sandcastle.', options: ['build', 'drink', 'fly'], answer: 'build' },
  { before: 'I', after: 'my bike.', options: ['swim', 'ride', 'eat'], answer: 'ride' },
];
function GapsActivity({ onComplete, earn }) {
  const [answers, setAnswers] = useState({}); // i -> chosen word (only when correct)
  const [wrongPick, setWrongPick] = useState({}); // i -> {word: true}
  const allDone = Object.keys(answers).length === GAPS.length;

  function pick(i, word, e) {
    if (answers[i] !== undefined) return;
    if (word === GAPS[i].answer) {
      SFX.correct(); earn(1);
      starPop(e.clientX, e.clientY);
      const next = { ...answers, [i]: word };
      setAnswers(next);
      if (Object.keys(next).length === GAPS.length) {
        setTimeout(() => { SFX.win(); burstConfetti(24); }, 300);
      }
    } else {
      SFX.wrong();
      setWrongPick({ ...wrongPick, [i]: { ...(wrongPick[i] || {}), [word]: true } });
    }
  }

  return (
    <ActivityShell stepNo="5" title="Fill the gaps"
      instructions="Tap the right word for each sentence.">
      <div className="gaps-list">
        {GAPS.map((g, i) => (
          <div key={i} className={'gap-row' + (answers[i] ? ' gap-row-done' : '')}>
            <div className="gap-sentence">
              {g.before}{' '}
              <span className={'gap-slot' + (answers[i] ? ' gap-slot-filled' : '')}>
                {answers[i] || '____'}
              </span>{' '}
              {g.after}
            </div>
            <div className="gap-options">
              {g.options.map((w) => {
                const isWrong = wrongPick[i] && wrongPick[i][w];
                const isRight = answers[i] === w;
                return (
                  <button key={w} type="button"
                    className={'chip chip-small' + (isRight ? ' chip-right' : '') + (isWrong ? ' chip-wrong' : '')}
                    disabled={answers[i] !== undefined || isWrong}
                    onClick={(e) => pick(i, w, e)}>
                    {w}
                  </button>
                );
              })}
            </div>
          </div>
        ))}
      </div>
      <div className="activity-foot">
        <span className="foot-hint">{allDone ? 'All gaps filled — fantastic!' : (Object.keys(answers).length + ' / ' + GAPS.length)}</span>
        <NextBtn onClick={onComplete} disabled={!allDone} />
      </div>
    </ActivityShell>
  );
}

Object.assign(window, { WordsActivity, MatchActivity, SpellActivity, BuildActivity, GapsActivity });
