/* global React, window, Vex */
// Lesson 1.2 — The bass clef (F clef).
// Body-only — rendered inside <LessonPage>.

(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);
  }

  // Bass clef lines (bottom→top): G2 B2 D3 F3 A3
  // Bass clef spaces (bottom→top): A2 C3 E3 G3
  var LINE_NOTES = [
    { letter: 'G', octave: 2, midi: 43, label: 'G' },
    { letter: 'B', octave: 2, midi: 47, label: 'B' },
    { letter: 'D', octave: 3, midi: 50, label: 'D' },
    { letter: 'F', octave: 3, midi: 53, label: 'F' },
    { letter: 'A', octave: 3, midi: 57, label: 'A' },
  ];
  var SPACE_NOTES = [
    { letter: 'A', octave: 2, midi: 45, label: 'A' },
    { letter: 'C', octave: 3, midi: 48, label: 'C' },
    { letter: 'E', octave: 3, midi: 52, label: 'E' },
    { letter: 'G', octave: 3, midi: 55, label: 'G' },
  ];

  function renderBassSequence(containerEl, notes) {
    if (!vexAvailable() || !containerEl) return;
    containerEl.innerHTML = '';
    try {
      var VF = window.Vex.Flow;
      var width = Math.max(280, notes.length * 46 + 80);
      var height = 130;
      var renderer = new VF.Renderer(containerEl, VF.Renderer.Backends.SVG);
      renderer.resize(width, height);
      var ctx = renderer.getContext();
      ctx.setFont('Plus Jakarta Sans', 11);
      var stave = new VF.Stave(8, 16, width - 16);
      stave.addClef('bass');
      stave.setContext(ctx).draw();

      var vexNotes = notes.map(function (n) {
        return new VF.StaveNote({
          clef: 'bass',
          keys: [n.letter.toLowerCase() + '/' + n.octave],
          duration: 'q',
          autoStem: true,
        });
      });
      var voice = new VF.Voice({ num_beats: notes.length, beat_value: 4 });
      voice.setStrict(false);
      voice.addTickables(vexNotes);
      new VF.Formatter().joinVoices([voice]).format([voice], width - 80);
      voice.draw(ctx, stave);
    } catch (e) {
      try { containerEl.textContent = 'Could not render staff.'; } catch (e2) {}
    }
  }

  var LessonBassClef = function () {
    const Bits = window.PracticeLab.ui.LessonBits;
    if (!Bits) return null;
    const Section = Bits.Section;
    const DemoBox = Bits.DemoBox;
    const PlayButton = Bits.PlayButton;
    const Mnemonic = Bits.Mnemonic;
    const audio = window.PracticeLab.audio;

    const linesRef = React.useRef(null);
    const spacesRef = React.useRef(null);
    const [vexReady, setVexReady] = React.useState(vexAvailable());

    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 (!vexReady) return;
      renderBassSequence(linesRef.current, LINE_NOTES);
      renderBassSequence(spacesRef.current, SPACE_NOTES);
    }, [vexReady]);

    const playSeq = React.useCallback(async function (notes) {
      for (var i = 0; i < notes.length; i++) {
        await audio.playNote(notes[i].midi, 480);
      }
    }, [audio]);

    return (
      <div>
        <Section heading="The bass clef (F clef)">
          The bass clef is used for lower-pitched instruments — piano left hand, cello, bassoon, bass guitar, tuba. The symbol is the <strong>F clef</strong>: the two dots sit either side of the second line from the top, marking that line as <strong>F</strong>. (Treble = G clef, bass = F clef. Easy to mix them up — the dots are the giveaway.)
        </Section>

        <Section heading="Different note names from the treble clef">
          The lines and spaces of the bass clef spell out <em>different</em> letters than the treble clef. Don't try to reuse the treble mnemonics — they don't work here. Bass clef has its own.
          <DemoBox label="The 5 lines of the bass clef · bottom → top">
            <div ref={linesRef} style={{ overflowX: 'auto' }} />
            <div style={{ marginTop: 10, display: 'flex', gap: 10, flexWrap: 'wrap', alignItems: 'center' }}>
              <PlayButton label="Play the lines" onPlay={function () { return playSeq(LINE_NOTES); }} />
              <span style={{ fontSize: 13, color: 'oklch(40% 0.04 265)' }}>G — B — D — F — A</span>
            </div>
            <Mnemonic>
              <strong>G</strong>ood <strong>B</strong>oys <strong>D</strong>o <strong>F</strong>ine <strong>A</strong>lways.
            </Mnemonic>
          </DemoBox>
          <DemoBox label="The 4 spaces of the bass clef · bottom → top">
            <div ref={spacesRef} style={{ overflowX: 'auto' }} />
            <div style={{ marginTop: 10, display: 'flex', gap: 10, flexWrap: 'wrap', alignItems: 'center' }}>
              <PlayButton label="Play the spaces" onPlay={function () { return playSeq(SPACE_NOTES); }} />
              <span style={{ fontSize: 13, color: 'oklch(40% 0.04 265)' }}>A — C — E — G</span>
            </div>
            <Mnemonic>
              <strong>A</strong>ll <strong>C</strong>ows <strong>E</strong>at <strong>G</strong>rass.
            </Mnemonic>
          </DemoBox>
        </Section>

        <Section heading="Middle C is the bridge" last>
          Middle C sits one ledger line <em>above</em> the bass clef staff and one ledger line <em>below</em> the treble clef staff. That's how the two staves connect on a piano: bass clef is the lower half, treble clef the upper half, and middle C is the dividing line.
        </Section>
      </div>
    );
  };

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