// Memory match game.
const MEM_PAIRS = [
  { id: 'mawar', e: '🌹' },
  { id: 'kucing', e: '🐈' },
  { id: 'bulan', e: '🌙' },
  { id: 'teh', e: '🍵' },
  { id: 'kupu', e: '🦋' },
  { id: 'rumah', e: '🏡' },
];

function shuffle(arr) {
  const a = arr.slice();
  for (let i = a.length - 1; i > 0; i--) {
    const j = Math.floor(Math.random() * (i + 1));
    [a[i], a[j]] = [a[j], a[i]];
  }
  return a;
}

function buildDeck() {
  return shuffle(MEM_PAIRS.flatMap(p => [
    { key: p.id + 'a', id: p.id, e: p.e },
    { key: p.id + 'b', id: p.id, e: p.e },
  ]));
}

function GameTopBar({ onExit, progress, hearts }) {
  return (
    <div style={{ display:'flex', alignItems:'center', gap: 14, padding: '8px 18px 14px' }}>
      <button onClick={() => { OASound.tap(); onExit(); }} className="oa-no-tap" aria-label="Keluar latihan" style={{
        width: 48, height: 48, borderRadius: 16, border: `2px solid ${OA_THEME.line}`,
        background: OA_THEME.card, fontSize: 24, fontWeight: 900, color: OA_THEME.inkSoft, cursor: 'pointer',
        flexShrink: 0,
      }}>✕</button>
      <div style={{ flex: 1, height: 16, borderRadius: 10, background: '#E6DFD3', overflow:'hidden', border: `1.5px solid ${OA_THEME.line}` }}>
        <div style={{
          height: '100%', width: `${Math.max(0, Math.min(100, progress * 100))}%`,
          background: `linear-gradient(90deg, ${OA_THEME.sage}, ${OA_THEME.sageDeep})`,
          borderRadius: 10, transition: 'width .5s',
        }} />
      </div>
      <div style={{ display:'flex', alignItems:'center', gap: 4, fontSize: 22, fontWeight: 800, color: OA_THEME.roseDeep }}>
        {Array.from({length: 5}).map((_, i) => (
          <span key={i} style={{ opacity: i < hearts ? 1 : 0.25, transform: `scale(${i < hearts ? 1 : .85})`, transition: 'all .3s' }}>♥</span>
        ))}
      </div>
    </div>
  );
}

