// Main app — Kairos direction only, state machine across screens

function App() {
  const tweaks = /*EDITMODE-BEGIN*/{
    "lang": "fr"
  }/*EDITMODE-END*/;

  const [lang, setLang] = React.useState(tweaks.lang);
  const [editOpen, setEditOpen] = React.useState(false);
  const theme = THEMES.kairos;

  const [screen, setScreen] = React.useState('home');
  const [exStep, setExStep] = React.useState(0);
  const [speedMode, setSpeedMode] = React.useState('debitCredit');
  const [speedResult, setSpeedResult] = React.useState(null);
  // Persistance : on charge l'état depuis localStorage au 1er rendu.
  // Clé unique `compta:v1` qui stocke progress, goal, currentLessonId en JSON.
  const loadSaved = () => {
    try {
      const raw = localStorage.getItem('compta:v1');
      return raw ? JSON.parse(raw) : null;
    } catch (e) { return null; }
  };
  const saved = loadSaved();
  // Progression par unité (clés partagées, chaque track a ses ids d'unité propres).
  const DEFAULT_PROGRESS = { u1: 4, u2: 0, u3: 0, u4: 0, u5: 0, f1: 0 };
  const [currentLessonId, setCurrentLessonId] = React.useState(saved?.currentLessonId || 'u1-l1');
  const [progress, setProgress] = React.useState(
    Object.assign({}, DEFAULT_PROGRESS, saved?.progress || {})
  );
  const [goal, setGoal] = React.useState(saved?.goal || null);
  const [activeTrackId, setActiveTrackId] = React.useState(saved?.activeTrackId || 'fundamentals');
  // Système de cœurs : max 5, −1 par erreur, +1 toutes les 10 minutes.
  const MAX_HEARTS = 5;
  const REGEN_MS = 10 * 60 * 1000;
  const [hearts, setHearts] = React.useState(saved?.hearts ?? MAX_HEARTS);
  const [lastLossAt, setLastLossAt] = React.useState(saved?.lastLossAt ?? null);
  // Précision par leçon : { lessonId: { hits, misses } }. Met à jour à chaque réponse.
  const [accuracy, setAccuracy] = React.useState(saved?.accuracy || {});

  const recordAnswer = React.useCallback((lessonId, isCorrect) => {
    if (!lessonId) return;
    setAccuracy((prev) => {
      const cur = prev[lessonId] || { hits: 0, misses: 0 };
      return Object.assign({}, prev, {
        [lessonId]: {
          hits: cur.hits + (isCorrect ? 1 : 0),
          misses: cur.misses + (isCorrect ? 0 : 1),
        },
      });
    });
  }, []);

  // Régénération : au boot + tick toutes les 30s, on recalcule combien de cœurs
  // ont pu se recharger depuis `lastLossAt`. Math local, pas besoin de backend.
  React.useEffect(() => {
    const tick = () => {
      if (!lastLossAt || hearts >= MAX_HEARTS) return;
      const elapsed = Date.now() - lastLossAt;
      const regained = Math.floor(elapsed / REGEN_MS);
      if (regained > 0) {
        const newHearts = Math.min(MAX_HEARTS, hearts + regained);
        setHearts(newHearts);
        setLastLossAt(newHearts >= MAX_HEARTS ? null : lastLossAt + regained * REGEN_MS);
      }
    };
    tick();
    const id = setInterval(tick, 30000);
    return () => clearInterval(id);
  }, [lastLossAt, hearts]);

  const loseHeart = React.useCallback(() => {
    // Updater pur pour hearts — pas d'effet de bord dans l'updater.
    setHearts((h) => (h <= 0 ? 0 : h - 1));
    // On ne fixe lastLossAt que s'il n'existe pas déjà (préserve le timer de régen).
    setLastLossAt((prev) => prev || Date.now());
  }, []);

  // À chaque changement d'un des champs persistés, on sauvegarde.
  React.useEffect(() => {
    try {
      localStorage.setItem('compta:v1', JSON.stringify({ currentLessonId, progress, goal, hearts, lastLossAt, activeTrackId, accuracy }));
    } catch (e) { /* quota / storage disabled : on ignore */ }
  }, [currentLessonId, progress, goal, hearts, lastLossAt, activeTrackId, accuracy]);

  // Reset complet : efface localStorage et revient à l'état démo initial.
  const resetState = () => {
    try { localStorage.removeItem('compta:v1'); } catch (e) {}
    setCurrentLessonId('u1-l1');
    setProgress({ u1: 4, u2: 0, u3: 0, u4: 0, u5: 0, f1: 0 });
    setGoal(null);
    setHearts(MAX_HEARTS);
    setLastLossAt(null);
    setAccuracy({});
    setActiveTrackId('fundamentals');
    setScreen('home');
  };

  // Onboarding : chaque goal pointe vers le parcours le PLUS PERTINENT, et chaque
  // niveau détermine où on démarre dans ce parcours.
  //   student       → dcg-ue9      (programme officiel de l'examen)
  //   pro           → fundamentals (monter en compétence = maîtriser le socle)
  //   entrepreneur  → freelance    (le quotidien d'un indépendant)
  //   curious       → balance-sheet (lecture pure, sans tenue)
  const GOAL_TO_TRACK = {
    student: 'dcg-ue9',
    pro: 'fundamentals',
    entrepreneur: 'freelance',
    curious: 'balance-sheet',
  };
  const applyOnboarding = (pickedGoal, pickedLevel) => {
    const trackId = GOAL_TO_TRACK[pickedGoal] || 'fundamentals';
    const track = window.LESSON_INDEX && window.LESSON_INDEX.tracks.find((t) => t.id === trackId);
    if (!track) return;
    // Niveau → nombre d'unités supposées validées dans CE track.
    // Plafonne au nb d'unités dispo (une 1-unité-track ne laisse pas avancer au-delà).
    const nbUnits = track.units.length;
    const unitsDone = Math.min(nbUnits - 1, pickedLevel);
    const nextUnit = track.units[unitsDone] || track.units[0];
    // Progression : toutes les unités précédentes marquées comme terminées.
    const nextProgress = Object.assign({}, DEFAULT_PROGRESS);
    for (let i = 0; i < unitsDone; i++) {
      nextProgress[track.units[i].id] = track.units[i].lessons.length;
    }
    nextProgress[nextUnit.id] = 0;
    setGoal(pickedGoal);
    setActiveTrackId(trackId);
    setProgress(nextProgress);
    setCurrentLessonId(nextUnit.lessons[0]);
  };

  React.useEffect(() => {
    const h = (e) => {
      if (e.data?.type === '__activate_edit_mode') setEditOpen(true);
      if (e.data?.type === '__deactivate_edit_mode') setEditOpen(false);
    };
    window.addEventListener('message', h);
    window.parent.postMessage({ type: '__edit_mode_available' }, '*');
    return () => window.removeEventListener('message', h);
  }, []);
  const persistEdit = (edits) => {
    window.parent.postMessage({ type: '__edit_mode_set_keys', edits }, '*');
  };

  const lesson = getLesson(currentLessonId);
  const exQ1 = lesson.exercises[0];
  const exQ2 = lesson.exercises[1];
  const exQ3 = lesson.exercises[2];

  // Dispatcher unique pour toutes les bottom-tabs.
  // Chaque écran (Home, Tracks, Catalog, Profile) délègue ici → cohérence garantie.
  const goToTab = (k) => {
    if (k === 'home') setScreen('home');
    else if (k === 'tracks') setScreen('tracks');
    else if (k === 'catalog') setScreen('catalog');
    else if (k === 'profile') setScreen('profile');
    else if (k === 'league') setScreen('paywall');
    else if (k === 'speed') setScreen('speedIntro');
  };

  // Quand on clique un parcours dans TracksScreen, on bascule activeTrackId + retour home.
  // 'speed' → mode Speed. Clés des cartes → mapping vers ids réels de LESSON_INDEX.
  const TRACK_KEY_MAP = {
    fondamentaux: 'fundamentals',
    freelance: 'freelance',
    bilan: 'balance-sheet',
    tva: 'vat-tax',
    dcg: 'dcg-ue9',
    // 'ifrs' n'a pas encore de contenu — on ignore le clic.
  };
  const goToTrack = (t) => {
    if (!t) return;
    if (t.k === 'speed') { setScreen('speedIntro'); return; }
    const trackId = TRACK_KEY_MAP[t.k];
    if (trackId && window.LESSON_INDEX && window.LESSON_INDEX.tracks.find((x) => x.id === trackId)) {
      setActiveTrackId(trackId);
      setScreen('home');
    }
    // Sinon (ex : ifrs) on reste sur l'écran tracks — pas de redirection silencieuse.
  };
  // Appelé depuis l'écran completion : marque la leçon en cours comme faite
  // (si elle ne l'était pas déjà) puis navigue vers la suivante — ou home si fin de parcours.
  const advanceOrComplete = () => {
    if (window.LESSON_INDEX && lesson) {
      // Retrouve l'unité par son id (partagé entre tracks) dans le bon track.
      const track = window.LESSON_INDEX.tracks.find((t) => t.id === lesson.track);
      const unitInfo = track && track.units.find((u) => u.order === lesson.unit);
      if (unitInfo) {
        const unitId = unitInfo.id;
        const lessonIdx = unitInfo.lessons.indexOf(currentLessonId);
        if (lessonIdx >= 0 && (progress[unitId] || 0) <= lessonIdx) {
          setProgress({ ...progress, [unitId]: lessonIdx + 1 });
        }
      }
    }
    const nextId = window.LESSON_INDEX && window.LESSON_INDEX.next(currentLessonId);
    if (nextId) {
      setCurrentLessonId(nextId);
      setScreen('lessonIntro');
    } else {
      setScreen('home');
    }
  };
  const props = { theme, lang };
  const closeToHome = () => setScreen('home');

  const screens = {
    onboarding: <OnboardingScreen {...props} onComplete={(g, lv) => { applyOnboarding(g, lv); setScreen('home'); }}/>,
    home: <HomeScreen {...props} progress={progress} goal={goal} hearts={hearts}
      activeTrackId={activeTrackId} setActiveTrackId={setActiveTrackId}
      onLessonClick={(l) => { if (l?.lessonId) setCurrentLessonId(l.lessonId); setScreen('lessonIntro'); }}
      onTabClick={goToTab}
    />,
    tracks: <TracksScreen {...props}
      onTrackClick={goToTrack}
      onTabClick={goToTab}
    />,
    speedIntro: <SpeedIntroScreen {...props}
      onStart={(mk) => { setSpeedMode(mk); setScreen('speedRun'); }}
      onClose={() => setScreen('tracks')}
    />,
    speedRun: <SpeedRunScreen {...props} modeKey={speedMode}
      onEnd={(res) => { setSpeedResult(res); setScreen('speedResults'); }}
      onClose={() => setScreen('speedIntro')}
    />,
    speedResults: <SpeedResultsScreen {...props} result={speedResult || { score: 0, correct: 0, wrong: 0, bestCombo: 0, mode: speedMode }}
      onReplay={() => setScreen('speedRun')}
      onClose={() => setScreen('speedIntro')}
    />,
    lessonIntro: <LessonIntroScreen {...props} lesson={lesson} hearts={hearts} onStart={() => { if (hearts > 0) { setExStep(0); setScreen('ex1'); } else { setScreen('paywall'); } }} onClose={closeToHome}/>,
    ex1: <LessonShell {...props} progress={exQ1.progress} hearts={hearts} onClose={closeToHome}>
      <QCMExercise {...props} exercise={exQ1} onAnswer={(ok) => { recordAnswer(currentLessonId, ok); if (!ok) loseHeart(); setScreen('ex2'); }}/>
    </LessonShell>,
    ex2: <LessonShell {...props} progress={exQ2.progress} hearts={hearts} onClose={closeToHome}>
      <DragDropExercise {...props} exercise={exQ2} onAnswer={(ok) => { recordAnswer(currentLessonId, ok); if (!ok) loseHeart(); setScreen('ex3'); }}/>
    </LessonShell>,
    ex3: <LessonShell {...props} progress={exQ3.progress} hearts={hearts} onClose={closeToHome}>
      <JournalExercise {...props} exercise={exQ3} onAnswer={(ok) => { recordAnswer(currentLessonId, ok); if (!ok) loseHeart(); setScreen('complete'); }}/>
    </LessonShell>,
    complete: <CompletionScreen {...props} completion={lesson.completion} onContinue={advanceOrComplete}/>,
    catalog: <CatalogScreen {...props} onTabClick={goToTab} onLessonClick={(l) => { if (l?.lessonId) setCurrentLessonId(l.lessonId); setScreen('lessonIntro'); }}/>,
    profile: <ProfileScreen {...props} progress={progress} goal={goal} accuracy={accuracy} onTabClick={goToTab}/>,
    paywall: <PaywallScreen {...props} onClose={closeToHome}/>,
  };

  // Note : on rendait précédemment chaque écran dans <motion.div> via Framer
  // Motion, mais le composant Mt de framer-motion plantait à chaque changement
  // d'écran (LessonIntroScreen → exercise → ...) et React revertait à l'écran
  // précédent. Plus simple et fiable : rendu natif. La landing garde Motion.
  const screenContent = screens[screen];

  return (
    <>
      <div style={{ minHeight: '100vh', background: '#F5F5F7', display: 'flex', alignItems: 'center', justifyContent: 'center', padding: '24px 20px', flexDirection: 'column', gap: 20 }}>
        <NavStrip theme={theme} screen={screen} setScreen={setScreen} lang={lang}
          currentLessonId={currentLessonId} setCurrentLessonId={setCurrentLessonId}/>
        <IOSDevice data-screen-label={screen}>
          {screenContent}
        </IOSDevice>
      </div>
      {editOpen && (
        <TweaksPanel
          lang={lang} setLang={(l) => { setLang(l); persistEdit({ lang: l }); }}
          onReset={resetState}
        />
      )}
    </>
  );
}

