// ─── AUTH MODAL ───────────────────────────────────────────────────────────
const AuthModal = ({ onLogin }) => {
  const [isLogin, setIsLogin] = React.useState(true);
  const [email, setEmail] = React.useState('');
  const [password, setPassword] = React.useState('');
  const [displayName, setDisplayName] = React.useState('');
  const [loading, setLoading] = React.useState(false);
  const [error, setError] = React.useState('');

  const handleSubmit = async (e) => {
    e.preventDefault();
    setLoading(true);
    setError('');

    try {
      if (isLogin) {
        const { error: signInError } = await window.supabase.auth.signInWithPassword({ email, password });
        if (signInError) throw signInError;
      } else {
        const { error: signUpError } = await window.supabase.auth.signUp({
          email,
          password,
          options: {
            data: { display_name: displayName, user_type: 'student' }
          }
        });
        if (signUpError) throw signUpError;
        alert("Inscription réussie ! Vous êtes connecté.");
      }
      onLogin();
    } catch (err) {
      setError(err.message);
    } finally {
      setLoading(false);
    }
  };

  return (
    <div style={{ position:'fixed', top:0, left:0, right:0, bottom:0, background:'rgba(8,15,30,0.85)', backdropFilter:'blur(5px)', display:'flex', alignItems:'center', justifyContent:'center', zIndex:100, padding:20 }}>
      <div style={{ background:'var(--surface)', border:'1px solid var(--border)', borderRadius:'var(--r)', padding:30, width:'100%', maxWidth:400, boxShadow:'0 10px 40px rgba(0,0,0,0.5)' }}>
        <div style={{ textAlign:'center', marginBottom:20 }}>
          <div style={{ fontFamily:'var(--mono)', fontSize:14, fontWeight:700, color:'var(--teal)', letterSpacing:'0.14em', marginBottom:6 }}>PHUTURISTIC</div>
          <div style={{ fontSize:18, fontWeight:700 }}>Espace Étudiant</div>
        </div>
        
        {error && <div style={{ background:'var(--red-dim)', color:'var(--red)', padding:10, borderRadius:8, fontSize:13, marginBottom:16 }}>{error}</div>}
        
        <form onSubmit={handleSubmit} style={{ display:'flex', flexDirection:'column', gap:14 }}>
          {!isLogin && (
            <div>
              <label style={{ display:'block', fontSize:12, color:'var(--text-dim)', marginBottom:6 }}>Prénom / Pseudo</label>
              <input required value={displayName} onChange={e=>setDisplayName(e.target.value)} style={{ width:'100%', padding:'10px 14px', borderRadius:8, border:'1px solid var(--border2)', background:'var(--surface2)', color:'var(--text)' }} />
            </div>
          )}
          <div>
            <label style={{ display:'block', fontSize:12, color:'var(--text-dim)', marginBottom:6 }}>Email</label>
            <input required type="email" value={email} onChange={e=>setEmail(e.target.value)} style={{ width:'100%', padding:'10px 14px', borderRadius:8, border:'1px solid var(--border2)', background:'var(--surface2)', color:'var(--text)' }} />
          </div>
          <div>
            <label style={{ display:'block', fontSize:12, color:'var(--text-dim)', marginBottom:6 }}>Mot de passe</label>
            <input required type="password" value={password} onChange={e=>setPassword(e.target.value)} style={{ width:'100%', padding:'10px 14px', borderRadius:8, border:'1px solid var(--border2)', background:'var(--surface2)', color:'var(--text)' }} />
          </div>
          
          <PrimaryBtn disabled={loading} style={{ marginTop:10 }}>
            {loading ? 'Patientez...' : isLogin ? 'Se connecter' : "S'inscrire"}
          </PrimaryBtn>
        </form>
        
        <div style={{ textAlign:'center', marginTop:16, fontSize:13, color:'var(--text-dim)' }}>
          {isLogin ? "Pas encore de compte ?" : "Déjà un compte ?"}
          <span onClick={() => setIsLogin(!isLogin)} style={{ color:'var(--blue)', cursor:'pointer', marginLeft:6 }}>
            {isLogin ? "S'inscrire" : "Se connecter"}
          </span>
        </div>
      </div>
    </div>
  );
};

