// Custom video player with chapter markers, aspect toggle, and integrated playback
function ChispaVideoPlayer() {
  const TOTAL_DURATION = 54;
  const [time, setTime] = React.useState(0);
  const [playing, setPlaying] = React.useState(true);
  const [aspect, setAspect] = React.useState('16:9'); // 16:9, 9:16, 1:1
  const [isFullscreen, setIsFullscreen] = React.useState(false);
  const playerRef = React.useRef(null);

  const toggleFullscreen = React.useCallback(() => {
    const el = playerRef.current;
    if (!el) return;
    if (!document.fullscreenElement) {
      (el.requestFullscreen?.() || el.webkitRequestFullscreen?.() || el.msRequestFullscreen?.());
    } else {
      (document.exitFullscreen?.() || document.webkitExitFullscreen?.() || document.msExitFullscreen?.());
    }
  }, []);

  React.useEffect(() => {
    const onFsChange = () => setIsFullscreen(!!document.fullscreenElement);
    document.addEventListener('fullscreenchange', onFsChange);
    document.addEventListener('webkitfullscreenchange', onFsChange);
    return () => {
      document.removeEventListener('fullscreenchange', onFsChange);
      document.removeEventListener('webkitfullscreenchange', onFsChange);
    };
  }, []);
  const [showSubs, setShowSubs] = React.useState(true);
  const [speed, setSpeed] = React.useState(1);
  const [pacing, setPacing] = React.useState('full'); // full or fast
  const [primaryHue, setPrimaryHue] = React.useState(28); // base orange hue
  const [recording, setRecording] = React.useState(false);
  const [recordProgress, setRecordProgress] = React.useState(0);
  const rafRef = React.useRef(null);
  const lastTsRef = React.useRef(null);
  const stageRef = React.useRef(null);
  const stageInnerRef = React.useRef(null);
  const [scale, setScale] = React.useState(1);

  // Record video using html2canvas + MediaRecorder
  const recordVideo = React.useCallback(async () => {
    if (recording) return;
    if (!window.html2canvas) {
      alert('Cargando html2canvas... espera un momento e intenta de nuevo.');
      return;
    }
    setRecording(true);
    setPlaying(false);
    setTime(0);

    const SCENE_W = STAGE_W;
    const SCENE_H = STAGE_H;
    const FPS = 24;
    const frameInterval = 1000 / FPS;

    // Output canvas at native resolution
    const outCanvas = document.createElement('canvas');
    outCanvas.width = SCENE_W;
    outCanvas.height = SCENE_H;
    const outCtx = outCanvas.getContext('2d');

    const stream = outCanvas.captureStream(FPS);
    // Try MP4 (H.264) first — Chrome 117+, Edge, Safari. Fall back to WebM.
    const mp4Candidates = [
      'video/mp4;codecs=avc1.42E01E',  // H.264 baseline
      'video/mp4;codecs=avc1.4D401F',  // H.264 main
      'video/mp4',
    ];
    const webmCandidates = [
      'video/webm;codecs=vp9',
      'video/webm;codecs=vp8',
      'video/webm',
    ];
    let mimeType = null;
    for (const m of [...mp4Candidates, ...webmCandidates]) {
      if (MediaRecorder.isTypeSupported(m)) { mimeType = m; break; }
    }
    const isMp4 = mimeType && mimeType.startsWith('video/mp4');
    const recorder = new MediaRecorder(stream, { mimeType, videoBitsPerSecond: 8000000 });
    const chunks = [];
    recorder.ondataavailable = (e) => { if (e.data.size > 0) chunks.push(e.data); };

    const finished = new Promise(resolve => { recorder.onstop = resolve; });
    recorder.start();

    // Wait for next paint then capture frame-by-frame
    const totalFrames = Math.ceil(TOTAL_DURATION * FPS);
    for (let i = 0; i <= totalFrames; i++) {
      const t = (i / FPS);
      setTime(t);
      setRecordProgress(t / TOTAL_DURATION);
      // Wait two RAFs for React to render
      await new Promise(r => requestAnimationFrame(() => requestAnimationFrame(r)));
      try {
        const inner = stageInnerRef.current;
        if (!inner) break;
        const snap = await window.html2canvas(inner, {
          backgroundColor: '#000',
          width: SCENE_W,
          height: SCENE_H,
          scale: 1,
          useCORS: true,
          logging: false,
        });
        outCtx.fillStyle = '#000';
        outCtx.fillRect(0, 0, SCENE_W, SCENE_H);
        outCtx.drawImage(snap, 0, 0, SCENE_W, SCENE_H);
      } catch (err) {
        console.error('Frame capture failed', err);
      }
      // Pace to FPS
      await new Promise(r => setTimeout(r, Math.max(0, frameInterval - 16)));
    }

    recorder.stop();
    await finished;
    const ext = isMp4 ? 'mp4' : 'webm';
    const blob = new Blob(chunks, { type: isMp4 ? 'video/mp4' : 'video/webm' });
    const url = URL.createObjectURL(blob);
    const a = document.createElement('a');
    a.href = url;
    const aspectLabel = aspect.replace(':', 'x');
    a.download = `chispa-promo-${aspectLabel}.${ext}`;
    document.body.appendChild(a);
    a.click();
    document.body.removeChild(a);
    URL.revokeObjectURL(url);

    setRecording(false);
    setRecordProgress(0);
    setTime(0);
  }, [recording, aspect, STAGE_W, STAGE_H]);

  // Speed multiplier from pacing
  const effectiveSpeed = pacing === 'fast' ? speed * 2 : speed;

  React.useEffect(() => {
    window.__chispaSubsOn = showSubs;
  }, [showSubs]);

  // Expose recording trigger globally so devs can run window.recordChispa()
  // from the console without needing a visible button in the player chrome.
  React.useEffect(() => {
    window.recordChispa = recordVideo;
    window.setChispaAspect = (a) => { if (['16:9','9:16','1:1'].includes(a)) setAspect(a); };
    return () => {
      if (window.recordChispa === recordVideo) delete window.recordChispa;
    };
  }, [recordVideo]);

  // Animation loop
  React.useEffect(() => {
    if (!playing) {
      lastTsRef.current = null;
      return;
    }
    const step = (ts) => {
      if (lastTsRef.current == null) lastTsRef.current = ts;
      const dt = ((ts - lastTsRef.current) / 1000) * effectiveSpeed;
      lastTsRef.current = ts;
      setTime(t => {
        let next = t + dt;
        if (next >= TOTAL_DURATION) next = next % TOTAL_DURATION;
        return next;
      });
      rafRef.current = requestAnimationFrame(step);
    };
    rafRef.current = requestAnimationFrame(step);
    return () => {
      if (rafRef.current) cancelAnimationFrame(rafRef.current);
      lastTsRef.current = null;
    };
  }, [playing, effectiveSpeed]);

  // Each aspect has its own canonical authoring size + dedicated scenes.
  // 16:9 → 1920x1080 wide-format scenes (Act1Problem, Act2Solution, ...)
  // 9:16 → 1080x1920 portrait scenes (Act1ProblemV, Act2SolutionV, ...)
  // 1:1  → uses 9:16 portrait composition cropped/contained (still fills cleanly)
  const isVertical = aspect === '9:16';
  const isSquare = aspect === '1:1';
  const STAGE_W = isVertical ? 1080 : isSquare ? 1080 : 1920;
  const STAGE_H = isVertical ? 1920 : isSquare ? 1080 : 1080;

  React.useEffect(() => {
    if (!stageRef.current) return;
    const el = stageRef.current;
    const measure = () => {
      const s = Math.min(
        el.clientWidth / STAGE_W,
        el.clientHeight / STAGE_H
      );
      setScale(Math.max(0.05, s));
    };
    measure();
    const ro = new ResizeObserver(measure);
    ro.observe(el);
    return () => ro.disconnect();
  }, [aspect, STAGE_W, STAGE_H]);

  // Keyboard
  React.useEffect(() => {
    const onKey = (e) => {
      if (e.target && (e.target.tagName === 'INPUT' || e.target.tagName === 'TEXTAREA')) return;
      if (e.code === 'Space') {
        e.preventDefault();
        setPlaying(p => !p);
      } else if (e.code === 'ArrowLeft') {
        setTime(t => Math.max(0, t - 1));
      } else if (e.code === 'ArrowRight') {
        setTime(t => Math.min(TOTAL_DURATION, t + 1));
      }
    };
    window.addEventListener('keydown', onKey);
    return () => window.removeEventListener('keydown', onKey);
  }, []);

  const acts = [
    { id: 1, name: 'Problema', start: 0, end: 5.0 },
    { id: 2, name: 'Solución', start: 5.0, end: 20.0 },
    { id: 3, name: 'IA aprende', start: 20.0, end: 32.0 },
    { id: 4, name: 'Resultados', start: 32.0, end: 42.0 },
    { id: 5, name: 'CTA', start: 42.0, end: 54.0 },
  ];
  const currentAct = acts.find(a => time >= a.start && time < a.end) || acts[0];

  const ctxValue = { time, duration: TOTAL_DURATION, playing, setTime, setPlaying };
  const primaryColor = `oklch(63% 0.18 ${primaryHue})`;
  const accentColor = `oklch(72% 0.16 ${primaryHue + 20})`;

  return (
    <div style={{ width: '100%', display: 'flex', flexDirection: 'column', gap: 16 }}>
      {/* Player chrome */}
      <div ref={playerRef} style={{ position: 'relative', width: '100%', background: '#000', borderRadius: isFullscreen ? 0 : 18, overflow: 'hidden', border: isFullscreen ? 'none' : '1px solid rgba(255,255,255,0.08)', display: 'flex', flexDirection: 'column', height: isFullscreen ? '100vh' : 'auto' }}>
        {/* Video stage — outer container takes the chosen aspect; stage scales to FIT inside */}
        <div ref={stageRef} style={{
          width: '100%',
          aspectRatio: isFullscreen ? 'unset' : (aspect === '9:16' ? '9/16' : aspect === '1:1' ? '1/1' : '16/9'),
          flex: isFullscreen ? '1 1 auto' : 'unset',
          maxHeight: isFullscreen ? 'unset' : (aspect === '9:16' ? 760 : 'unset'),
          background: '#000',
          position: 'relative',
          display: 'flex', alignItems: 'center', justifyContent: 'center',
          overflow: 'hidden',
          margin: isFullscreen ? 0 : (aspect === '9:16' ? '0 auto' : 0),
          maxWidth: isFullscreen ? 'unset' : (aspect === '9:16' ? 428 : 'unset'),
        }}>
          {/* Canonical stage, scaled to fit the container */}
          <div ref={stageInnerRef} style={{
            width: STAGE_W, height: STAGE_H,
            transform: `scale(${scale})`, transformOrigin: 'center',
            position: 'relative',
            flexShrink: 0,
            background: '#000',
          }}>
            <TimelineContext.Provider value={ctxValue}>
              {isVertical || isSquare ? (
                <React.Fragment>
                  <Act1ProblemV />
                  <Act2SolutionV />
                  <Act3AIV />
                  <Act4ResultsV />
                  <Act5CTAV />
                </React.Fragment>
              ) : (
                <React.Fragment>
                  <Act1Problem />
                  <Act2Solution />
                  <Act3AI />
                  <Act4Results />
                  <Act5CTA />
                </React.Fragment>
              )}
            </TimelineContext.Provider>
          </div>

          {/* Aspect toggle removed from UI — use window.setChispaAspect('16:9' | '9:16' | '1:1') from console */}
        </div>

        {/* Recording overlay */}
        {recording && (
          <div style={{ position: 'absolute', inset: 0, background: 'rgba(0,0,0,0.85)', backdropFilter: 'blur(6px)', display: 'flex', alignItems: 'center', justifyContent: 'center', zIndex: 200, flexDirection: 'column', gap: 18 }}>
            <div style={{ display: 'flex', alignItems: 'center', gap: 10, padding: '8px 16px', background: 'rgba(234,88,12,0.15)', border: '1px solid rgba(234,88,12,0.4)', borderRadius: 999 }}>
              <div style={{ width: 10, height: 10, borderRadius: 5, background: '#EA580C', animation: 'chispaPulse 1s infinite' }} />
              <span style={{ fontFamily: 'JetBrains Mono, monospace', fontSize: 13, color: '#F59E0B', letterSpacing: '0.08em', textTransform: 'uppercase' }}>Grabando · {Math.round(recordProgress*100)}%</span>
            </div>
            <div style={{ width: 360, height: 4, background: 'rgba(255,255,255,0.1)', borderRadius: 2, overflow: 'hidden' }}>
              <div style={{ width: `${recordProgress*100}%`, height: '100%', background: 'linear-gradient(90deg, #EA580C, #F59E0B)', transition: 'width 100ms' }} />
            </div>
            <div style={{ fontFamily: 'Inter, system-ui, sans-serif', fontSize: 13, color: 'rgba(255,255,255,0.5)', maxWidth: 380, textAlign: 'center', lineHeight: 1.5 }}>
              Renderizando frame por frame. Tarda ~2-3 minutos. No cierres la pestaña.
            </div>
          </div>
        )}
        <style>{`@keyframes chispaPulse { 0%,100% { opacity: 1; } 50% { opacity: 0.3; } }`}</style>

        {/* Custom playback bar */}
        <PlaybackBar
          time={time} duration={TOTAL_DURATION}
          playing={playing}
          setPlaying={setPlaying}
          setTime={setTime}
          acts={acts}
          showSubs={showSubs}
          setShowSubs={setShowSubs}
          speed={speed}
          setSpeed={setSpeed}
          pacing={pacing}
          setPacing={setPacing}
          primaryColor={primaryColor}
          onRecord={recordVideo}
          recording={recording}
          isFullscreen={isFullscreen}
          onToggleFullscreen={toggleFullscreen}
        />
      </div>
    </div>
  );
}