function NavStrip({ theme, screen, setScreen, lang, currentLessonId, setCurrentLessonId }) {
  const allIds = (window.LESSON_INDEX && window.LESSON_INDEX.allIds()) || [currentLessonId];
  const steps = [
    { k: 'onboarding', label: 'Onboarding' },
    { k: 'home', label: lang === 'fr' ? 'Leçon' : 'Lesson' },
    { k: 'tracks', label: lang === 'fr' ? 'Parcours' : 'Tracks' },
    { k: 'speedIntro', label: 'Speed' },
    { k: 'speedRun', label: 'Speed run' },
    { k: 'speedResults', label: 'Speed res.' },
    { k: 'lessonIntro', label: lang === 'fr' ? 'Intro leçon' : 'Lesson intro' },
    { k: 'ex1', label: 'QCM' },
    { k: 'ex2', label: 'Drag&Drop' },
    { k: 'ex3', label: lang === 'fr' ? 'Écriture' : 'Journal' },
    { k: 'complete', label: lang === 'fr' ? 'Fin' : 'Done' },
    { k: 'catalog', label: lang === 'fr' ? 'Catalogue' : 'Catalog' },
    { k: 'profile', label: 'Profile' },
    { k: 'paywall', label: 'Paywall' },
  ];
  return (
    <div style={{
      display: 'flex', gap: 6, flexWrap: 'wrap', justifyContent: 'center',
      maxWidth: 640, padding: '8px 12px',
      background: '#fff', borderRadius: 16, border: '1px solid #E5E5E7',
      boxShadow: '0 2px 10px rgba(0,0,0,0.04)',
    }}>
      {steps.map(s => {
        const active = screen === s.k || (s.k === 'ex1' && screen.startsWith('ex'));
        return (
          <button key={s.k} onClick={() => setScreen(s.k)} style={{
            padding: '6px 12px', borderRadius: 999, border: 'none', cursor: 'pointer',
            background: active ? theme.primary : '#F5F5F7',
            color: active ? '#fff' : theme.ink,
            fontFamily: 'ui-sans-serif, -apple-system, system-ui', fontSize: 12, fontWeight: 700,
          }}>{s.label}</button>
        );
      })}
      <div style={{ display: 'flex', alignItems: 'center', gap: 6, paddingLeft: 8, marginLeft: 4, borderLeft: '1px solid #E5E5E7' }}>
        <span style={{ fontSize: 11, fontWeight: 700, color: '#8A8A90', textTransform: 'uppercase', letterSpacing: 0.5 }}>
          {lang==='fr'?'Leçon':'Lesson'}
        </span>
        <select value={currentLessonId} onChange={(e) => setCurrentLessonId(e.target.value)} style={{
          padding: '5px 8px', borderRadius: 999, border: '1px solid #E5E5E7',
          background: '#F5F5F7', color: theme.ink, cursor: 'pointer',
          fontFamily: 'inherit', fontSize: 12, fontWeight: 700,
        }}>
          {allIds.map(id => {
            const l = getLesson(id);
            const t = l ? loc(l.title, lang) : id;
            return <option key={id} value={id}>{id.toUpperCase()} · {t}</option>;
          })}
        </select>
      </div>
    </div>
  );
}