function MemoryGame({ onExit, onComplete }) {
  const [deck, setDeck] = React.useState(() => buildDeck());
  const [flipped, setFlipped] = React.useState([]);
  const [matched, setMatched] = React.useState({});
  const [taps, setTaps] = React.useState(0);
  const [hearts, setHearts] = React.useState(5);
  const [bouncing, setBouncing] = React.useState(null);
  const totalPairs = MEM_PAIRS.length;
  const matchedCount = Object.keys(matched).length;

  React.useEffect(() => {
    if (flipped.length !== 2) return;
    const [a, b] = flipped;
    setTaps(t => t + 1);
    if (deck[a].id === deck[b].id) {
      OASound.match();
      setTimeout(() => {
        setMatched(m => ({ ...m, [deck[a].id]: true }));
        setBouncing(deck[a].id);
        setFlipped([]);
        setTimeout(() => setBouncing(null), 600);
      }, 500);
    } else {
      OASound.miss();
      setTimeout(() => {
        setHearts(h => Math.max(0, h - 1));
        setFlipped([]);
      }, 900);
    }
  }, [flipped]);

  React.useEffect(() => {
    if (matchedCount === totalPairs) {
      const acc = Math.round((totalPairs / Math.max(1, taps)) * 100);
      setTimeout(() => onComplete({ taps, hearts, accuracy: acc }), 700);
    }
  }, [matchedCount]);

  const handleTap = (i) => {
    if (flipped.length >= 2) return;
    if (flipped.includes(i)) return;
    if (matched[deck[i].id]) return;
    OASound.tap();
    setFlipped(f => [...f, i]);
  };

  const progress = matchedCount / totalPairs;

  return (
    <div style={{ minHeight: '100dvh', background: 'linear-gradient(180deg, #DDE9DF 0%, #EDE6DC 60%)', display: 'flex', flexDirection: 'column', paddingTop: 'max(20px, env(safe-area-inset-top))' }}>
      <GameTopBar onExit={onExit} progress={progress} hearts={hearts} />

      <div style={{ padding: '0 22px 12px', display:'flex', alignItems:'flex-end', gap: 14 }}>
        <Mascot size={64} mood={flipped.length === 2 ? 'think' : 'happy'} />
        <div style={{ flex: 1 }}>
          <SpeechBubble accent={OA_THEME.sage}>
            <b style={{ color: OA_THEME.sageDeep }}>Cocokkan kartu</b> yang sama. Tidak terburu-buru ya.
          </SpeechBubble>
        </div>
      </div>

      <div style={{
        flex: 1, padding: '8px 22px 22px',
        display: 'grid',
        gridTemplateColumns: 'repeat(3, 1fr)',
        gap: 12,
        minHeight: 480,
      }}>
        {deck.map((c, i) => {
          const isFlipped = flipped.includes(i) || matched[c.id];
          const isMatched = matched[c.id];
          return (
            <button key={c.key} onClick={() => handleTap(i)} className="oa-no-tap" aria-label={isFlipped ? `Kartu ${c.e}` : 'Kartu tertutup'} style={{
              border: 'none', padding: 0, background: 'transparent', cursor: 'pointer',
              perspective: 800,
              aspectRatio: '3/4',
              animation: isMatched && bouncing === c.id ? 'oaPop .6s' : 'none',
            }}>
              <div style={{
                width: '100%', height: '100%', position: 'relative',
                transformStyle: 'preserve-3d',
                transition: 'transform .5s cubic-bezier(.2,.7,.2,1)',
                transform: isFlipped ? 'rotateY(180deg)' : 'none',
              }}>
                <div style={{
                  position:'absolute', inset:0,
                  borderRadius: 18,
                  background: `linear-gradient(160deg, ${OA_THEME.sky}, ${OA_THEME.skyDeep})`,
                  border: `2px solid ${OA_THEME.skyDeep}`,
                  boxShadow: `0 4px 0 ${OA_THEME.skyDeep}, 0 1px 0 rgba(255,255,255,.4) inset`,
                  display:'flex', alignItems:'center', justifyContent:'center',
                  backfaceVisibility: 'hidden', WebkitBackfaceVisibility: 'hidden',
                }}>
                  <div style={{
                    width: 44, height: 44, borderRadius: '50%',
                    border: '3px dashed rgba(255,255,255,0.55)',
                    display:'flex', alignItems:'center', justifyContent:'center',
                    color: '#fff', fontFamily: 'Lora, serif', fontStyle: 'italic', fontSize: 28, fontWeight: 600,
                  }}>O</div>
                </div>
                <div style={{
                  position:'absolute', inset:0,
                  borderRadius: 18,
                  background: isMatched ? '#EAF1EB' : OA_THEME.card,
                  border: `2px solid ${isMatched ? OA_THEME.sage : OA_THEME.line}`,
                  boxShadow: isMatched ? `0 4px 0 ${OA_THEME.sage}` : `0 4px 0 ${OA_THEME.line}`,
                  display:'flex', alignItems:'center', justifyContent:'center',
                  fontSize: 56,
                  backfaceVisibility: 'hidden', WebkitBackfaceVisibility: 'hidden',
                  transform: 'rotateY(180deg)',
                }}>
                  {c.e}
                </div>
              </div>
            </button>
          );
        })}
      </div>
    </div>
  );
}

window.MemoryGame = MemoryGame;
window.GameTopBar = GameTopBar;