function PlaybackBar({ time, duration, playing, setPlaying, setTime, acts, showSubs, setShowSubs, speed, setSpeed, pacing, setPacing, primaryColor, onRecord, recording, isFullscreen, onToggleFullscreen }) {
  const trackRef = React.useRef(null);
  const [dragging, setDragging] = React.useState(false);

  const seek = (e) => {
    const rect = trackRef.current.getBoundingClientRect();
    const x = Math.max(0, Math.min(1, (e.clientX - rect.left) / rect.width));
    setTime(x * duration);
  };

  React.useEffect(() => {
    if (!dragging) return;
    const onMove = (e) => seek(e);
    const onUp = () => setDragging(false);
    window.addEventListener('mousemove', onMove);
    window.addEventListener('mouseup', onUp);
    return () => {
      window.removeEventListener('mousemove', onMove);
      window.removeEventListener('mouseup', onUp);
    };
  }, [dragging]);

  const fmt = (t) => {
    const m = Math.floor(t / 60);
    const s = Math.floor(t % 60);
    return `${m}:${String(s).padStart(2, '0')}`;
  };

  const pct = (time / duration) * 100;

  return (
    <div style={{ background: '#0a0a0a', padding: '14px 20px', borderTop: '1px solid rgba(255,255,255,0.06)' }}>
      {/* Scrub bar */}
      <div style={{ display: 'flex', alignItems: 'center', gap: 14 }}>
        <button onClick={() => setPlaying(p => !p)} style={{
          width: 36, height: 36, borderRadius: 18,
          background: primaryColor,
          border: 'none', color: '#fff',
          cursor: 'pointer',
          display: 'flex', alignItems: 'center', justifyContent: 'center',
          flexShrink: 0,
        }}>
          {playing ? (
            <svg width="14" height="14" viewBox="0 0 14 14"><rect x="3" y="2" width="3" height="10" fill="#fff"/><rect x="8" y="2" width="3" height="10" fill="#fff"/></svg>
          ) : (
            <svg width="14" height="14" viewBox="0 0 14 14"><path d="M3 2l9 5-9 5V2z" fill="#fff"/></svg>
          )}
        </button>

        <div style={{ fontFamily: 'JetBrains Mono, monospace', fontSize: 12, color: 'rgba(255,255,255,0.85)', fontVariantNumeric: 'tabular-nums', minWidth: 36 }}>
          {fmt(time)}
        </div>

        <div
          ref={trackRef}
          onMouseDown={(e) => { setDragging(true); seek(e); }}
          style={{ flex: 1, height: 18, position: 'relative', cursor: 'pointer', display: 'flex', alignItems: 'center' }}
        >
          <div style={{ position: 'absolute', left: 0, right: 0, height: 4, background: 'rgba(255,255,255,0.1)', borderRadius: 2 }} />
          <div style={{ position: 'absolute', left: 0, width: `${pct}%`, height: 4, background: `linear-gradient(90deg, #EA580C, #F59E0B)`, borderRadius: 2 }} />
          {/* Chapter ticks */}
          {acts.slice(1).map(a => {
            const tickPct = (a.start / duration) * 100;
            return <div key={a.id} style={{ position: 'absolute', left: `${tickPct}%`, top: '50%', width: 2, height: 10, marginLeft: -1, marginTop: -5, background: 'rgba(255,255,255,0.3)' }} />;
          })}
          {/* Knob */}
          <div style={{ position: 'absolute', left: `${pct}%`, top: '50%', width: 14, height: 14, marginLeft: -7, marginTop: -7, background: '#fff', borderRadius: 7, boxShadow: '0 2px 8px rgba(0,0,0,0.6)', pointerEvents: 'none' }} />
        </div>

        <div style={{ fontFamily: 'JetBrains Mono, monospace', fontSize: 12, color: 'rgba(255,255,255,0.5)', fontVariantNumeric: 'tabular-nums', minWidth: 36 }}>
          {fmt(duration)}
        </div>

        {/* Fullscreen toggle */}
        <button onClick={onToggleFullscreen} title={isFullscreen ? 'Salir de pantalla completa (Esc)' : 'Pantalla completa'} aria-label={isFullscreen ? 'Salir de pantalla completa' : 'Pantalla completa'} style={{
          width: 32, height: 32,
          background: 'transparent',
          border: '1px solid rgba(255,255,255,0.1)',
          borderRadius: 6,
          color: 'rgba(255,255,255,0.7)',
          cursor: 'pointer',
          display: 'flex', alignItems: 'center', justifyContent: 'center',
          flexShrink: 0,
        }}>
          {isFullscreen ? (
            <svg width="14" height="14" viewBox="0 0 14 14" fill="none" stroke="currentColor" strokeWidth="1.6" strokeLinecap="round" strokeLinejoin="round"><path d="M9 1v3h3M5 13v-3H2M13 5h-3V2M1 9h3v3"/></svg>
          ) : (
            <svg width="14" height="14" viewBox="0 0 14 14" fill="none" stroke="currentColor" strokeWidth="1.6" strokeLinecap="round" strokeLinejoin="round"><path d="M2 5V2h3M9 2h3v3M12 9v3H9M5 12H2V9"/></svg>
          )}
        </button>
      </div>
    </div>
  );
}

window.ChispaVideoPlayer = ChispaVideoPlayer;