// ─── REDEEM CODE MODAL ────────────────────────────────────────────────────
const RedeemCodeModal = ({ onClose, onSuccess }) => {
  const [code, setCode] = React.useState('');
  const [loading, setLoading] = React.useState(false);
  const [error, setError] = React.useState('');

  const submit = async (e) => {
    e.preventDefault();
    if (!code) return;
    setLoading(true);
    setError('');

    try {
      const { data, error: rpcError } = await window.supabase.rpc('redeem_activation_code', { p_code: code });
      if (rpcError) throw rpcError;
      if (data) {
        onSuccess();
      }
    } catch (err) {
      if (err.message.includes('invalide')) setError('Code introuvable ou invalide.');
      else if (err.message.includes('déjà été utilisé')) setError('Ce code a déjà été utilisé.');
      else setError(err.message);
    } finally {
      setLoading(false);
    }
  };

  return (
    <div style={{ position:'fixed', top:0, left:0, right:0, bottom:0, background:'rgba(8,15,30,0.85)', backdropFilter:'blur(5px)', display:'flex', alignItems:'center', justifyContent:'center', zIndex:100, padding:20 }}>
      <div style={{ background:'var(--surface)', border:'1px solid var(--border)', borderRadius:'var(--r)', padding:24, width:'100%', maxWidth:360, boxShadow:'0 10px 40px rgba(0,0,0,0.5)' }}>
        <div style={{ display:'flex', justifyContent:'space-between', alignItems:'center', marginBottom:16 }}>
          <div style={{ fontSize:16, fontWeight:700 }}>Activer un accès Premium</div>
          <button onClick={onClose} style={{ background:'none', border:'none', color:'var(--text-muted)', fontSize:20, cursor:'pointer' }}>×</button>
        </div>
        <p style={{ fontSize:12, color:'var(--text-dim)', marginBottom:16, lineHeight:1.5 }}>
          Saisissez le code PIN acheté via Wave/Orange Money pour débloquer les séries premium.
        </p>
        
        {error && <div style={{ background:'var(--red-dim)', color:'var(--red)', padding:10, borderRadius:8, fontSize:12, marginBottom:16 }}>{error}</div>}
        
        <form onSubmit={submit}>
          <input required placeholder="Ex: PH-1234-ABCD" value={code} onChange={e=>setCode(e.target.value.toUpperCase())} style={{ width:'100%', padding:'12px 14px', borderRadius:8, border:'1px solid var(--teal)', background:'rgba(0,212,170,0.05)', color:'var(--teal)', fontWeight:700, fontFamily:'var(--mono)', letterSpacing:2, textAlign:'center', marginBottom:14 }} />
          <PrimaryBtn disabled={loading || !code} color="var(--teal)" style={{ width:'100%' }}>
            {loading ? 'Vérification...' : 'Activer mon code'}
          </PrimaryBtn>
        </form>
      </div>
    </div>
  );
};

