// subtitles.jsx — Narrative subtitles overlaid at the bottom of the canvas.
//
// 22 entries timed to the 3:31 video; each {start, end} window overlays a
// single line in the current language (ES default, EN when lang === 'en').
// Windows intentionally AVOID the title card buffers (8.7-12.2, 72-77,
// 180-186) so they don't compete with the act-card copy.
//
// Style: Netflix-style caption — small dark pill at bottom-center, white text,
// no chrome, fades in/out 240ms. Sits at y ≈ 660 of the 1280×720 canvas.

const SUBTITLES = [
  // ── Act 1 — Onboarding (0-9) ─────────────────────────────────────────
  { start: 0.6,  end: 4.2,  es: 'Amelia entra a EasyPro Plus.',                                       en: 'Amelia signs in to EasyPro Plus.' },
  { start: 4.4,  end: 8.6,  es: 'Activa los módulos de su office.',                                   en: 'She activates the modules her office needs.' },

  // (8.7-12.2 title card "Taxes" — no subtitle)

  // ── Act 2 — Taxes (12.25-74.25) ──────────────────────────────────────
  // Subtítulos re-alineados a las escenas reales (2026-05-25):
  //   12.6-19.5  Case creation modals
  //   20.0-33.0  Office sends contract by email + WhatsApp (toast 20.5)
  //   33.5-43.5  Phone moment 1: TOMÁS signs contract on WhatsApp
  //   44.5-58.0  Intake doc-drop → Sophia detects 1099-K → Revisar y Firmar
  //   58.5-67.5  Phone moment 2: TOMÁS reviews + signs intake
  //   68.0-73.5  Office "¡Listo!" + client gracias → "Declaración lista"
  { start: 12.6, end: 19.5, es: 'Amelia crea el caso de TOMÁS para sus taxes 2026.',                  en: "Amelia opens TOMÁS's 2026 tax case." },
  { start: 20.0, end: 33.0, es: 'Le envía el contrato — TOMÁS lo recibe en WhatsApp.',                en: 'Sends the engagement letter — TOMÁS gets it on WhatsApp.' },
  { start: 33.5, end: 43.5, es: 'TOMÁS firma el contrato desde su celular.',                          en: 'TOMÁS signs the engagement letter on his phone.' },
  { start: 44.5, end: 58.0, es: 'Sophia detecta un 1099-K faltante. Amelia revisa el intake.',        en: 'Sophia catches a missing 1099-K. Amelia reviews the intake.' },
  { start: 58.5, end: 67.5, es: 'TOMÁS revisa el intake completo y firma.',                           en: 'TOMÁS reviews the full intake and signs.' },
  { start: 68.0, end: 73.5, es: 'Declaración lista para revisión final.',                             en: 'Return queued for final review.' },

  // (72-77 title card "Migración" — no subtitle)

  // ── Act 3 — Migración (77-139.5) ─────────────────────────────────────
  { start: 77.4, end: 88.7, es: 'TOMÁS se casó. Pide la residencia para CARLA.',                       en: 'TOMÁS just married. Asks for residency for CARLA.' },
  { start: 89.6, end: 100.5, es: 'Amelia crea el caso de migración en segundos.',                      en: 'Amelia opens the migration case in seconds.' },
  { start: 101.4, end: 112.7, es: 'Contrato firmado. CARLA está feliz.',                               en: 'Contract signed. CARLA is happy.' },
  { start: 113.5, end: 124.0, es: 'Sophia importa los datos del módulo Taxes — usa OCR para leer cada documento.',          en: 'Sophia imports data from Taxes — uses OCR to read each document.' },
  { start: 125.0, end: 139.0, es: 'Con esos datos llena las formas migratorias en segundos.',                              en: 'With that data she fills the immigration forms in seconds.' },

  // ── Act 4 — Paquete USCIS (140.75-167) ───────────────────────────────
  { start: 141.0, end: 148.0, es: 'Sophia prellena la forma I-130. Amelia revisa cada campo.',         en: 'Sophia pre-fills Form I-130. Amelia checks every field.' },
  { start: 149.0, end: 153.5, es: 'La evidencia se auto-clasifica. Los fiscales se heredan.',          en: 'Evidence auto-sorts. Tax docs inherit from Taxes.' },
  { start: 154.0, end: 157.5, es: 'Amelia ordena el paquete según USCIS.',                             en: 'Amelia orders the package per USCIS spec.' },
  { start: 158.0, end: 161.0, es: 'Sophia redacta la cover letter.',                                   en: 'Sophia drafts the cover letter.' },
  { start: 161.5, end: 166.5, es: '1 click: sobre, etiquetas, email y WhatsApp con tracking.',         en: '1 click: envelope, labels, email and WhatsApp with tracking.' },

  // ── Phone payoff (167-180) ───────────────────────────────────────────
  { start: 167.5, end: 179.5, es: 'TOMÁS recibe el aviso. Su paquete USCIS ya salió.',                 en: 'TOMÁS gets the update. The USCIS package is on its way.' },

  // (180-186 title card "Explain" — no subtitle)

  // ── Act 5 — Explain (186-206) ────────────────────────────────────────
  { start: 186.4, end: 190.8, es: 'Meses después: USCIS envía una carta. TOMÁS no entiende.',          en: 'Months later: USCIS sends a letter. TOMÁS is lost.' },
  { start: 191.2, end: 196.8, es: 'Sophia lee el notice. Es un RFE — no una negación.',                en: 'Sophia reads the notice. It\u2019s an RFE — not a denial.' },
  { start: 197.2, end: 201.8, es: 'Redacta la explicación humana. 87 días para responder.',            en: 'Drafts the human explanation. 87 days to respond.' },
  { start: 202.2, end: 205.8, es: 'Amelia aprueba. WhatsApp listo para TOMÁS.',                        en: 'Amelia approves. WhatsApp ready for TOMÁS.' },

  // ── Closing (206-211) ────────────────────────────────────────────────
  { start: 206.4, end: 210.6, es: 'Una sola plataforma. Todos tus módulos. Cero re-captura.',          en: 'One platform. Every module. Zero re-entry.' },
];

