/* global React, window */
// Violin Lab — SVG fingerboard renderer.
//
// Props:
//   - highlight  { string: 'G'|'D'|'A'|'E', finger: 0..4 } (optional)
//   - showLabels boolean — render G/D/A/E labels at the nut end
//   - showFingerNumbers boolean — render 0..4 along the side
//   - height  number — total SVG height in px (width auto from aspect)
//   - revealNote boolean — when true and `highlight` is set, draw the
//     note's letter inside the finger dot (used by lessons; exercises
//     keep it hidden so the student must read the position).
//
// The fingerboard is drawn with the NUT on the LEFT and strings running
// horizontally to the right. Strings, top to bottom: E A D G (highest
// pitch on top — same orientation as classical fingerings in print).

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

  // Strings TOP-DOWN in render order = E, A, D, G (highest pitch on top).
  const STRING_RENDER_ORDER = ['E', 'A', 'D', 'G'];

  const Fingerboard = function (props) {
    const showLabels = props.showLabels !== false;
    const showFingerNumbers = props.showFingerNumbers !== false;
    const revealNote = !!props.revealNote;
    const highlight = props.highlight || null;

    // SVG layout
    const padTop = 36;
    const padBottom = 28;
    const padLeft = 56;
    const padRight = 28;
    const stringSpacing = 28;
    const fingerSpacing = 80;

    const stringCount = 4;
    const fingerCount = 5; // 0..4

    const fbWidth = (fingerCount - 1) * fingerSpacing;
    const fbHeight = (stringCount - 1) * stringSpacing;

    const svgWidth = padLeft + fbWidth + padRight;
    const svgHeight = padTop + fbHeight + padBottom;

    // Y position for a string by id
    function stringY(stringId) {
      const idx = STRING_RENDER_ORDER.indexOf(stringId);
      return padTop + idx * stringSpacing;
    }
    function fingerX(finger) {
      return padLeft + finger * fingerSpacing;
    }

    // Pre-fetch first position notes for revealNote handling.
    const theory = window.ViolinLab && window.ViolinLab.theory;
    function noteAt(stringId, finger) {
      if (!theory) return '';
      const notes = theory.FIRST_POSITION[stringId];
      if (!notes) return '';
      const found = notes.find(function (n) { return n.finger === finger; });
      return found ? found.letter : '';
    }

    return (
      <div style={{ width: '100%', overflowX: 'auto', WebkitOverflowScrolling: 'touch' }}>
        <svg
          viewBox={'0 0 ' + svgWidth + ' ' + svgHeight}
          width="100%"
          style={{ maxWidth: svgWidth, height: 'auto', display: 'block', margin: '0 auto' }}
          role="img"
          aria-label="Violin fingerboard with finger positions"
        >
          {/* Fingerboard background — wood-coloured rectangle behind strings */}
          <rect
            x={padLeft - 18}
            y={padTop - 14}
            width={fbWidth + 36}
            height={fbHeight + 28}
            rx={6}
            fill="oklch(22% 0.04 50)"
          />

          {/* Nut (white bar at finger 0) */}
          <rect
            x={padLeft - 6}
            y={padTop - 12}
            width={6}
            height={fbHeight + 24}
            fill="oklch(96% 0.01 60)"
          />

          {/* Finger position guide lines (vertical, subtle) */}
          {Array.from({ length: fingerCount }).map(function (_, i) {
            if (i === 0) return null;
            return (
              <line
                key={'fg' + i}
                x1={fingerX(i)}
                y1={padTop - 10}
                x2={fingerX(i)}
                y2={padTop + fbHeight + 10}
                stroke="oklch(40% 0.02 50)"
                strokeWidth={1}
                strokeDasharray="2 3"
              />
            );
          })}

          {/* Strings */}
          {STRING_RENDER_ORDER.map(function (sid, idx) {
            const s = theory ? theory.STRINGS.find(function (st) { return st.id === sid; }) : null;
            const color = s ? s.color : '#fff';
            const y = padTop + idx * stringSpacing;
            // Thicker for lower strings (G thickest, E thinnest)
            const thickness = sid === 'G' ? 2.6 : sid === 'D' ? 2.2 : sid === 'A' ? 1.8 : 1.4;
            return (
              <g key={'s' + sid}>
                <line
                  x1={padLeft - 14}
                  y1={y}
                  x2={padLeft + fbWidth + 14}
                  y2={y}
                  stroke="oklch(90% 0.02 60)"
                  strokeWidth={thickness}
                  strokeLinecap="round"
                />
                {showLabels && (
                  <g>
                    <circle cx={padLeft - 32} cy={y} r={11} fill={color} />
                    <text
                      x={padLeft - 32}
                      y={y + 1}
                      fill="#fff"
                      fontSize={12}
                      fontWeight={700}
                      textAnchor="middle"
                      dominantBaseline="middle"
                      style={{ fontFamily: "'Plus Jakarta Sans', sans-serif" }}
                    >{sid}</text>
                  </g>
                )}
              </g>
            );
          })}

          {/* Finger position dots (only when highlight is set) */}
          {highlight && (
            <g>
              {(function () {
                const cx = fingerX(highlight.finger);
                const cy = stringY(highlight.string);
                return (
                  <g>
                    <circle cx={cx} cy={cy} r={14} fill="oklch(70% 0.18 80)" stroke="#fff" strokeWidth={2} />
                    {revealNote && (
                      <text
                        x={cx}
                        y={cy + 1}
                        fill="oklch(22% 0.06 80)"
                        fontSize={13}
                        fontWeight={800}
                        textAnchor="middle"
                        dominantBaseline="middle"
                        style={{ fontFamily: "'Plus Jakarta Sans', sans-serif" }}
                      >{noteAt(highlight.string, highlight.finger)}</text>
                    )}
                  </g>
                );
              })()}
            </g>
          )}

          {/* Finger number labels along the top */}
          {showFingerNumbers && Array.from({ length: fingerCount }).map(function (_, i) {
            return (
              <text
                key={'fn' + i}
                x={fingerX(i)}
                y={padTop - 18}
                fill="oklch(45% 0.04 265)"
                fontSize={11}
                fontWeight={700}
                textAnchor="middle"
                style={{ fontFamily: "'Plus Jakarta Sans', sans-serif", letterSpacing: '0.04em', textTransform: 'uppercase' }}
              >{i === 0 ? 'OPEN' : 'F' + i}</text>
            );
          })}
        </svg>
      </div>
    );
  };

  window.ViolinLab.ui.Fingerboard = Fingerboard;
})();