// ─── SERIES DASHBOARD ─────────────────────────────────────────────────────
const SeriesDashboard = ({ seriesList, casesBySeries, onSelectCase, onPlayMirror, progress, studentProfile, onLogout, refreshProfile }) => {
  const [openSeries, setOpenSeries] = React.useState(seriesList.length > 0 ? seriesList[0].id : null);
  const [showRedeem, setShowRedeem] = React.useState(false);
  
  const hasPremium = studentProfile?.premium_until && new Date(studentProfile.premium_until) > new Date();
  
  return (
    <div style={{ animation:'fadeIn 0.4s ease' }}>
      <div style={{ padding:'24px 0 20px', display:'flex', justifyContent:'space-between', alignItems:'flex-start' }}>
        <div>
          <div style={{ fontFamily:'var(--mono)', fontSize:13, fontWeight:700, color:'var(--teal)', letterSpacing:'0.14em', marginBottom:4 }}>PHUTURISTIC</div>
          <div style={{ fontSize:18, fontWeight:700 }}>Dispensation Raisonnée</div>
        </div>
        <div style={{ display:'flex', alignItems:'center', gap:10 }}>
          <div style={{ textAlign:'right' }}>
            <div style={{ fontSize:13, fontWeight:600 }}>{studentProfile?.display_name || 'Étudiant'}</div>
            <div style={{ fontSize:11, color:'var(--text-muted)' }} onClick={onLogout} style={{ cursor:'pointer', color:'var(--red)' }}>Déconnexion</div>
          </div>
        </div>
      </div>

      {/* Premium Status Banner */}
      <div style={{ background:'var(--surface2)', border:'1px solid var(--border)', borderRadius:'var(--r)', padding:16, marginBottom:20, display:'flex', alignItems:'center', justifyContent:'space-between' }}>
        <div>
          <div style={{ fontSize:12, color:'var(--text-muted)', marginBottom:2 }}>Statut du compte</div>
          {hasPremium ? (
            <div style={{ color:'var(--teal)', fontSize:14, fontWeight:600, display:'flex', alignItems:'center', gap:6 }}>
              <span style={{ fontSize:16 }}>✨</span> Premium jusqu'au {new Date(studentProfile.premium_until).toLocaleDateString('fr-FR')}
            </div>
          ) : (
            <div style={{ color:'var(--text)', fontSize:14, fontWeight:600 }}>Standard (Gratuit)</div>
          )}
        </div>
        <button onClick={() => setShowRedeem(true)} style={{ background:hasPremium?'transparent':'var(--teal-dim)', border:hasPremium?'1px solid var(--teal)':'none', color:'var(--teal)', padding:'8px 14px', borderRadius:8, fontSize:12, fontWeight:600, cursor:'pointer' }}>
          {hasPremium ? 'Ajouter du temps' : 'Activer Premium'}
        </button>
      </div>

      {showRedeem && <RedeemCodeModal onClose={() => setShowRedeem(false)} onSuccess={() => { setShowRedeem(false); refreshProfile(); }} />}

      {seriesList.map((series) => {
        const isOpen = openSeries === series.id;
        const seriesCases = casesBySeries[series.id] || [];
        const seriesProg = progress[series.id] || {};
        const doneCount = Object.values(seriesProg).filter(v=>v?.done).length;
        const isLocked = series.is_premium && !hasPremium;
        
        return (
          <div key={series.id} style={{ marginBottom:8 }}>
            <div onClick={() => setOpenSeries(isOpen ? null : series.id)} style={{ background:'var(--surface2)', border:`1.5px solid ${isOpen ? 'rgba(0,212,170,0.35)' : 'var(--border)'}`, borderRadius:isOpen?'var(--r) var(--r) 0 0':'var(--r)', padding:'14px 16px', cursor:'pointer', display:'flex', alignItems:'center', justifyContent:'space-between', transition:'all 0.18s' }}>
              <div style={{ display:'flex', alignItems:'center', gap:12 }}>
                <div style={{ width:36, height:36, borderRadius:8, background:'var(--surface3)', display:'flex', alignItems:'center', justifyContent:'center', fontSize:18 }}>
                  {series.icon === 'fungus' ? '🍄' : series.icon === 'mosquito' ? '🦟' : '📚'}
                </div>
                <div>
                  <div style={{ fontWeight:700, fontSize:15, display:'flex', alignItems:'center', gap:8, color:isLocked?'var(--text-muted)':'var(--text)' }}>
                    {series.title}
                    {series.is_premium && <span style={{ fontSize:10, background:isLocked?'var(--surface3)':'var(--amber-dim)', color:isLocked?'var(--text-muted)':'var(--amber)', padding:'2px 6px', borderRadius:6 }}>PREMIUM</span>}
                  </div>
                  <div style={{ fontSize:12, color:'var(--text-muted)', marginTop:2 }}>{series.description}</div>
                </div>
              </div>
              <div style={{ display:'flex', alignItems:'center', gap:8 }}>
                {isLocked ? (
                  <span style={{ fontSize:14, color:'var(--text-muted)' }}>🔒</span>
                ) : (
                  <>
                    <span style={{ fontFamily:'var(--mono)', fontSize:11, color:doneCount===seriesCases.length && seriesCases.length>0 ? 'var(--teal)' : 'var(--text-muted)' }}>{doneCount}/{seriesCases.length}</span>
                    <div style={{ transform:isOpen?'rotate(90deg)':'none', transition:'transform 0.2s', color:'var(--text-muted)', display:'flex' }}><Ico.right /></div>
                  </>
                )}
              </div>
            </div>
            
            {isOpen && (
              <div style={{ background:'var(--surface)', border:`1.5px solid rgba(0,212,170,0.35)`, borderTop:'none', borderRadius:'0 0 var(--r) var(--r)', overflow:'hidden' }}>
                {isLocked ? (
                  <div style={{ padding:'24px', textAlign:'center' }}>
                    <div style={{ fontSize:32, marginBottom:10 }}>🔒</div>
                    <div style={{ fontSize:14, fontWeight:600, color:'var(--text)', marginBottom:6 }}>Série Premium</div>
                    <div style={{ fontSize:12, color:'var(--text-dim)', marginBottom:16 }}>Vous devez activer un code premium pour accéder à ces cas cliniques.</div>
                    <button onClick={() => setShowRedeem(true)} style={{ background:'var(--teal-dim)', color:'var(--teal)', border:'none', padding:'8px 16px', borderRadius:8, fontSize:13, fontWeight:600, cursor:'pointer' }}>Activer un code</button>
                  </div>
                ) : seriesCases.length === 0 ? (
                  <div style={{ padding:'20px', textAlign:'center', color:'var(--text-muted)', fontSize:13 }}>Aucun cas disponible dans cette série pour le moment.</div>
                ) : seriesCases.map((c, ci) => {
                  const cd = c.content;
                  const prog = seriesProg[c.id] || {};
                  return (
                    <React.Fragment key={c.id}>
                      <div onClick={() => onSelectCase(c.id, series.id)}
                        style={{ padding:'13px 16px', borderTop:ci>0?'1px solid var(--border)':'none', cursor:'pointer', display:'flex', alignItems:'center', justifyContent:'space-between', transition:'background 0.12s' }}
                        onMouseEnter={e=>e.currentTarget.style.background='var(--surface2)'}
                        onMouseLeave={e=>e.currentTarget.style.background='transparent'}
                      >
                        <div style={{ display:'flex', alignItems:'center', gap:12 }}>
                          <div style={{ width:32, height:32, borderRadius:8, background:prog.done?`var(--teal-dim)`:'var(--surface3)', border:`1px solid ${prog.done?'var(--teal)':'var(--border)'}`, display:'flex', alignItems:'center', justifyContent:'center', flexShrink:0 }}>
                            {prog.done ? <span style={{color:'var(--teal)',display:'flex'}}><Ico.check /></span> : <span style={{ fontFamily:'var(--mono)', fontSize:12, color:'var(--text-muted)' }}>{ci+1}</span>}
                          </div>
                          <div>
                            <div style={{ fontSize:13.5, fontWeight:600 }}>{cd.title}</div>
                            <div style={{ fontSize:11, color:'var(--text-muted)', marginTop:2 }}>{cd.subtitle}</div>
                          </div>
                        </div>
                        {prog.bestScore !== undefined && (
                          <div style={{ background:prog.bestScore>=7?`var(--teal-dim)`:'var(--surface3)', border:`1px solid ${prog.bestScore>=7?'var(--teal)':'var(--border)'}`, borderRadius:8, padding:'4px 9px', fontFamily:'var(--mono)', fontSize:11, color:prog.bestScore>=7?'var(--teal)':'var(--text-muted)', flexShrink:0 }}>
                            {prog.bestScore}/10
                          </div>
                        )}
                      </div>
                      {cd.mirror && prog.done && (
                        <div onClick={() => onPlayMirror(c.id)} style={{ padding:'10px 16px 10px 60px', borderTop:'1px solid var(--border)', cursor:'pointer', display:'flex', alignItems:'center', gap:8, background:'rgba(139,111,191,0.04)', transition:'background 0.12s' }}
                          onMouseEnter={e=>e.currentTarget.style.background='rgba(139,111,191,0.09)'}
                          onMouseLeave={e=>e.currentTarget.style.background='rgba(139,111,191,0.04)'}
                        >
                          <span style={{ fontSize:12 }}>⚡</span>
                          <div style={{ flex:1 }}>
                            <div style={{ fontSize:11.5, color:'var(--purple)', fontWeight:600 }}>Cas miroir</div>
                            <div style={{ fontSize:10, color:'var(--text-muted)', marginTop:1 }}>{cd.mirror.twist_signal}</div>
                          </div>
                          <span style={{ fontFamily:'var(--mono)', fontSize:9, color:'var(--purple)', background:'rgba(139,111,191,0.15)', padding:'2px 7px', borderRadius:10 }}>MIROIR</span>
                        </div>
                      )}
                    </React.Fragment>
                  );
                })}
              </div>
            )}
          </div>
        );
      })}
    </div>
  );
};

