// The desktop chronology reuses the mobile chapters, historical events and decade labels.
function dtChronology() {
  const years = new Map();
  const at = year => {
    if (!years.has(year)) years.set(year, { year, films: [], events: [] });
    return years.get(year);
  };
  [...dtEntries('ib')].sort((a, b) => Number(a.year) - Number(b.year)).forEach(film => at(Number(film.year)).films.push(film));
  IB_HIST.forEach(event => {
    // afterYear describes the mobile insertion point; the printed year is the chronological date.
    const year = Number(event.event.match(/\d{4}/)?.[0] || event.afterYear);
    at(year).events.push(event);
  });
  const eras = new Map();
  [...years.values()].sort((a, b) => a.year - b.year).forEach(row => {
    const decade = ibDecadeOf(row.year);
    if (!eras.has(decade)) eras.set(decade, { decade, years: [] });
    eras.get(decade).years.push(row);
  });
  return [...eras.values()];
}

function DesktopTimeline({ scrollRef }) {
  const eras = React.useMemo(dtChronology, []);
  const root = React.useRef(null);
  const chronology = React.useRef(null);
  const navigation = React.useRef(null);
  const [active, setActive] = React.useState(eras[0].decade);
  const films = dtEntries('ib');
  const minutes = films.reduce((sum, film) => sum + runtimeFor(film).mins, 0);
  const jump = decade => {
    const target = root.current.querySelector(`#dt-era-${decade}`);
    const scroller = scrollRef.current;
    const top = target.getBoundingClientRect().top - scroller.getBoundingClientRect().top + scroller.scrollTop - navigation.current.offsetHeight;
    scroller.scrollTo({ top, behavior: matchMedia('(prefers-reduced-motion: reduce)').matches ? 'instant' : 'smooth' });
    target.focus({ preventScroll: true });
  };
  React.useEffect(() => {
    const scroller = scrollRef.current;
    const sections = [...root.current.querySelectorAll('.dt-era')];
    const media = matchMedia('(prefers-reduced-motion: reduce)');
    let frame;
    const update = () => {
      if (frame) return;
      frame = requestAnimationFrame(() => {
        frame = null;
        const view = scroller.getBoundingClientRect();
        const bounds = chronology.current.getBoundingClientRect();
        const atEnd = scroller.scrollTop + scroller.clientHeight >= scroller.scrollHeight - 4;
        const progress = atEnd ? 1 : Math.min(1, Math.max(0, (view.top + view.height * .48 - bounds.top) / bounds.height));
        root.current.style.setProperty('--timeline-progress', progress);
        const current = atEnd ? sections[sections.length - 1] : sections.filter(el => el.getBoundingClientRect().top <= view.top + navigation.current.offsetHeight + 100).pop() || sections[0];
        setActive(Number(current.dataset.decade));
        if (!media.matches) root.current.style.setProperty('--era-turn', `${Math.min(scroller.scrollTop * .035, 90)}deg`);
      });
    };
    const resize = new ResizeObserver(update);
    resize.observe(chronology.current);
    scroller.addEventListener('scroll', update, { passive: true });
    window.addEventListener('resize', update);
    update();
    return () => { cancelAnimationFrame(frame); resize.disconnect(); scroller.removeEventListener('scroll', update); window.removeEventListener('resize', update); };
  }, []);
  return <div className="dt-timeline" ref={root}>
    <header className="dt-timeline-head">
      <div className="dt-kicker"><span>Cuadernos · Vol II</span><span>{films.length} NOTAS · {Math.floor(minutes / 60)}H {dtNumber(minutes % 60)}MIN</span></div>
      <div className="dt-timeline-heading">
        <h1 className="dt-name--ib">Inmenso <em>Bastardo.</em></h1>
        <div className="dt-era-emblem" aria-hidden="true"><div className="dt-era-orbit">{Array.from({ length: 24 }, (_, i) => <i key={i} style={{ '--tick': i }}/>)}</div><span>{IB_DECADE_SYMBOLS[active]}</span><small>{Math.min(...films.map(f => f.year))} — {Math.max(...films.map(f => f.year))}</small></div>
      </div>
      <div className="dt-timeline-lead"><p>Proyectos desmedidos, repartidos desde hace más de un siglo. Una cronología de las películas más largas de la historia.</p><button onClick={() => jump(eras[0].decade)} aria-label="Recorrer la línea de tiempo"><span aria-hidden="true">↓</span></button></div>
    </header>
    <nav ref={navigation} className="dt-decade-nav" aria-label="Décadas">
      {eras.map(({ decade, years }) => <button key={decade} onClick={() => jump(decade)} aria-current={active === decade ? 'location' : undefined} aria-label={`Ir a ${decade}`}><span>{decade}<small>s</small></span><i aria-hidden="true">{years.flatMap(row => row.films).map(film => <b key={film.slug}/>)}</i></button>)}
      <div className="dt-timeline-meter" aria-hidden="true"><i/></div>
    </nav>
    <div className="dt-chronology" ref={chronology}>
      <div className="dt-chronology-line" aria-hidden="true"><i/></div>
      {eras.map(({ decade, years }) => <section key={decade} id={`dt-era-${decade}`} data-decade={decade} className="dt-era" tabIndex={-1} aria-labelledby={`dt-era-title-${decade}`}>
        <header className="dt-era-head"><h2 id={`dt-era-title-${decade}`}>{decade}<small>s</small></h2><span aria-hidden="true">{IB_DECADE_SYMBOLS[decade]}</span><p>{IB_DECADE_TAGS[decade]}</p></header>
        {years.map(({ year, films: chapters, events }) => <div className="dt-time-year" data-year={year} key={year}>
          <div className="dt-year-marker"><time>{year}</time><i aria-hidden="true"/></div>
          <div className="dt-year-films">{chapters.map(film => <DesktopLink key={film.slug} to={`/ib/${film.slug}`} data-slug={film.slug} className="dt-timeline-film">
            <div className="dt-timeline-still"><img src={dtImage(film)} alt="" loading="lazy" decoding="async"/><span className="dt-timeline-open" aria-hidden="true">↗</span><small>CAP. {dtNumber(dtEntries('ib').indexOf(film) + 1)}</small></div>
            <div className="dt-timeline-film-copy"><div className="dt-timeline-film-meta"><span>{dtText(film.director)}</span><span>{runtimeFor(film).str}</span></div><h3>{dtTitle(film)}</h3><p>{film.excerpt}</p><div className="dt-runtime" aria-hidden="true"><i style={{ '--runtime': Math.min(1, runtimeFor(film).mins / 300) }}/></div><span className="dt-timeline-cta">Leer capítulo <span aria-hidden="true">↗</span></span></div>
          </DesktopLink>)}</div>
          <div className="dt-year-events">{events.map((event, i) => <article className="dt-history-event" key={i}><span className="dt-kicker">{event.tag}</span><h3>{event.event}</h3><p>{event.blurb}</p></article>)}</div>
        </div>)}
      </section>)}
    </div>
    <section className="dt-timeline-close" aria-labelledby="dt-timeline-close-title">
      <span aria-hidden="true">❋</span>
      <h2 id="dt-timeline-close-title"><em>Inmenso Bastardo volverá.</em></h2>
      <p><em>El cuaderno sigue abierto.</em></p>
    </section>
    <DesktopFooter/>
  </div>;
}
