// app.jsx — Aldene IA — vidéo salon
// Composes all scenes inside a <Stage> timeline.

const TWEAK_DEFAULTS = /*EDITMODE-BEGIN*/{
  "speed": 1.0,
  "loop": true,
  "showChrome": true,
  "showPlaybackBar": false,
  "scenesEnabled": {
    "opener":       true,
    "promise":      true,
    "portail":      true,
    "openwebui":    true,
    "trimail":      true,
    "three_cx":     true,
    "dash_support": true,
    "tampon":       true,
    "s2f":          true,
    "n8n":          true,
    "aldene_ai":    true,
    "diag_ia":      true,
    "live_cyber":   true,
    "quick_ia":     true,
    "quick_repo":   true,
    "quick_codial": true,
    "quick_metier": true,
    "stats":        true,
    "outro":        true
  }
}/*EDITMODE-END*/;

// Scene timing (seconds). Heroes 11s, quick pages 10s, stats 12s, outro 13.5s.
// 0.5s overlap (1.5s opener→promise) for soft cross-fades.
// Total runtime ≈ 197s (3:17).
const SCENES = [
  // intro (slower)
  { id: 'opener',       start:   0.0, end:  10.0, label: '01 · Opener'             },
  { id: 'promise',      start:   8.5, end:  19.5, label: '02 · Aldene IA'           },

  // hero apps — 11s each
  { id: 'portail',      start:  19.0, end:  30.0, label: '03 · Portail'             },
  { id: 'openwebui',    start:  29.5, end:  40.5, label: '04 · ChatGPT Interne'     },
  { id: 'trimail',      start:  40.0, end:  51.0, label: '05 · Tri Mail IA'         },
  { id: 'three_cx',     start:  50.5, end:  61.5, label: '06 · 3CX Transcript'      },
  { id: 'dash_support', start:  61.0, end:  72.0, label: '07 · Dashboard Support'   },
  { id: 'tampon',       start:  71.5, end:  82.5, label: '08 · Tampon Facture'      },
  { id: 's2f',          start:  82.0, end:  93.0, label: '09 · Suivi Factures'      },
  { id: 'n8n',          start:  92.5, end: 103.5, label: '10 · n8n Workflows'       },
  { id: 'aldene_ai',    start: 103.0, end: 114.0, label: '11 · Aldene AI'           },
  { id: 'diag_ia',      start: 113.5, end: 124.5, label: '12 · Diagnostic IA'       },
  { id: 'live_cyber',   start: 124.0, end: 135.0, label: '13 · Live Cyber'          },

  // quick pages — 10s each
  { id: 'quick_ia',     start: 134.5, end: 144.5, label: '14 · IA · Suite'          },
  { id: 'quick_repo',   start: 144.0, end: 154.0, label: '15 · Reporting'           },
  { id: 'quick_codial', start: 153.5, end: 163.5, label: '16 · ERP & Compta'        },
  { id: 'quick_metier', start: 163.0, end: 173.0, label: '17 · Métier & Infra'      },

  // closing
  { id: 'stats',        start: 172.5, end: 184.5, label: '18 · Résultats'           },
  { id: 'outro',        start: 184.0, end: 197.5, label: '19 · CTA'                 },
];

const TOTAL_DURATION = 197.5; // seconds

const CONTACT = {
  phone:  '04 50 58 14 45',
  web:    'aldene.ai',
  cities: 'Sallanches · Seynod · Saint-Vulbas',
};

// ─────────────────────────────────────────────────────────────────────────
// SceneRouter — picks which scene component to render
// ─────────────────────────────────────────────────────────────────────────
function SceneRouter({ id }) {
  switch (id) {
    case 'opener':       return <SceneOpener/>;
    case 'promise':      return <ScenePromise/>;
    case 'portail':      return <SceneAppPortail/>;
    case 'openwebui':    return <SceneAppOpenWebUI/>;
    case 'trimail':      return <SceneAppTriMail/>;
    case 'three_cx':     return <SceneApp3CX/>;
    case 'dash_support': return <SceneAppDashboardSupport/>;
    case 'tampon':       return <SceneAppTamponFacture/>;
    case 's2f':          return <SceneAppS2F/>;
    case 'n8n':          return <SceneAppN8N/>;
    case 'aldene_ai':    return <SceneAppAldeneAI/>;
    case 'diag_ia':      return <SceneAppDiagnosticIA/>;
    case 'live_cyber':   return <SceneAppLiveCyber/>;
    case 'quick_ia':     return <SceneQuickIA/>;
    case 'quick_repo':   return <SceneQuickReporting/>;
    case 'quick_codial': return <SceneQuickCodial/>;
    case 'quick_metier': return <SceneQuickMetier/>;
    case 'stats':        return <SceneStats/>;
    case 'outro':        return <SceneOutro contact={CONTACT}/>;
    default: return null;
  }
}

