/* App — top-level state */

const { useState, useEffect, useMemo, useRef } = React;

const TWEAK_DEFAULTS = /*EDITMODE-BEGIN*/{
  "accent": "#ED643B",
  "blueAccent": "#6F9FB5",
  "bgGlobalRail": "#FFFFFF",
  "bgCourseRail": "#FAF7F2",
  "bgLesson": "#FAF7F2",
  "bgPanel": "#FFFFFF",
  "density": "default",
  "favouritedDefault": true,
  "arrowSize": 14,
  "arrowOffsetX": 6,
  "lessonPadLeft": 40
}/*EDITMODE-END*/;

function App() {
  const [tweaks, setTweak] = useTweaks(TWEAK_DEFAULTS);

  const [mode, setMode] = useState("desktop");
  const [globalActive, setGlobalActive] = useState("library");

  // course rail state
  const [courseCollapsed, setCourseCollapsed] = useState(false);
  const [performancesOpen, setPerformancesOpen] = useState(false);
  const [mobileCourseOpen, setMobileCourseOpen] = useState(false);
  const [mobileGlobalOpen, setMobileGlobalOpen] = useState(false);

  useEffect(() => {
    if (mode === "tablet") setCourseCollapsed(true);
    else if (mode === "desktop") setCourseCollapsed(false);
  }, [mode]);

  // current lesson
  const [currentLessonId, setCurrentLessonId] = useState(LESSON.id);

  // flat list for prev/next
  const flat = useMemo(() => {
    const arr = [];
    COURSE.items.forEach(it => {
      if (it.children) it.children.forEach(c => arr.push(c));
      else arr.push(it);
    });
    return arr;
  }, []);

  const currentIdx = flat.findIndex(l => l.id === currentLessonId);
  const prevLesson = currentIdx > 0 ? flat[currentIdx - 1] : null;
  const nextLesson = currentIdx < flat.length - 1 ? flat[currentIdx + 1] : null;

  const initialDone = new Set();
  flat.forEach(l => { if (l.status === "done") initialDone.add(l.id); });
  const [completedIds, setCompletedIds] = useState(initialDone);

  const [favourited, setFavourited] = useState(!!tweaks.favouritedDefault);

  const [goals, setGoals] = useState(GOALS);
  const [currentChapterId, setCurrentChapterId] = useState("g3");

  const [notes, setNotes] = useState(
    "Bars 9–12 felt easier when I let the wrist breathe with the harmony rather than holding it still.\n\nCome back to bar 17 — the F# wants more weight than I'm giving it.\n\nTry hands-separately at a slower tempo tomorrow."
  );
  const [notesState, setNotesState] = useState("idle");
  const saveTimer = useRef(null);
  const onChangeNotes = (val) => {
    setNotes(val);
    setNotesState("saving");
    if (saveTimer.current) clearTimeout(saveTimer.current);
    saveTimer.current = setTimeout(() => setNotesState("saved"), 800);
  };

  const [videoLoaded, setVideoLoaded] = useState(false);

  // accent + bg live update
  useEffect(() => {
    const root = document.documentElement.style;
    const a = tweaks.accent || "#ED643B";
    const b = tweaks.blueAccent || "#6F9FB5";
    root.setProperty("--accent", a);
    root.setProperty("--accent-hover", shade(a, -10));
    root.setProperty("--accent-text", shade(a, -16));
    root.setProperty("--accent-soft", tint(a, 86));
    root.setProperty("--blue", b);
    root.setProperty("--blue-soft", tint(b, 86));
    root.setProperty("--blue-deep", shade(b, -28));
    root.setProperty("--bg-global-rail", tweaks.bgGlobalRail || "#FFFFFF");
    root.setProperty("--bg-course-rail", tweaks.bgCourseRail || "#FAF7F2");
    root.setProperty("--bg-lesson", tweaks.bgLesson || "#FAF7F2");
    root.setProperty("--bg-panel", tweaks.bgPanel || "#FFFFFF");
    root.setProperty("--cr-arrow-size", `${tweaks.arrowSize ?? 14}px`);
    root.setProperty("--cr-arrow-x", `${tweaks.arrowOffsetX ?? 6}px`);
    root.setProperty("--lesson-pad-left", `${tweaks.lessonPadLeft ?? 40}px`);
  }, [tweaks.accent, tweaks.blueAccent, tweaks.bgGlobalRail, tweaks.bgCourseRail, tweaks.bgLesson, tweaks.bgPanel, tweaks.arrowSize, tweaks.arrowOffsetX, tweaks.lessonPadLeft]);

  const onPickLesson = (id) => {
    setCurrentLessonId(id);
    setVideoLoaded(false);
    if (mode === "mobile") setMobileCourseOpen(false);
    if (mode === "tablet") setCourseCollapsed(true);
  };

  const onToggleGoal = (id) => {
    setGoals(prev => prev.map(g => g.id === id ? { ...g, done: !g.done } : g));
  };
  const onJumpChapter = (id) => {
    setCurrentChapterId(id);
    if (!videoLoaded) setVideoLoaded(true);
  };

  const onPrev = () => prevLesson && onPickLesson(prevLesson.id);
  const onNext = () => nextLesson && onPickLesson(nextLesson.id);

  const lessonForDisplay = currentLessonId === LESSON.id ? LESSON : (() => {
    const l = flat.find(x => x.id === currentLessonId);
    return {
      ...LESSON,
      id: l.id,
      num: l.num ?? null,
      navLabel: l.title,
      displayTitle: l.num ? `${l.title} — Continuing the Journey` : l.title,
      duration: l.dur ? `${l.dur} min` : LESSON.duration,
    };
  })();

  return (
    <DeviceShell mode={mode} setMode={setMode}>
      <div
        className="app-shell"
        data-mode={mode}
        data-course-collapsed={courseCollapsed}
        data-density={tweaks.density}
      >
        {mode === "mobile" && (
          <div className="mobile-topbar">
            <button className="mt-btn" onClick={() => setMobileGlobalOpen(true)} aria-label="Open menu">
              <Icon.Menu size={18} />
            </button>
            <img src="assets/cpa-logo-full.png" alt="Creative Piano Academy" />
            <div className="mt-spacer" />
            <button className="mt-btn" onClick={() => setMobileCourseOpen(true)} aria-label="Open course">
              <Icon.Library size={16} />
            </button>
          </div>
        )}

        {mode !== "mobile" && (
          <GlobalRail
            active={globalActive}
            onNavigate={setGlobalActive}
            mode={mode}
          />
        )}

        {/* Course rail — always mounted on desktop/tablet so it can animate slide in/out */}
        {mode !== "mobile" && (
          <CourseRail
            course={COURSE}
            currentLessonId={currentLessonId}
            performancesOpen={performancesOpen}
            onTogglePerformances={() => setPerformancesOpen(o => !o)}
            collapsed={courseCollapsed}
            onToggleCollapse={() => setCourseCollapsed(true)}
            onPickLesson={onPickLesson}
            onCourseHome={() => {
              // In production this would route to the course landing page.
              // Here we surface it visually by jumping to lesson 1 + scroll-to-top.
              onPickLesson(COURSE.items[0].id);
            }}
            completedIds={completedIds}
          />
        )}

        {/* Labelled expand bubble when course rail is fully collapsed.
            Always rendered so it can fade in/out in sync with the rail. */}
        {mode !== "mobile" && (
          <CourseRailExpander mode={mode} onClick={() => setCourseCollapsed(false)} />
        )}

        <LessonContent
          lesson={lessonForDisplay}
          course={COURSE}
          goals={goals}
          onToggleGoal={onToggleGoal}
          currentChapterId={currentChapterId}
          onJumpChapter={onJumpChapter}
          favourited={favourited}
          onToggleFav={() => setFavourited(f => !f)}
          notes={notes}
          onChangeNotes={onChangeNotes}
          notesState={notesState}
          onPrev={onPrev}
          onNext={onNext}
          prevLesson={prevLesson}
          nextLesson={nextLesson}
          videoLoaded={videoLoaded}
          onLoadVideo={() => setVideoLoaded(true)}
          mode={mode}
        />

        {mode === "mobile" && mobileGlobalOpen && (
          <>
            <div className="drawer-overlay" onClick={() => setMobileGlobalOpen(false)} />
            <div className="drawer drawer-global">
              <div className="drawer-head">
                <div className="dh-title">Menu</div>
                <button className="dh-close" onClick={() => setMobileGlobalOpen(false)}>
                  <Icon.X size={14} />
                </button>
              </div>
              <div className="drawer-body" style={{ padding: 12 }}>
                <GlobalRail
                  active={globalActive}
                  onNavigate={(id) => { setGlobalActive(id); setMobileGlobalOpen(false); }}
                  mode="desktop"
                />
              </div>
            </div>
          </>
        )}
        {mode === "mobile" && mobileCourseOpen && (
          <>
            <div className="drawer-overlay" onClick={() => setMobileCourseOpen(false)} />
            <div className="drawer">
              <CourseRail
                course={COURSE}
                currentLessonId={currentLessonId}
                performancesOpen={performancesOpen}
                onTogglePerformances={() => setPerformancesOpen(o => !o)}
                collapsed={false}
                onToggleCollapse={() => setMobileCourseOpen(false)}
                onPickLesson={onPickLesson}
                onCourseHome={() => {
                  onPickLesson(COURSE.items[0].id);
                  setMobileCourseOpen(false);
                }}
                completedIds={completedIds}
              />
            </div>
          </>
        )}
      </div>

      <TweaksPanel title="Tweaks">
        <TweakSection label="Accents">
          <TweakColor label="Accent" value={tweaks.accent} onChange={(v) => setTweak("accent", v)} />
          <TweakColor label="Blue accent" value={tweaks.blueAccent} onChange={(v) => setTweak("blueAccent", v)} />
        </TweakSection>
        <TweakSection label="Backgrounds">
          <TweakColor label="Main nav" value={tweaks.bgGlobalRail} onChange={(v) => setTweak("bgGlobalRail", v)} />
          <TweakColor label="Course nav" value={tweaks.bgCourseRail} onChange={(v) => setTweak("bgCourseRail", v)} />
          <TweakColor label="Lesson area" value={tweaks.bgLesson} onChange={(v) => setTweak("bgLesson", v)} />
          <TweakColor label="Panels" value={tweaks.bgPanel} onChange={(v) => setTweak("bgPanel", v)} />
          <TweakButton
            label="Reset backgrounds"
            secondary
            onClick={() => {
              setTweak({
                bgGlobalRail: "#FFFFFF",
                bgCourseRail: "#FAF7F2",
                bgLesson: "#FAF7F2",
                bgPanel: "#FFFFFF",
              });
            }}
          />
        </TweakSection>
        <TweakSection label="Layout">
          <TweakRadio
            label="Density"
            value={tweaks.density}
            onChange={(v) => setTweak("density", v)}
            options={[{ value: "default", label: "Comfy" }, { value: "cozy", label: "Cozy" }]}
          />
          <TweakToggle
            label="Favourited by default"
            value={!!tweaks.favouritedDefault}
            onChange={(v) => { setTweak("favouritedDefault", v); setFavourited(v); }}
          />
        </TweakSection>
        <TweakSection label="Collapsed nav">
          <TweakSlider
            label="Arrow size"
            value={tweaks.arrowSize ?? 14}
            min={8} max={28} step={1} unit="px"
            onChange={(v) => setTweak("arrowSize", v)}
          />
          <TweakSlider
            label="Arrow offset"
            value={tweaks.arrowOffsetX ?? 6}
            min={-8} max={40} step={1} unit="px"
            onChange={(v) => setTweak("arrowOffsetX", v)}
          />
          <TweakSlider
            label="Lesson left edge"
            value={tweaks.lessonPadLeft ?? 40}
            min={0} max={120} step={1} unit="px"
            onChange={(v) => setTweak("lessonPadLeft", v)}
          />
          <TweakButton
            label="Reset collapsed nav"
            secondary
            onClick={() => {
              setTweak({ arrowSize: 14, arrowOffsetX: 6, lessonPadLeft: 40 });
            }}
          />
        </TweakSection>
        <TweakSection label="Try it">
          <TweakButton label="Reset video" onClick={() => setVideoLoaded(false)} />
          <TweakButton
            label="Mark complete & next"
            secondary
            onClick={() => {
              setCompletedIds(s => new Set([...s, currentLessonId]));
              if (nextLesson) onPickLesson(nextLesson.id);
            }}
          />
        </TweakSection>
      </TweaksPanel>
    </DeviceShell>
  );
}

function hexToRgb(hex) {
  const m = hex.replace("#", "");
  const v = m.length === 3
    ? m.split("").map(c => parseInt(c + c, 16))
    : [parseInt(m.slice(0, 2), 16), parseInt(m.slice(2, 4), 16), parseInt(m.slice(4, 6), 16)];
  return v;
}
function rgbToHex(r, g, b) {
  return "#" + [r, g, b].map(c => Math.max(0, Math.min(255, c | 0)).toString(16).padStart(2, "0")).join("");
}
function shade(hex, pct) {
  const [r, g, b] = hexToRgb(hex);
  const f = pct / 100;
  return rgbToHex(r + (255 - r) * f, g + (255 - g) * f, b + (255 - b) * f);
}
function tint(hex, pct) {
  const [r, g, b] = hexToRgb(hex);
  const f = pct / 100;
  return rgbToHex(r + (255 - r) * f, g + (255 - g) * f, b + (255 - b) * f);
}

ReactDOM.createRoot(document.getElementById("root")).render(<App />);
