/* global React, window */
// Violin Lab — top-level container component.
//
// Two sections:
//   - Lessons    : 5 instructional pages (anatomy, tuning, first
//                  position, bowing, posture).
//   - Practice   : 4 ear-training / fingerboard exercises with
//                  difficulty selector + session HUD + lifetime stats.
//
// Mounted from admin-dashboard.jsx as
// <window.ViolinLab.ui.ViolinLab />.

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

  const MODES = [
    { id: 'lessons',  label: 'Lessons' },
    { id: 'practice', label: 'Practice' },
  ];

  const LESSONS = [
    { id: 'anatomy',        label: 'Parts of the violin' },
    { id: 'tuning',         label: 'Standard tuning' },
    { id: 'first_position', label: 'First position notes' },
    { id: 'bowing',         label: 'Bowing direction' },
    { id: 'posture',        label: 'Holding violin & bow' },
  ];

  const EXERCISES = [
    { id: 'mixed',             label: 'Mixed' },
    { id: 'open_string',       label: 'Open string' },
    { id: 'fingerboard_note',  label: 'Fingerboard note' },
    { id: 'interval_fifths',   label: 'Interval' },
    { id: 'tuning',            label: 'Tune by ear' },
  ];

  const DIFFICULTIES = [
    { id: 'beginner',     label: 'Beginner' },
    { id: 'intermediate', label: 'Intermediate' },
    { id: 'advanced',     label: 'Advanced' },
  ];

  const MIXED_POOL = ['open_string', 'fingerboard_note', 'interval_fifths', 'tuning'];

  function pickNextExercise(currentExercise, lastInMixed) {
    if (currentExercise !== 'mixed') return currentExercise;
    const pool = MIXED_POOL.filter(function (id) { return id !== lastInMixed; });
    return pool[Math.floor(Math.random() * pool.length)];
  }

  const Pill = function (props) {
    const active = !!props.active;
    return (
      <button
        onClick={props.onClick}
        style={{
          padding: '8px 16px',
          borderRadius: 999,
          border: '1px solid ' + (active ? 'oklch(35% 0.16 265)' : 'oklch(88% 0.02 265)'),
          background: active ? 'oklch(35% 0.16 265)' : '#fff',
          color: active ? '#fff' : 'oklch(28% 0.05 265)',
          fontSize: 13,
          fontWeight: 600,
          cursor: 'pointer',
          fontFamily: "'Plus Jakarta Sans', sans-serif",
          transition: 'all 0.14s',
          whiteSpace: 'nowrap',
        }}
      >{props.children}</button>
    );
  };

  const StatTile = function (props) {
    return (
      <div style={{
        flex: 1,
        minWidth: 110,
        background: '#fff',
        border: '1px solid oklch(92% 0.012 265)',
        borderRadius: 12,
        padding: '14px 18px',
      }}>
        <div style={{ fontSize: 11, color: 'oklch(55% 0.04 265)', fontWeight: 600, letterSpacing: '0.04em', textTransform: 'uppercase', marginBottom: 6 }}>{props.label}</div>
        <div style={{ fontSize: 22, fontWeight: 700, color: 'oklch(18% 0.03 265)', lineHeight: 1.1 }}>{props.value}</div>
        {props.sub && <div style={{ fontSize: 11, color: 'oklch(55% 0.04 265)', marginTop: 4 }}>{props.sub}</div>}
      </div>
    );
  };

  const EnableSoundSplash = function (props) {
    return (
      <div style={{
        background: 'oklch(96% 0.02 80)',
        border: '1px solid oklch(85% 0.07 80)',
        borderRadius: 12,
        padding: '18px 20px',
        marginBottom: 18,
        display: 'flex',
        alignItems: 'center',
        gap: 14,
        flexWrap: 'wrap',
      }}>
        <svg aria-hidden="true" width="26" height="26" viewBox="0 0 24 24" fill="none" stroke="oklch(45% 0.13 80)" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
          <polygon points="11 5 6 9 2 9 2 15 6 15 11 19 11 5"/>
          <path d="M15.54 8.46a5 5 0 0 1 0 7.07"/>
          <path d="M19.07 4.93a10 10 0 0 1 0 14.14"/>
        </svg>
        <div style={{ flex: 1, minWidth: 200 }}>
          <div style={{ fontSize: 14, fontWeight: 700, color: 'oklch(22% 0.06 265)', marginBottom: 3 }}>Enable sound</div>
          <div style={{ fontSize: 12.5, color: 'oklch(40% 0.04 265)' }}>Browsers require a click before playing audio. One tap and we're set.</div>
        </div>
        <button
          onClick={props.onEnable}
          style={{
            padding: '10px 18px',
            borderRadius: 10,
            border: 'none',
            background: 'oklch(35% 0.16 265)',
            color: '#fff',
            fontSize: 13,
            fontWeight: 700,
            cursor: 'pointer',
            fontFamily: "'Plus Jakarta Sans', sans-serif",
          }}
        >Enable sound</button>
      </div>
    );
  };

  const ViolinLab = function () {
    const [mode, setMode] = React.useState('lessons');
    const [lesson, setLesson] = React.useState('anatomy');
    const [difficulty, setDifficulty] = React.useState('beginner');
    const [exercise, setExercise] = React.useState('mixed');
    const [activeExercise, setActiveExercise] = React.useState(null);
    const [audioReady, setAudioReady] = React.useState(false);

    const [sessionScore, setSessionScore] = React.useState({ correct: 0, total: 0 });
    const [streak, setStreak] = React.useState(0);
    const [stats, setStats] = React.useState({ totalAttempts: 0, accuracy: 0, bestStreak: 0 });

    const lastContext = React.useRef(null);
    const [roundKey, setRoundKey] = React.useState(0);

    React.useEffect(function () {
      setActiveExercise(function (prev) {
        return pickNextExercise(exercise, prev);
      });
    }, [exercise, roundKey]);

    React.useEffect(function () {
      const id = setInterval(function () {
        try { setAudioReady(window.ViolinLab.audio.isReady()); } catch (e) {}
      }, 500);
      return function () { clearInterval(id); };
    }, []);

    const refreshStats = React.useCallback(async function () {
      try {
        const s = await window.ViolinLab.db.getLifetimeStats();
        setStats(s);
      } catch (e) {}
    }, []);

    React.useEffect(function () { refreshStats(); }, [refreshStats]);

    const enableSound = React.useCallback(async function () {
      try { await window.ViolinLab.audio.resumeContext(); } catch (e) {}
      try { setAudioReady(window.ViolinLab.audio.isReady()); } catch (e) {}
    }, []);

    const handleAttempt = React.useCallback(async function (attempt) {
      lastContext.current = attempt;
      setSessionScore(function (prev) {
        return {
          correct: prev.correct + (attempt.wasCorrect ? 1 : 0),
          total: prev.total + 1,
        };
      });
      setStreak(function (prev) { return attempt.wasCorrect ? prev + 1 : 0; });
      try { await window.ViolinLab.db.recordAttempt(attempt); } catch (e) {}
      refreshStats();
    }, [refreshStats]);

    const handleNext = React.useCallback(function () {
      setRoundKey(function (k) { return k + 1; });
    }, []);

    const handlePickDifficulty = React.useCallback(function (d) {
      setDifficulty(d);
      setSessionScore({ correct: 0, total: 0 });
      setStreak(0);
      setRoundKey(function (k) { return k + 1; });
    }, []);

    const handlePickExercise = React.useCallback(function (e) {
      setExercise(e);
      setSessionScore({ correct: 0, total: 0 });
      setStreak(0);
      setRoundKey(function (k) { return k + 1; });
    }, []);

    const ExerciseComponent = (function () {
      switch (activeExercise) {
        case 'open_string':       return window.ViolinLab.ui.ExerciseOpenString;
        case 'fingerboard_note':  return window.ViolinLab.ui.ExerciseFingerboardNote;
        case 'interval_fifths':   return window.ViolinLab.ui.ExerciseIntervalFifths;
        case 'tuning':            return window.ViolinLab.ui.ExerciseTuning;
        default:                  return null;
      }
    })();

    const LessonComponent = (function () {
      switch (lesson) {
        case 'anatomy':        return window.ViolinLab.ui.LessonAnatomy;
        case 'tuning':         return window.ViolinLab.ui.LessonTuning;
        case 'first_position': return window.ViolinLab.ui.LessonFirstPosition;
        case 'bowing':         return window.ViolinLab.ui.LessonBowing;
        case 'posture':        return window.ViolinLab.ui.LessonPosture;
        default:               return null;
      }
    })();

    const showAudioSplash = mode === 'practice' && !audioReady && (
      activeExercise === 'open_string' ||
      activeExercise === 'fingerboard_note' ||
      activeExercise === 'interval_fifths' ||
      activeExercise === 'tuning'
    );

    return (
      <div style={{ fontFamily: "'Plus Jakarta Sans', sans-serif", maxWidth: 1000, margin: '0 auto', paddingBottom: 80 }}>
        {/* Beta banner */}
        <div style={{
          background: 'oklch(96% 0.04 265)',
          border: '1px solid oklch(85% 0.06 265)',
          color: 'oklch(28% 0.1 265)',
          borderRadius: 12,
          padding: '12px 16px',
          fontSize: 12.5,
          marginBottom: 16,
          display: 'flex',
          alignItems: 'center',
          gap: 10,
          flexWrap: 'wrap',
        }}>
          <strong style={{ fontWeight: 700 }}>Beta — admin only.</strong>
          <span style={{ opacity: 0.85 }}>Violin lessons + practice exercises. Microphone-based playing detection coming later.</span>
        </div>

        {/* Mode toggle (Lessons vs Practice) */}
        <div style={{ display: 'flex', gap: 8, marginBottom: 18, padding: 4, background: 'oklch(96% 0.005 265)', borderRadius: 12, border: '1px solid oklch(92% 0.012 265)', width: 'fit-content' }}>
          {MODES.map(function (m) {
            const on = mode === m.id;
            return (
              <button
                key={m.id}
                onClick={function () { setMode(m.id); }}
                style={{
                  padding: '8px 18px',
                  borderRadius: 8,
                  border: 'none',
                  background: on ? '#fff' : 'transparent',
                  color: on ? 'oklch(22% 0.06 265)' : 'oklch(45% 0.04 265)',
                  fontSize: 13,
                  fontWeight: 700,
                  cursor: 'pointer',
                  fontFamily: "'Plus Jakarta Sans', sans-serif",
                  boxShadow: on ? '0 1px 3px rgba(0,0,0,0.08)' : 'none',
                  transition: 'all 0.14s',
                }}
              >{m.label}</button>
            );
          })}
        </div>

        {mode === 'lessons' && (
          <div>
            <div style={{ marginBottom: 14 }}>
              <div style={{ fontSize: 11, color: 'oklch(55% 0.04 265)', fontWeight: 600, letterSpacing: '0.04em', textTransform: 'uppercase', marginBottom: 8 }}>Lesson</div>
              <div style={{ display: 'flex', flexWrap: 'wrap', gap: 8 }}>
                {LESSONS.map(function (l) {
                  return (
                    <Pill key={l.id} active={lesson === l.id} onClick={function () { setLesson(l.id); }}>{l.label}</Pill>
                  );
                })}
              </div>
            </div>
            <div style={{
              background: '#fff',
              border: '1px solid oklch(92% 0.012 265)',
              borderRadius: 14,
              padding: 22,
              minHeight: 320,
            }}>
              {LessonComponent && <LessonComponent />}
              {!LessonComponent && (
                <div style={{ padding: 40, textAlign: 'center', color: 'oklch(55% 0.04 265)', fontSize: 13 }}>Loading lesson…</div>
              )}
            </div>
          </div>
        )}

        {mode === 'practice' && (
          <div>
            {/* Controls */}
            <div style={{ display: 'flex', flexDirection: 'column', gap: 12, marginBottom: 18 }}>
              <div>
                <div style={{ fontSize: 11, color: 'oklch(55% 0.04 265)', fontWeight: 600, letterSpacing: '0.04em', textTransform: 'uppercase', marginBottom: 8 }}>Difficulty</div>
                <div style={{ display: 'flex', flexWrap: 'wrap', gap: 8 }}>
                  {DIFFICULTIES.map(function (d) {
                    return (
                      <Pill key={d.id} active={difficulty === d.id} onClick={function () { handlePickDifficulty(d.id); }}>{d.label}</Pill>
                    );
                  })}
                </div>
              </div>
              <div>
                <div style={{ fontSize: 11, color: 'oklch(55% 0.04 265)', fontWeight: 600, letterSpacing: '0.04em', textTransform: 'uppercase', marginBottom: 8 }}>Exercise</div>
                <div style={{ display: 'flex', flexWrap: 'wrap', gap: 8 }}>
                  {EXERCISES.map(function (e) {
                    return (
                      <Pill key={e.id} active={exercise === e.id} onClick={function () { handlePickExercise(e.id); }}>{e.label}</Pill>
                    );
                  })}
                </div>
              </div>
            </div>

            {/* Session HUD */}
            <div style={{ display: 'flex', gap: 10, marginBottom: 16, flexWrap: 'wrap' }}>
              <StatTile label="This session" value={sessionScore.total === 0 ? '0 / 0' : sessionScore.correct + ' / ' + sessionScore.total} sub={sessionScore.total === 0 ? 'No attempts yet' : Math.round((sessionScore.correct / sessionScore.total) * 100) + '% correct'} />
              <StatTile label="Current streak" value={String(streak)} sub={streak === 0 ? 'Get one right' : 'In a row'} />
            </div>

            {showAudioSplash && <EnableSoundSplash onEnable={enableSound} />}

            {/* Exercise card */}
            <div style={{
              background: '#fff',
              border: '1px solid oklch(92% 0.012 265)',
              borderRadius: 14,
              padding: 22,
              minHeight: 320,
            }}>
              {!ExerciseComponent && (
                <div style={{ padding: 40, textAlign: 'center', color: 'oklch(55% 0.04 265)', fontSize: 13 }}>Loading exercise…</div>
              )}
              {ExerciseComponent && (
                <ExerciseComponent
                  key={roundKey + ':' + activeExercise + ':' + difficulty}
                  difficulty={difficulty}
                  onAttempt={handleAttempt}
                  onNext={handleNext}
                />
              )}
            </div>

            {/* Lifetime stats footer */}
            <div style={{
              marginTop: 22,
              padding: '14px 18px',
              background: 'oklch(98% 0.005 265)',
              border: '1px solid oklch(92% 0.012 265)',
              borderRadius: 12,
              display: 'flex',
              gap: 22,
              flexWrap: 'wrap',
            }}>
              <div style={{ fontSize: 11, color: 'oklch(55% 0.04 265)', fontWeight: 700, letterSpacing: '0.04em', textTransform: 'uppercase', alignSelf: 'center' }}>Lifetime</div>
              <div><strong style={{ fontWeight: 700 }}>{stats.totalAttempts}</strong> <span style={{ color: 'oklch(55% 0.04 265)', fontSize: 12 }}>attempts</span></div>
              <div><strong style={{ fontWeight: 700 }}>{stats.accuracy}%</strong> <span style={{ color: 'oklch(55% 0.04 265)', fontSize: 12 }}>accuracy</span></div>
              <div><strong style={{ fontWeight: 700 }}>{stats.bestStreak}</strong> <span style={{ color: 'oklch(55% 0.04 265)', fontSize: 12 }}>best streak</span></div>
            </div>
          </div>
        )}

        {/* Floating feedback widget (works in both modes).
            exerciseType is constrained on the DB side to null or one
            of the 4 exercise ids — so in Lessons mode we pass null and
            stash the lesson id inside exerciseContext (which is a free
            jsonb column). */}
        {window.ViolinLab.ui.FeedbackWidget && (
          <window.ViolinLab.ui.FeedbackWidget
            exerciseType={mode === 'practice' ? activeExercise : null}
            getContext={function () {
              if (mode === 'practice') return lastContext.current;
              return { mode: 'lesson', lesson: lesson };
            }}
          />
        )}
      </div>
    );
  };

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