// app.jsx — Atelier prototype: app shell + route container + tweaks.

const { useState: useAppS, useEffect: useAppE, useMemo: useAppM } = React;

const TWEAK_DEFAULS = /*EDITMODE-BEGIN*/{
  "palette": "pistachio",
  "heatmapStyle": "wash",
  "heatmapIntensity": 1.0,
  "trajectoryStyle": "painterly",
  "startRoute": "home"
}/*EDITMODE-END*/;

// Keys we persist across sessions so the user's preferences survive a refresh.
const PERSISTED_TWEAK_KEYS = ['palette', 'heatmapStyle', 'heatmapIntensity', 'trajectoryStyle'];
const STORAGE_KEY = 'chesswarp_tweaks';

function loadPersistedTweaks() {
  try {
    const stored = localStorage.getItem(STORAGE_KEY);
    return stored ? JSON.parse(stored) : {};
  } catch (_) { return {}; }
}

function persistTweaks(tweaks) {
  try {
    const toSave = {};
    PERSISTED_TWEAK_KEYS.forEach((k) => { if (k in tweaks) toSave[k] = tweaks[k]; });
    localStorage.setItem(STORAGE_KEY, JSON.stringify(toSave));
  } catch (_) {}
}

// Progress helpers — exposed on window so shell and screens can call them.
function getProgress() {
  try { return JSON.parse(localStorage.getItem('cwProgress') || '{}'); } catch (_) { return {}; }
}
function setLessonProgress(lessonId, stepIndex, total) {
  const p = getProgress();
  p[lessonId] = { lastStep: stepIndex, complete: stepIndex >= total - 1 };
  localStorage.setItem('cwProgress', JSON.stringify(p));
}
window.setLessonProgress = setLessonProgress;
window.getProgress = getProgress;

function AtelierTweaks({ tweaks, setTweak }) {
  const {
    TweaksPanel, TweakSection, TweakSlider, TweakRadio, TweakSelect,
  } = window;
  return (
    <TweaksPanel title="Tweaks">
      <TweakSection title="Palette">
        <TweakSelect
          label="Room"
          value={tweaks.palette}
          options={[
            { value: 'pistachio', label: 'Pistachio · soft museum green' },
            { value: 'porcelain', label: 'Porcelain · cool off-white' },
            { value: 'blush',     label: 'Blush · warm rose plaster' },
            { value: 'paper',     label: 'Paper · warm bone (original)' },
          ]}
          onChange={(v) => setTweak('palette', v)}
        />
      </TweakSection>
      <TweakSection title="Heatmap">
        <TweakRadio
          label="Style"
          value={tweaks.heatmapStyle}
          options={[
            { value: 'wash', label: 'Wash' },
            { value: 'dotted', label: 'Dotted' },
            { value: 'contour', label: 'Contour' },
          ]}
          onChange={(v) => setTweak('heatmapStyle', v)}
        />
        <TweakSlider
          label="Intensity"
          value={tweaks.heatmapIntensity}
          min={0.2} max={1.5} step={0.05}
          onChange={(v) => setTweak('heatmapIntensity', v)}
        />
      </TweakSection>
      <TweakSection title="Trajectory">
        <TweakRadio
          label="Brushstroke"
          value={tweaks.trajectoryStyle}
          options={[
            { value: 'painterly', label: 'Painterly' },
            { value: 'clean', label: 'Clean' },
          ]}
          onChange={(v) => setTweak('trajectoryStyle', v)}
        />
      </TweakSection>
    </TweaksPanel>
  );
}

function AtelierApp() {
  const defaults = useAppM(() => ({ ...TWEAK_DEFAULS, ...loadPersistedTweaks() }), []);
  const [tweaks, _setTweak] = window.useTweaks(defaults);

  const setTweak = React.useCallback((keyOrEdits, val) => {
    _setTweak(keyOrEdits, val);
    const edits = typeof keyOrEdits === 'object' ? keyOrEdits : { [keyOrEdits]: val };
    persistTweaks({ ...tweaks, ...edits });
  }, [tweaks, _setTweak]);

  // Determine starting route: URL hash → onboarding (first visit) → home.
  // Passed as an initializer so it only runs once, not on every re-render.
  const [route, setRoute] = useAppS(() => {
    const hash = window.location.hash.replace('#', '');
    // Accept both flat IDs ('lesson') and composite IDs ('lesson:some-id').
    const screenName = hash.includes(':') ? hash.split(':')[0] : hash;
    if (hash && (window.ROUTES.some((r) => r.id === screenName) || hash.includes(':'))) return hash;
    if (!localStorage.getItem('chesswarp_onboarding_seen')) return 'onboarding';
    return tweaks.startRoute || 'home';
  });

  // Derive screen name and lesson ID from the composite route.
  const screenName = route.includes(':') ? route.split(':')[0] : route;
  const lessonId   = route.includes(':') ? route.split(':')[1] : null;

  // lessonReady tracks whether the lesson data for the current route is loaded.
  // Starts false if the route already points to a lesson that isn't loaded yet,
  // so we never flash stale data before the fetch completes.
  const [lessonReady, setLessonReady] = useAppS(() => {
    if (!lessonId) return true;
    return !!(window.LESSON && window.LESSON.id === lessonId);
  });

  // When a composite route changes to a new lesson ID, fetch that lesson.
  useAppE(() => {
    if (!lessonId) return;
    if (window.LESSON && window.LESSON.id === lessonId) return; // already loaded
    setLessonReady(false);
    if (window.loadLesson) {
      window.loadLesson(lessonId)
        .then(() => setLessonReady(true))
        .catch(() => setLessonReady(true)); // fall back gracefully
    } else {
      setLessonReady(true);
    }
  }, [lessonId]);

  const palette = useAppM(() => window.atelierPalette(tweaks.palette), [tweaks.palette]);

  // Sync route into URL hash for refresh resilience.
  useAppE(() => { window.location.hash = '#' + route; }, [route]);

  const Screen = {
    home: window.HomeScreen,
    onboarding: window.OnboardingScreen,
    lesson: window.LessonScreen,
    puzzle: window.PuzzleScreen,
    hero: window.HeroPieceScreen,
    tension: window.TensionScreen,
    targets: window.TargetsScreen,
    vectors: window.AttackVectorsScreen,
    overload: window.OverloadedDefenderScreen,
    ghost: window.GhostRoutesScreen,
    play: window.PlayScreen,
  }[screenName];

  return (
    <div className="atelier-main-grid" style={{
      width: '100%', height: '100vh',
      display: 'flex',
      background: palette.bone,
      color: palette.umber,
      overflow: 'hidden',
      fontFamily: window.ATELIER_TYPE.ui,
    }}>
      <window.Rail route={route} setRoute={setRoute} palette={palette} />
      <main style={{
        flex: 1, height: '100%', display: 'flex', flexDirection: 'column',
        background: palette.bone, position: 'relative',
        minWidth: 0,
      }}>
        {!lessonReady ? (
          <div style={{
            flex: 1, display: 'flex', alignItems: 'center', justifyContent: 'center',
            fontFamily: window.ATELIER_TYPE.ui, fontSize: 13, opacity: 0.5,
            color: palette.umberSoft,
          }}>
            Loading lesson…
          </div>
        ) : Screen ? (
          <Screen palette={palette} setRoute={setRoute} tweaks={tweaks} lessonId={lessonId} />
        ) : null}
      </main>
      <AtelierTweaks tweaks={tweaks} setTweak={setTweak} />
    </div>
  );
}

const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(<AtelierApp />);
