/* global React, window */
// Drums Lab — top-level container.
//
// Two top-level sections:
//   - Lessons (anatomy, counting, basic beat, fills, rudiments)
//   - Practice (4 exercises with difficulty pills + session HUD + stats)
//
// Mirrors the guitar-lab structure exactly so the admin-side feel is
// consistent across instruments.

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

  const LESSONS = [
    { id: 'anatomy',   label: 'Parts of the drum kit', component: 'LessonAnatomy' },
    { id: 'counting',  label: 'Counting & subdivisions', component: 'LessonCounting' },
    { id: 'basic',     label: 'The basic rock beat',   component: 'LessonBasicBeat' },
    { id: 'fills',     label: 'Fills',                 component: 'LessonFills' },
    { id: 'rudiments', label: 'The foundational rudiments', component: 'LessonRudiments' },
  ];

  const EXERCISES = [
    { id: 'mixed',       label: 'Mixed' },
    { id: 'kit_name',    label: 'Kit piece by sound' },
    { id: 'beat_match',  label: 'Beat match' },
    { id: 'count_hits',  label: 'Count hits' },
    { id: 'rudiment',    label: 'Rudiment ID' },
  ];

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

  const MIXED_POOL = ['kit_name', 'beat_match', 'count_hits', 'rudiment'];

  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 ModeTab = function (props) {
    const active = !!props.active;
    return (
      <button
        onClick={props.onClick}
        style={{
          padding: '10px 22px',
          borderRadius: 10,
          border: 'none',
          background: active ? 'oklch(35% 0.16 265)' : 'transparent',
          color: active ? '#fff' : 'oklch(35% 0.04 265)',
          fontSize: 13.5,
          fontWeight: 700,
          cursor: 'pointer',
          fontFamily: "'Plus Jakarta Sans', sans-serif",
        }}
      >{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 PracticeMode = function () {
    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.DrumsLab.audio.isReady()); } catch (e) {}
      }, 500);
      return function () { clearInterval(id); };
    }, []);

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

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

    const enableSound = React.useCallback(async function () {
      try { await window.DrumsLab.audio.resumeContext(); } catch (e) {}
      try { setAudioReady(window.DrumsLab.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.DrumsLab.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 'kit_name':   return window.DrumsLab.ui.ExerciseKitName;
        case 'beat_match': return window.DrumsLab.ui.ExerciseBeatMatch;
        case 'count_hits': return window.DrumsLab.ui.ExerciseCountHits;
        case 'rudiment':   return window.DrumsLab.ui.ExerciseRudiment;
        default:           return null;
      }
    })();

    // Every drums exercise plays audio, so always show the splash until
    // the AudioContext is running.
    const showAudioSplash = !audioReady;

    return (
      <div>
        <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>

        <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} />}

        <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>

        <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>

        {/* FeedbackWidget mounted INSIDE PracticeMode so it sees the
            activeExercise id (one of the CHECK-constraint-valid values)
            and the actual lastContext written by handleAttempt. */}
        {window.DrumsLab.ui.FeedbackWidget && (
          <window.DrumsLab.ui.FeedbackWidget
            exerciseType={activeExercise || null}
            getContext={function () { return lastContext.current; }}
          />
        )}
      </div>
    );
  };

  const LessonsMode = function () {
    const [activeLessonId, setActiveLessonId] = React.useState('anatomy');
    const activeLesson = LESSONS.find(function (l) { return l.id === activeLessonId; });
    const LessonComponent = activeLesson && window.DrumsLab.ui[activeLesson.component];

    return (
      <div style={{ display: 'grid', gridTemplateColumns: 'minmax(180px, 220px) 1fr', gap: 22 }}>
        <nav style={{ display: 'flex', flexDirection: 'column', gap: 4, position: 'sticky', top: 16, alignSelf: 'flex-start' }}>
          {LESSONS.map(function (l, i) {
            const active = l.id === activeLessonId;
            return (
              <button
                key={l.id}
                onClick={function () { setActiveLessonId(l.id); }}
                style={{
                  textAlign: 'left',
                  padding: '10px 12px',
                  borderRadius: 8,
                  border: 'none',
                  background: active ? 'oklch(94% 0.04 265)' : 'transparent',
                  color: active ? 'oklch(22% 0.1 265)' : 'oklch(35% 0.04 265)',
                  fontSize: 13.5,
                  fontWeight: active ? 700 : 500,
                  cursor: 'pointer',
                  fontFamily: "'Plus Jakarta Sans', sans-serif",
                }}
              >
                <span style={{ display: 'inline-block', width: 20, color: active ? 'oklch(35% 0.16 265)' : 'oklch(55% 0.04 265)', fontWeight: 700 }}>{i + 1}.</span>
                {l.label}
              </button>
            );
          })}
        </nav>

        <div style={{ background: '#fff', border: '1px solid oklch(92% 0.012 265)', borderRadius: 14, padding: 22 }}>
          {LessonComponent ? <LessonComponent /> : (
            <div style={{ padding: 40, textAlign: 'center', color: 'oklch(55% 0.04 265)', fontSize: 13 }}>Loading lesson…</div>
          )}
        </div>

        {/* Lesson-mode feedback widget. exerciseType='lesson' is in the
            drums_feedback CHECK constraint. Context records which lesson
            was active when the user opened the widget. */}
        {window.DrumsLab.ui.FeedbackWidget && (
          <window.DrumsLab.ui.FeedbackWidget
            exerciseType="lesson"
            getContext={function () { return { lesson_id: activeLessonId }; }}
          />
        )}
      </div>
    );
  };

  const MobileLessonsMode = function () {
    const [activeLessonId, setActiveLessonId] = React.useState('anatomy');
    const activeLesson = LESSONS.find(function (l) { return l.id === activeLessonId; });
    const LessonComponent = activeLesson && window.DrumsLab.ui[activeLesson.component];

    return (
      <div style={{ display: 'flex', flexDirection: 'column', gap: 16 }}>
        <div style={{ display: 'flex', flexWrap: 'wrap', gap: 6 }}>
          {LESSONS.map(function (l, i) {
            return (
              <Pill key={l.id} active={activeLessonId === l.id} onClick={function () { setActiveLessonId(l.id); }}>{i + 1}. {l.label}</Pill>
            );
          })}
        </div>
        <div style={{ background: '#fff', border: '1px solid oklch(92% 0.012 265)', borderRadius: 14, padding: 18 }}>
          {LessonComponent ? <LessonComponent /> : null}
        </div>

        {window.DrumsLab.ui.FeedbackWidget && (
          <window.DrumsLab.ui.FeedbackWidget
            exerciseType="lesson"
            getContext={function () { return { lesson_id: activeLessonId }; }}
          />
        )}
      </div>
    );
  };

  const DrumsLab = function () {
    const [mode, setMode] = React.useState('lessons');
    // Use the shared useIsMobile hook so the layout responds to viewport
    // resizes (window resize, orientation change). Falls back to a one-
    // shot check if the hook isn't loaded (older preview builds).
    const isMobile = window.useIsMobile ? window.useIsMobile(720) :
      (typeof window !== 'undefined' && window.innerWidth < 720);

    return (
      <div style={{ fontFamily: "'Plus Jakarta Sans', sans-serif", maxWidth: 1080, 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 }}>Drum basics: lessons + practice quizzes with synthesized kit. Mic-based detection coming later.</span>
        </div>

        {/* Mode tabs */}
        <div style={{
          display: 'inline-flex',
          gap: 4,
          background: 'oklch(95% 0.01 265)',
          border: '1px solid oklch(90% 0.02 265)',
          borderRadius: 12,
          padding: 4,
          marginBottom: 22,
        }}>
          <ModeTab active={mode === 'lessons'}  onClick={function () { setMode('lessons'); }}>Lessons</ModeTab>
          <ModeTab active={mode === 'practice'} onClick={function () { setMode('practice'); }}>Practice</ModeTab>
        </div>

        {mode === 'lessons' && (isMobile ? <MobileLessonsMode /> : <LessonsMode />)}
        {mode === 'practice' && <PracticeMode />}
      </div>
    );
  };

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