// SubtitleTrack reads the current timeline time + lang prop and renders the
// active subtitle (if any) at the bottom of the canvas with a fade.
function SubtitleTrack({ lang = 'es' }) {
  const { time } = useTimeline();

  // Find the subtitle whose window covers `time`. Linear scan is fine — 22 entries.
  const active = SUBTITLES.find(s => time >= s.start && time <= s.end);

  // Compute fade opacity (200ms in, 200ms out).
  let opacity = 0;
  if (active) {
    const FADE = 0.24;
    if (time - active.start < FADE) opacity = (time - active.start) / FADE;
    else if (active.end - time < FADE) opacity = (active.end - time) / FADE;
    else opacity = 1;
    opacity = Math.max(0, Math.min(1, opacity));
  }

  const text = active ? (lang === 'en' ? active.en : active.es) : '';

  return (
    <div style={{
      position: 'absolute',
      left: 0, right: 0,
      bottom: 32,
      display: 'flex',
      justifyContent: 'center',
      pointerEvents: 'none',
      zIndex: 60,  // above iPhone (30), title cards (40 backdrop), below player chrome
    }}>
      <div style={{
        maxWidth: 900,
        padding: '12px 22px',
        background: 'rgba(8, 6, 14, 0.78)',
        backdropFilter: 'blur(10px)',
        WebkitBackdropFilter: 'blur(10px)',
        border: '1px solid rgba(255, 255, 255, 0.06)',
        borderRadius: 10,
        color: '#fff',
        fontSize: 22,
        fontWeight: 500,
        letterSpacing: -0.012,
        lineHeight: 1.35,
        textAlign: 'center',
        textShadow: '0 1px 4px rgba(0, 0, 0, 0.55)',
        opacity,
        transition: 'opacity 200ms ease-out',
        // Keep the box invisible (no border, no bg) when text is empty so it
        // doesn't flash an empty pill between subtitles.
        visibility: opacity > 0 ? 'visible' : 'hidden',
      }}>
        {text || '\u00A0'}
      </div>
    </div>
  );
}

Object.assign(window, { SubtitleTrack, SUBTITLES });