// ─────────────────────────────────────────────────────────────────────────
// Persistent header strip — mini logo + scene counter + progress bar.
// Hidden during opener / promise / outro.
// ─────────────────────────────────────────────────────────────────────────
function PersistentChrome({ showChrome }) {
  const t = useTime();
  const inIntro = t < 19.5;
  const inOutro = t > 184.0;
  const visible = showChrome && !inIntro && !inOutro;

  const cur = SCENES.find(s => t >= s.start && t < s.end) || SCENES[SCENES.length - 1];

  return (
    <>
      {/* Top strip */}
      <div style={{
        position: 'absolute',
        top: 28, left: 56, right: 56,
        display: 'flex', alignItems: 'center',
        zIndex: 10, pointerEvents: 'none',
        opacity: visible ? 1 : 0,
        transition: 'opacity 280ms cubic-bezier(.2,.7,.2,1)',
      }}>
        <div style={{ display: 'flex', alignItems: 'center', gap: 14 }}>
          <AldeneWordmark height={28} drawProgress={1} dotPop={1}/>
        </div>
        <div style={{ flex: 1 }}/>
        <div style={{
          display: 'flex', alignItems: 'center', gap: 12,
          fontFamily: FONT_DISPLAY, fontWeight: 700, fontSize: 11,
          letterSpacing: '.18em', textTransform: 'uppercase',
          color: 'rgba(255,255,255,.55)',
        }}>
          <span style={{ color: ALD.yellow }}>{cur.label.split(' · ')[0]}</span>
          <span>{cur.label.split(' · ')[1]}</span>
        </div>
      </div>

      {/* Bottom progress bar */}
      <div style={{
        position: 'absolute', bottom: 28, left: 56, right: 56,
        display: 'flex', gap: 4,
        opacity: visible ? 1 : 0,
        transition: 'opacity 280ms cubic-bezier(.2,.7,.2,1)',
        pointerEvents: 'none',
        zIndex: 10,
      }}>
        {SCENES.map(s => {
          const active = t >= s.start && t < s.end;
          const passed = t >= s.end;
          return (
            <div key={s.id} style={{
              flex: 1, height: 3,
              background: passed ? ALD.yellow : 'rgba(255,255,255,.10)',
              borderRadius: 2,
              position: 'relative', overflow: 'hidden',
            }}>
              {active && (
                <div style={{
                  position: 'absolute', inset: 0,
                  background: ALD.yellow,
                  transform: `scaleX(${Math.max(0, Math.min(1, (t - s.start) / (s.end - s.start)))})`,
                  transformOrigin: 'left',
                }}/>
              )}
            </div>
          );
        })}
      </div>
    </>
  );
}

// ─────────────────────────────────────────────────────────────────────────
// Video composition — wrap each scene in a Sprite + chrome
// ─────────────────────────────────────────────────────────────────────────
function VideoComposition({ scenesEnabled, showChrome }) {
  return (
    <>
      {SCENES.filter(s => scenesEnabled[s.id]).map(s => (
        <Sprite key={s.id} start={s.start} end={s.end}>
          <SceneRouter id={s.id}/>
        </Sprite>
      ))}
      <PersistentChrome showChrome={showChrome}/>
    </>
  );
}

// ─────────────────────────────────────────────────────────────────────────
// TimeScaler — speed multiplier wrapper
// ─────────────────────────────────────────────────────────────────────────
function TimeScaler({ from, to, children }) {
  const ctx = React.useContext(TimelineContext);
  const ratio = to / from;
  const scaled = React.useMemo(() => ({
    ...ctx,
    time: ctx.time * ratio,
    duration: to,
  }), [ctx.time, ratio, to]);

  return (
    <TimelineContext.Provider value={scaled}>
      {children}
    </TimelineContext.Provider>
  );
}

// ─────────────────────────────────────────────────────────────────────────
// App root
// ─────────────────────────────────────────────────────────────────────────
function App() {
  const [tweaks, setTweak] = useTweaks(TWEAK_DEFAULTS);
  const { speed, scenesEnabled, showChrome, loop, showPlaybackBar } = tweaks;

  const effectiveDuration = TOTAL_DURATION / Math.max(0.25, speed);

  return (
    <Stage
      width={1920}
      height={1080}
      duration={effectiveDuration}
      background={ALD.navy}
      loop={loop}
      persistKey="aldene-salon-video"
      showPlaybackBar={showPlaybackBar}
      letterboxColor={ALD.navy}
    >
      <TimeScaler from={effectiveDuration} to={TOTAL_DURATION}>
        <VideoComposition
          scenesEnabled={scenesEnabled}
          showChrome={showChrome}
        />
      </TimeScaler>
      <TweakControls tweaks={tweaks} setTweak={setTweak}/>
    </Stage>
  );
}

// ─────────────────────────────────────────────────────────────────────────
// Tweaks panel
// ─────────────────────────────────────────────────────────────────────────
function TweakControls({ tweaks, setTweak }) {
  const setScene = (id, v) => {
    setTweak('scenesEnabled', { ...tweaks.scenesEnabled, [id]: v });
  };

  return (
    <TweaksPanel title="Tweaks · Vidéo Aldene IA">
      <TweakSection label="Lecture"/>
      <TweakSlider
        label="Vitesse"
        value={tweaks.speed}
        min={0.5} max={2.5} step={0.05}
        unit="×"
        onChange={(v) => setTweak('speed', v)}
      />
      <TweakToggle
        label="Boucle"
        value={tweaks.loop}
        onChange={(v) => setTweak('loop', v)}
      />
      <TweakToggle
        label="Chrome (logo + progression)"
        value={tweaks.showChrome}
        onChange={(v) => setTweak('showChrome', v)}
      />
      <TweakToggle
        label="Barre de lecture (timer + scrub)"
        value={tweaks.showPlaybackBar}
        onChange={(v) => setTweak('showPlaybackBar', v)}
      />

      <TweakSection label="Scènes activées"/>
      {SCENES.map(s => (
        <TweakToggle
          key={s.id}
          label={s.label}
          value={!!tweaks.scenesEnabled[s.id]}
          onChange={(v) => setScene(s.id, v)}
        />
      ))}

      <TweakSection label="Raccourcis"/>
      <div style={{
        fontSize: 11, color: 'rgba(41,38,27,.5)',
        fontFamily: 'ui-sans-serif, system-ui, sans-serif',
        lineHeight: 1.6,
      }}>
        <div><b>Espace</b> — pause / lecture</div>
        <div><b>← →</b> — chapitrer (1s, 10s avec Shift)</div>
        <div><b>0</b> — retour début</div>
      </div>
    </TweaksPanel>
  );
}

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