function TweaksPanel({ lang, setLang, onReset }) {
  return (
    <div style={{
      position: 'fixed', right: 16, bottom: 16, width: 260, zIndex: 1000,
      background: '#1A1A1E', color: '#fff', borderRadius: 16,
      padding: 16, boxShadow: '0 12px 40px rgba(0,0,0,0.3)',
      fontFamily: '"Inter", system-ui',
    }}>
      <div style={{ fontSize: 13, fontWeight: 800, letterSpacing: 1, textTransform: 'uppercase', color: '#9A9AA0', marginBottom: 12 }}>Tweaks</div>
      <div style={{ marginBottom: 12 }}>
        <div style={{ fontSize: 11, color: '#6A6A70', marginBottom: 6, fontWeight: 700, letterSpacing: 0.5, textTransform: 'uppercase' }}>Langue</div>
        <div style={{ display: 'flex', gap: 6 }}>
          {['fr', 'en'].map(l => (
            <button key={l} onClick={() => setLang(l)} style={{
              background: lang === l ? '#fff' : 'rgba(255,255,255,0.06)',
              color: lang === l ? '#1A1A1E' : '#DDD',
              border: '1px solid ' + (lang === l ? '#fff' : 'rgba(255,255,255,0.1)'),
              padding: '6px 12px', borderRadius: 8, cursor: 'pointer',
              fontSize: 12, fontWeight: 700, fontFamily: 'inherit',
            }}>{l.toUpperCase()}</button>
          ))}
        </div>
      </div>
      {onReset && (
        <div>
          <div style={{ fontSize: 11, color: '#6A6A70', marginBottom: 6, fontWeight: 700, letterSpacing: 0.5, textTransform: 'uppercase' }}>Progression</div>
          <button onClick={onReset} style={{
            background: 'rgba(201, 74, 63, 0.15)', color: '#F87171',
            border: '1px solid rgba(201, 74, 63, 0.4)',
            padding: '8px 12px', borderRadius: 8, cursor: 'pointer',
            fontSize: 12, fontWeight: 700, fontFamily: 'inherit', width: '100%',
          }}>⟲ Reset (efface localStorage)</button>
        </div>
      )}
    </div>
  );
}

// On attend que Framer Motion soit chargé (script type="module" dans index.html)
// avant de monter l'App pour éviter le render initial sans AnimatePresence.
function bootApp() {
  ReactDOM.createRoot(document.getElementById('root')).render(<App/>);
}
if (window.__fmReady) {
  bootApp();
} else {
  window.addEventListener('fm-ready', bootApp, { once: true });
  // Sécurité : si le module échoue à charger en 4 s, on monte sans Motion.
  setTimeout(() => { if (!window.__fmReady) { window.__fmReady = true; bootApp(); } }, 4000);
}