// ─── CASE PLAYER ──────────────────────────────────────────────────────────
// Re-implemented to fetch CaseData from global CASES_DB.
const CasePlayer = ({ caseId, seriesId, onHome, onSaveProgress, onPlayMirror }) => {
  const caseData = window.CASES_DB[caseId];
  const [step, setStep] = React.useState(0);
  const [completedSteps, setCompletedSteps] = React.useState([]);
  const [scores, setScores] = React.useState([]);
  const [confidences, setConfidences] = React.useState({});
  const [extractedTags, setExtractedTags] = React.useState([]);
  const [finished, setFinished] = React.useState(false);
  const scrollRef = React.useRef(null);

  React.useEffect(() => { if (scrollRef.current) scrollRef.current.scrollTop = 0; }, [step]);

  const advance = (pts, conf, confKey) => {
    if (pts !== undefined) setScores(prev => [...prev, pts]);
    if (conf && confKey) setConfidences(prev => ({ ...prev, [confKey]:conf }));
    setCompletedSteps(prev => [...prev, step]);
    if (step >= 7) {
      setFinished(true);
    } else {
      setStep(step+1);
    }
  };

  const total = Math.round(scores.reduce((a,b)=>a+b,0)*10)/10;
  const lvlColor = 'var(--teal)'; // simplified for series

  React.useEffect(() => {
    if (finished) onSaveProgress(seriesId, caseId, total, extractedTags, confidences);
  }, [finished]);

  const restart = () => { setStep(0); setCompletedSteps([]); setScores([]); setConfidences({}); setExtractedTags([]); setFinished(false); };

  if (!caseData) return <div style={{ color:'var(--text)' }}>Chargement du cas...</div>;

  return (
    <div style={{ minHeight:'100vh', background:'var(--bg)', display:'flex', flexDirection:'column', alignItems:'center' }}>
      <div className="app-container">
        <div style={{ padding:'11px 18px 9px', background:'rgba(8,15,30,0.96)', backdropFilter:'blur(14px)', borderBottom:'1px solid var(--border)', position:'sticky', top:0, zIndex:10 }}>
          <div style={{ display:'flex', alignItems:'center', justifyContent:'space-between', marginBottom:9 }}>
            <div style={{ display:'flex', alignItems:'center', gap:6 }}>
              <button onClick={onHome} style={{ background:'none', border:'none', color:'var(--text-muted)', cursor:'pointer', fontSize:18, lineHeight:1, padding:'0 6px 0 0' }}>←</button>
              <div>
                <div style={{ display:'flex', alignItems:'center', gap:7 }}>
                  <span style={{ fontFamily:'var(--mono)', fontSize:10, fontWeight:700, color:'var(--teal)', letterSpacing:'0.12em' }}>PHUTURISTIC</span>
                </div>
                <div style={{ fontSize:12.5, fontWeight:600, marginTop:2 }}>{caseData.title}</div>
              </div>
            </div>
            {!finished && <div style={{ background:'var(--surface2)', border:'1px solid var(--border)', borderRadius:8, padding:'3px 9px', fontFamily:'var(--mono)', fontSize:10, color:'var(--text-muted)' }}>{step}/7</div>}
          </div>
          {!finished && <WaterfallProgress current={step} done={completedSteps} />}
        </div>

        <div ref={scrollRef} style={{ flex:1, padding:'16px 18px 90px', overflowY:'auto' }}>
          {finished ? (
            <ResultsScreen caseData={caseData} scores={scores} onRestart={restart} onHome={onHome} onPlayMirror={onPlayMirror} />
          ) : step===0 ? <Step0 caseData={caseData} onContinue={() => advance(undefined)} />
            : step===1 ? <Step0b key="s0b" caseData={caseData} onComplete={tags => { setExtractedTags(tags); advance(undefined); }} />
            : step===2 ? <Step1 key="s1" caseData={caseData} extractedTags={extractedTags} onComplete={(pts,conf) => advance(pts,conf,'step1_conf')} />
            : step===3 ? <Step1b key="s1b" caseData={caseData} onComplete={(pts,conf) => advance(pts,conf,'step1b_conf')} />
            : step===4 ? <Step2 key="s2" caseData={caseData} onComplete={(pts,conf) => advance(pts,conf,'step2_conf')} />
            : step===5 ? <Step3 key="s3" caseData={caseData} onComplete={(pts,conf) => advance(pts,conf,'step3_conf')} />
            : step===6 ? <Step4 key="s4" caseData={caseData} onComplete={(pts,conf) => advance(pts,conf,'step4_conf')} />
            : <Step5Debrief key="s5" caseData={caseData} extractedTags={extractedTags} confidences={confidences} scores={scores} onComplete={pts => advance(pts)} />
          }
        </div>

        {!finished && scores.length > 0 && (
          <div style={{ position:'sticky', bottom:0, background:'rgba(8,15,30,0.96)', backdropFilter:'blur(12px)', borderTop:'1px solid var(--border)', padding:'8px 18px', display:'flex', alignItems:'center', justifyContent:'space-between' }}>
            <span style={{ fontSize:9, color:'var(--text-muted)', fontFamily:'var(--mono)' }}>SCORE</span>
            <div style={{ display:'flex', gap:4, alignItems:'center' }}>
              {scores.map((s,i) => {
                const mx=[2,1,3,3,2][i]||1;
                return <div key={i} style={{ background:'var(--surface2)', border:'1px solid var(--border)', borderRadius:5, padding:'2px 6px', fontFamily:'var(--mono)', fontSize:10, color:s/mx>=0.8?'var(--green)':s/mx>=0.5?'var(--amber)':'var(--red)' }}>{s}</div>;
              })}
              <div style={{ background:'var(--blue-dim)', border:'1px solid rgba(59,130,246,0.22)', borderRadius:5, padding:'2px 8px', fontFamily:'var(--mono)', fontSize:11, fontWeight:700, color:'var(--blue)' }}>Σ {total}/10</div>
            </div>
          </div>
        )}
      </div>
    </div>
  );
};

