/* global React, window, Vex */
// Exercise: see a bar of notes, pick the time signature.

(function () {
  'use strict';
  window.PracticeLab = window.PracticeLab || {};
  window.PracticeLab.ui = window.PracticeLab.ui || {};

  function vexAvailable() {
    return !!(typeof window.Vex !== 'undefined' && window.Vex && window.Vex.Flow);
  }

  // Render a bar of the given pattern WITHOUT showing the time signature.
  // The user's job is to deduce the time signature from the rhythm.
  function renderHiddenBar(containerEl, pattern, tsId) {
    if (!vexAvailable() || !containerEl) return;
    containerEl.innerHTML = '';
    try {
      var VF = window.Vex.Flow;
      var ts = window.PracticeLab.rhythm.getTimeSig(tsId);
      if (!ts) return;
      var width = 320;
      var height = 130;
      var renderer = new VF.Renderer(containerEl, VF.Renderer.Backends.SVG);
      renderer.resize(width, height);
      var ctx = renderer.getContext();
      var stave = new VF.Stave(8, 14, width - 16);
      stave.addClef('treble');
      // Deliberately NO addTimeSignature — that's the answer.
      stave.setContext(ctx).draw();

      var vexNotes = pattern.events.map(function (e) {
        var info = window.PracticeLab.rhythm.lookup(e.value);
        if (!info) return null;
        return new VF.StaveNote({
          clef: 'treble',
          keys: ['b/4'],
          duration: info.vex,
          autoStem: true,
        });
      }).filter(function (n) { return n; });

      var voice = new VF.Voice({ num_beats: ts.num, beat_value: ts.den });
      voice.setStrict(false);
      voice.addTickables(vexNotes);
      new VF.Formatter().joinVoices([voice]).format([voice], width - 60);
      voice.draw(ctx, stave);
    } catch (e) {
      try { containerEl.textContent = 'Could not render bar.'; } catch (e2) {}
    }
  }

  // Pick a random (timeSig, pattern) pair.
  function pickRandom() {
    var rhythm = window.PracticeLab.rhythm;
    // V2 pool: 4/4, 3/4, 6/8 — the trio that 90% of music sits in.
    // 2/4 is in the data layer but deferred to a higher-difficulty
    // tier in a later slice.
    var tsIds = ['4/4', '3/4', '6/8'];
    var tsId = tsIds[Math.floor(Math.random() * tsIds.length)];
    var pattern = rhythm.randomPattern(tsId);
    return { tsId: tsId, pattern: pattern };
  }

  var ANSWER_OPTIONS = ['4/4', '3/4', '6/8'];

  var ExerciseTimeSignature = function (props) {
    const onAttempt = props.onAttempt || function () {};
    const onNext = props.onNext || function () {};

    const [prompt, setPrompt] = React.useState(null);
    const [picked, setPicked] = React.useState(null);
    const [vexReady, setVexReady] = React.useState(vexAvailable());
    const barRef = React.useRef(null);
    const submittedRef = React.useRef(false);

    React.useEffect(function () {
      if (vexReady) return;
      const id = setInterval(function () {
        if (vexAvailable()) { setVexReady(true); clearInterval(id); }
      }, 100);
      return function () { clearInterval(id); };
    }, [vexReady]);

    React.useEffect(function () {
      if (!prompt) setPrompt(pickRandom());
    }, [prompt]);

    React.useEffect(function () {
      if (!vexReady || !prompt || !prompt.pattern) return;
      renderHiddenBar(barRef.current, prompt.pattern, prompt.tsId);
    }, [vexReady, prompt]);

    const handlePlay = React.useCallback(function () {
      if (!prompt || !prompt.pattern) return Promise.resolve();
      var timeline = window.PracticeLab.rhythm.patternToTimeline(prompt.pattern);
      // BPM choice: 90 for 4/4 + 3/4, 130 for 6/8 (eighth-note feel).
      var bpm = (prompt.tsId === '6/8') ? 130 : 90;
      return window.PracticeLab.audio.playRhythm(timeline, bpm, { withMetronome: true });
    }, [prompt]);

    const handlePick = React.useCallback(function (option) {
      if (picked || !prompt) return;
      setPicked(option);
      if (submittedRef.current) return;
      submittedRef.current = true;
      onAttempt({
        exerciseType: 'time_signature',
        difficulty: props.difficulty || 'beginner',
        prompt: { tsId: prompt.tsId, patternId: prompt.pattern && prompt.pattern.id },
        userAnswer: option,
        correctAnswer: prompt.tsId,
        wasCorrect: option === prompt.tsId,
      });
    }, [picked, prompt, props.difficulty, onAttempt]);

    const handleNext = React.useCallback(function () {
      submittedRef.current = false;
      setPicked(null);
      setPrompt(null);
      onNext();
    }, [onNext]);

    const PRIMARY = 'oklch(35% 0.16 265)';
    const SUCCESS = 'oklch(48% 0.13 152)';
    const ERROR   = 'oklch(58% 0.18 25)';
    const SURFACE_BD = 'oklch(92% 0.012 265)';

    return (
      <div>
        <div style={{ fontSize: 12, color: 'oklch(55% 0.04 265)', fontWeight: 700, letterSpacing: '0.05em', textTransform: 'uppercase', marginBottom: 8 }}>
          Identify the time signature
        </div>
        <div ref={barRef} style={{ display: 'flex', justifyContent: 'center', minHeight: 130 }} />
        <div style={{ marginTop: 8, display: 'flex', justifyContent: 'center' }}>
          <button
            onClick={handlePlay}
            disabled={!prompt}
            style={{
              padding: '8px 16px',
              borderRadius: 8,
              border: '1px solid ' + PRIMARY,
              background: '#fff',
              color: PRIMARY,
              fontSize: 13,
              fontWeight: 700,
              cursor: prompt ? 'pointer' : 'default',
              fontFamily: "'Plus Jakarta Sans', sans-serif",
            }}
          >▶ Play with metronome</button>
        </div>
        <div style={{ marginTop: 18, display: 'flex', gap: 10, flexWrap: 'wrap', justifyContent: 'center' }}>
          {ANSWER_OPTIONS.map(function (opt) {
            var isCorrect = picked && opt === prompt.tsId;
            var isWrongPick = picked === opt && opt !== prompt.tsId;
            var bg = '#fff', color = 'oklch(28% 0.05 265)', border = SURFACE_BD;
            if (isCorrect) { bg = SUCCESS; color = '#fff'; border = SUCCESS; }
            else if (isWrongPick) { bg = ERROR; color = '#fff'; border = ERROR; }
            return (
              <button
                key={opt}
                onClick={function () { handlePick(opt); }}
                disabled={!!picked}
                style={{
                  padding: '14px 24px',
                  borderRadius: 12,
                  border: '1px solid ' + border,
                  background: bg,
                  color: color,
                  fontSize: 22,
                  fontWeight: 700,
                  minWidth: 80,
                  cursor: picked ? 'default' : 'pointer',
                  fontFamily: "'Plus Jakarta Sans', sans-serif",
                }}
              >{opt}</button>
            );
          })}
        </div>
        {picked && (
          <div style={{ marginTop: 18, display: 'flex', justifyContent: 'center' }}>
            <button
              onClick={handleNext}
              style={{
                padding: '11px 22px',
                borderRadius: 10,
                border: 'none',
                background: PRIMARY,
                color: '#fff',
                fontSize: 14,
                fontWeight: 700,
                cursor: 'pointer',
                fontFamily: "'Plus Jakarta Sans', sans-serif",
              }}
            >Next →</button>
          </div>
        )}
      </div>
    );
  };

  window.PracticeLab.ui.ExerciseTimeSignature = ExerciseTimeSignature;
})();