// ─── MAIN APP ─────────────────────────────────────────────────────────────
const TWEAK_DEFAULTS = { "accentColor": "#00D4AA", "showProgress": true, "typewriterSpeed": 1 };

const App = () => {
  const { tweaks = TWEAK_DEFAULTS, setTweak } = useTweaks(TWEAK_DEFAULTS);
  const [session, setSession] = React.useState(null);
  const [studentProfile, setStudentProfile] = React.useState(null);
  const [screen, setScreen] = React.useState('home');
  const [activeCaseId, setActiveCaseId] = React.useState(null);
  const [activeSeriesId, setActiveSeriesId] = React.useState(null);
  const [activeMirrorParentId, setActiveMirrorParentId] = React.useState(null);
  
  const [loading, setLoading] = React.useState(true);
  const [seriesList, setSeriesList] = React.useState([]);
  const [casesBySeries, setCasesBySeries] = React.useState({});
  
  const [progress, setProgress] = React.useState(() => {
    try { return JSON.parse(localStorage.getItem('ph_progress_v3')||'{}'); } catch { return {}; }
  });

  // Init Auth
  React.useEffect(() => {
    window.supabase.auth.getSession().then(({ data: { session } }) => {
      setSession(session);
    });

    const { data: { subscription } } = window.supabase.auth.onAuthStateChange((_event, session) => {
      setSession(session);
    });

    return () => subscription.unsubscribe();
  }, []);

  // Fetch Data when authenticated
  const fetchStudentData = async () => {
    setLoading(true);
    try {
      // Fetch Profile
      const { data: profile } = await window.supabase
        .from('student_profiles')
        .select('*')
        .eq('id', session.user.id)
        .single();
      if (profile) setStudentProfile(profile);

      // Fetch Series
      const { data: series } = await window.supabase
        .from('series')
        .select('*')
        .order('created_at', { ascending: true });
      
      // Fetch Cases (Only published ones, with series_id)
      const { data: cases } = await window.supabase
        .from('cases')
        .select('id, series_id, content')
        .eq('status', 'published');

      if (series) setSeriesList(series);
      if (cases) {
        window.CASES_DB = {};
        const bySeries = {};
        cases.forEach(c => {
          window.CASES_DB[c.id] = c.content;
          if (!bySeries[c.series_id]) bySeries[c.series_id] = [];
          bySeries[c.series_id].push(c);
        });
        setCasesBySeries(bySeries);
      }
    } catch (err) {
      console.error('Error fetching data:', err);
    } finally {
      setLoading(false);
    }
  };

  React.useEffect(() => {
    if (!session) {
      setLoading(false);
      return;
    }
    fetchStudentData();
  }, [session]);

  const saveProgress = async (seriesId, cid, score, extractedTags = [], mistakes = {}) => {
    setProgress(prev => {
      const next = { ...prev, [seriesId]:{ ...(prev[seriesId]||{}), [cid]:{ done:score>=7, bestScore:Math.max(score,(prev[seriesId]?.[cid]?.bestScore||0)) } } };
      localStorage.setItem('ph_progress_v3', JSON.stringify(next));
      return next;
    });
    
    // Save to student_sessions table in Supabase
    if (session) {
      try {
        await window.supabase.from('student_sessions').insert({
          student_id: session.user.id,
          case_id: cid,
          score: score,
          extracted_tags: extractedTags,
          mistakes: mistakes,
          completed_at: new Date().toISOString()
        });
      } catch (err) {
        console.error("Failed to save session to DB", err);
      }
    }
  };

  const handleLogout = async () => {
    await window.supabase.auth.signOut();
  };

  if (loading) {
    return <div style={{ minHeight:'100vh', display:'flex', alignItems:'center', justifyContent:'center', color:'var(--text)', background:'var(--bg)' }}>Chargement...</div>;
  }

  if (!session) {
    return <AuthModal onLogin={() => {}} />;
  }

  return (
    <div style={{ minHeight:'100vh', background:'var(--bg)' }}>
      {screen==='home' && (
        <div className="app-container" style={{ padding:'0 18px 80px', display:'block', minHeight:'auto' }}>
          <SeriesDashboard 
            seriesList={seriesList} 
            casesBySeries={casesBySeries} 
            progress={progress}
            studentProfile={studentProfile}
            onLogout={handleLogout}
            refreshProfile={fetchStudentData}
            onSelectCase={(cid, sid) => { setActiveCaseId(cid); setActiveSeriesId(sid); setScreen('case'); }} 
            onPlayMirror={(cid) => { setActiveMirrorParentId(cid); setScreen('mirror'); }} 
          />
        </div>
      )}
      {screen==='case' && activeCaseId && (
        <CasePlayer
          caseId={activeCaseId}
          seriesId={activeSeriesId}
          onHome={() => { setScreen('home'); setActiveCaseId(null); setActiveSeriesId(null); }}
          onSaveProgress={saveProgress}
          onPlayMirror={(cid) => { setActiveMirrorParentId(cid); setScreen('mirror'); }} 
        />
      )}
      {screen==='mirror' && activeMirrorParentId && window.CASES_DB[activeMirrorParentId]?.mirror && (
        <MirrorPlayer
          mirrorData={window.CASES_DB[activeMirrorParentId].mirror}
          parentCaseData={window.CASES_DB[activeMirrorParentId]}
          onHome={() => { setScreen('home'); setActiveMirrorParentId(null); }}
        />
      )}
      
      <TweaksPanel>
        <TweakColor id="accentColor" label="Couleur accent" value={tweaks.accentColor} onChange={v=>setTweak('accentColor',v)} />
        <TweakToggle id="showProgress" label="Barre de progression" value={tweaks.showProgress} onChange={v=>setTweak('showProgress',v)} />
        <TweakSlider id="typewriterSpeed" label="Vitesse typewriter (×)" min={0.5} max={3} step={0.5} value={tweaks.typewriterSpeed} onChange={v=>setTweak('typewriterSpeed',v)} />
      </TweaksPanel>
    </div>
  );
};

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