// Independent desktop presentation. All editorial content comes from the mobile datasets.
const DT_COPY = {
  vv: { kicker: 'En cartel · crítica', description: 'Críticas sueltas. Una película, un análisis, una opinión. A veces, todo eso mezclado.', cta: 'Leer crítica', unit: 'críticas' },
  ib: { kicker: 'Cuadernos · Vol II', description: 'Lo inconmensurable. Películas épicas y no tan épicas que marcaron la historia del cine.', cta: 'Leer capítulo', unit: 'capítulos' },
  ed: { kicker: 'Archivo · opinión', description: 'Textos de opinión. A veces sobre cine, a veces sobre todo lo demás.', cta: 'Leer editorial', unit: 'textos' },
  dirigien2: { kicker: 'Universo interactivo', description: 'Elegí proyectos, atravesá rodajes imposibles y descubrí qué filmografía te tocó construir.', cta: 'Empezar una carrera', unit: '' },
};
function dtEntries(section) {
  if (section === 'vv') return (window.VV_ORDER || []).map(slug => window.VV_FULL[slug]).filter(Boolean);
  if (section === 'ib') return window.IB_CAPITULOS || [];
  if (section === 'ed') return window.EDITORIALES || [];
  return [];
}
function dtTitle(entry) { return entry.filmTitle || entry.title; }
function dtText(value) { return Array.isArray(value) ? value.join(' · ') : value || ''; }
function dtImage(entry) { return entry?.cover || (entry?.blocks || []).find(b => (b.kind || b.type) === 'img')?.src || entry?.poster || (entry && edPaperImage(entry)); }
function dtNumber(n) { return String(n).padStart(2, '0'); }
function dtResolve(slug) {
  for (const section of ['vv', 'ib', 'ed']) {
    const entry = dtEntries(section).find(e => e.slug === slug);
    if (entry) return { section, entry };
  }
  return null;
}
function DesktopName({ section }) {
  if (section === 'vv') return <>Vamos <em>Viendo</em></>;
  if (section === 'ib') return <>Inmenso <em>Bastardo.</em></>;
  if (section === 'ed') return <>EDI<span className="dt-slash">/</span>BARAK</>;
  if (section === 'dirigien2') return <>Dirigien2</>;
  return <>Detrás de Escenas</>;
}
// Preserve native links, modifier clicks and opening in another tab.
function DesktopLink({ to, children, onClick, ...props }) {
  return <a href={to} {...props} onClick={event => {
    if (onClick) onClick(event);
    if (event.defaultPrevented || event.button !== 0 || event.metaKey || event.ctrlKey || event.shiftKey || event.altKey) return;
    if (/^\/(?:vv|ib|ed|about)(?:\/|$)/.test(to) || to === '/') {
      event.preventDefault(); window.rtGo(to);
    }
  }}>{children}</a>;
}
function useDesktopMotion(scrollRef, route) {
  React.useLayoutEffect(() => {
    const scroller = scrollRef.current;
    const page = scroller.querySelector('.dt-page');
    const media = matchMedia('(prefers-reduced-motion: reduce)');
    const targets = [...page.querySelectorAll('.dt-masthead h1, .dt-home-line, .dt-portal, .dt-archive-head h1, .dt-editorial, .dt-reader-intro > *, .dt-figure, .dt-related a, .dt-timeline-heading h1, .dt-timeline-lead, .dt-era-head, .dt-timeline-film, .dt-history-event, .dt-about .de-screen > section')];
    let observer;
    const reveal = target => { target.classList.add('is-revealed'); observer?.unobserve(target); };
    const configure = () => {
      observer?.disconnect();
      if (media.matches) { targets.forEach(reveal); return; }
      observer = new IntersectionObserver(entries => entries.forEach(entry => { if (entry.isIntersecting) reveal(entry.target); }), { root: scroller, rootMargin: '0px 0px -18px 0px', threshold: 0 });
      targets.forEach((target, index) => {
        target.classList.add('dt-reveal');
        target.style.setProperty('--reveal-delay', `${index % 4 * 45}ms`);
        if (!target.classList.contains('is-revealed')) observer.observe(target);
      });
    };
    // Tabbing or restoring history must never focus an invisible control.
    const onFocus = event => {
      const target = event.target.closest('.dt-reveal');
      if (target) reveal(target);
    };
    configure();
    scroller.addEventListener('focusin', onFocus);
    media.addEventListener('change', configure);
    return () => { observer?.disconnect(); scroller.removeEventListener('focusin', onFocus); media.removeEventListener('change', configure); };
  }, [route]);
}
function DesktopExperience({ section, slug, onPick, onHome }) {
  const scroll = React.useRef(null);
  const positions = React.useRef(new Map());
  const archiveMemory = React.useRef({});
  const lastArticle = React.useRef(null);
  const initial = React.useRef(true);
  const route = `${section || 'home'}/${slug || ''}`;
  useDesktopMotion(scroll, route);
  React.useLayoutEffect(() => {
    const element = scroll.current;
    element.scrollTop = positions.current.get(route) || 0;
    if (!initial.current) {
      const target = !slug && lastArticle.current && element.querySelector(`[data-slug="${lastArticle.current}"]`);
      (target || element).focus({ preventScroll: true });
    }
    initial.current = false;
    if (slug) lastArticle.current = slug;
    // Record while scrolling, before React replaces the page. A shorter next page
    // can clamp scrollTop before a layout-effect cleanup gets to read it.
  }, [route]);
  React.useEffect(() => {
    const entry = dtEntries(section).find(e => e.slug === slug);
    document.title = `${entry ? dtTitle(entry) : (window.RT_SECTIONS.find(s => s.id === section)?.name || 'Rintana')} · Cine`;
  }, [section, slug]);
  return <div className={`dt dt--${section || 'home'}`}>
    <a href="#dt-main" className="dt-skip" onClick={e => { e.preventDefault(); scroll.current.focus(); }}>Ir al contenido</a>
    <header className="dt-header">
      <DesktopLink to="/" className="dt-brand" aria-label="Rintana · Inicio">RINTANA<span aria-hidden="true">●</span></DesktopLink>
      <nav className="dt-nav" aria-label="Secciones">{(window.RT_SECTIONS || []).map((s, i) => <DesktopLink key={s.id} to={`/${s.id}${s.external ? '/' : ''}`} aria-current={section === s.id ? 'page' : undefined} className={`dt-nav-link dt-name--${s.id}`}><span className="dt-nav-number" aria-hidden="true">{dtNumber(i + 1)}</span><DesktopName section={s.id}/></DesktopLink>)}</nav>
    </header>
    <main id="dt-main" className="dt-scroll" ref={scroll} onScroll={event => positions.current.set(route, event.currentTarget.scrollTop)} tabIndex={-1} aria-label={section ? window.RT_SECTIONS.find(s => s.id === section)?.name : 'Inicio'}>
      <div className="dt-page" key={route}>
        {!section && <DesktopPortal/>}
        {['vv', 'ib', 'ed'].includes(section) && (slug ? <DesktopReader section={section} slug={slug} scrollRef={scroll}/> : section === 'ib' ? <DesktopTimeline scrollRef={scroll}/> : section === 'ed' ? <DesktopEditorialDesk/> : <DesktopArchive section={section} memory={archiveMemory.current}/>)}
        {section === 'about' && <DesktopAbout onPick={onPick} onHome={onHome}/>}
      </div>
    </main>
  </div>;
}
function DesktopPortal() {
  const [active, setActive] = React.useState('vv');
  const home = React.useRef(null);
  const entries = { vv: dtEntries('vv')[0], ib: dtEntries('ib').find(e => e.slug === '1979-apocalypse-now') || dtEntries('ib')[0], ed: dtEntries('ed')[0] };
  const pointer = event => {
    if (matchMedia('(prefers-reduced-motion: reduce)').matches) return;
    const rect = event.currentTarget.getBoundingClientRect();
    home.current.style.setProperty('--mx', `${((event.clientX - rect.left) / rect.width - .5) * 14}px`);
    home.current.style.setProperty('--my', `${((event.clientY - rect.top) / rect.height - .5) * 10}px`);
  };
  return <div className="dt-home" ref={home}>
    <div className="dt-masthead"><h1>RINTANA<span aria-hidden="true">●</span></h1><div className="dt-masthead-note"><span>Cine · Crítica</span><span>por Nicolás Barak</span><span>2026 · BA</span></div></div>
    <div className="dt-home-line"><p>Distintas maneras de <em>ver lo mismo.</em></p><span>↙ elegí por dónde entrar</span></div>
    <div className={`dt-portals dt-portals--${active}`} onPointerMove={pointer} onPointerLeave={() => { home.current.style.setProperty('--mx', '0px'); home.current.style.setProperty('--my', '0px'); }}>
      {['vv', 'ib', 'ed', 'dirigien2'].map((id, index) => <DesktopLink to={`/${id}${id === 'dirigien2' ? '/' : ''}`} key={id} className={`dt-portal dt-portal--${id} ${active === id ? 'is-active' : ''}`} onPointerEnter={() => setActive(id)} onFocus={() => setActive(id)}>
        {entries[id] && <img className="dt-portal-image" src={dtImage(entries[id])} alt="" decoding="async"/>}
        {id === 'dirigien2' && <div className="dt-orbits" aria-hidden="true"><i/><i/><i/><b>2</b></div>}
        <div className="dt-portal-top"><span>{DT_COPY[id].kicker}</span><span>{dtNumber(index + 1)}</span></div>
        {id === 'ed' && <span className="dt-portal-ed-note">No escribo para tener razón.<br/>Escribo para entender.</span>}
        <div className="dt-portal-bottom"><h2 className={`dt-name--${id}`}><DesktopName section={id}/></h2><div className="dt-portal-reveal"><p>{DT_COPY[id].description}</p></div><div className="dt-portal-foot"><span>{id === 'dirigien2' ? 'Tu camino como cineasta.' : `${dtNumber(dtEntries(id).length)} ${DT_COPY[id].unit}`}</span><span className="dt-arrow" aria-hidden="true">↗</span></div></div>
      </DesktopLink>)}
    </div>
    <footer className="dt-home-footer"><span>RINTANA · CINE · 2026</span><DesktopLink to="/about"><span>Detrás de Escenas</span><small>quién escribe, cómo, por qué.</small><b aria-hidden="true">↗</b></DesktopLink></footer>
  </div>;
}
function DesktopArchive({ section, memory }) {
  const entries = React.useMemo(() => dtEntries(section), [section]);
  const saved = memory[section] || {};
  const [query, setQuery] = React.useState(saved.query || '');
  const [sort, setSort] = React.useState(saved.sort || 'original');
  const [mode, setMode] = React.useState(saved.mode || 'list');
  const [selected, setSelected] = React.useState(saved.selected || entries[0]?.slug);
  React.useEffect(() => { memory[section] = { query, sort, mode, selected }; }, [section, query, sort, mode, selected, memory]);
  const normalize = text => String(text).normalize('NFD').replace(/[\u0300-\u036f]/g, '').toLowerCase();
  const visible = React.useMemo(() => {
    const result = entries.filter(e => normalize(`${dtTitle(e)} ${e.title} ${dtText(e.director)} ${e.year || ''}`).includes(normalize(query.trim())));
    if (sort === 'year') result.sort((a, b) => (b.year || 0) - (a.year || 0));
    if (sort === 'title') result.sort((a, b) => dtTitle(a).localeCompare(dtTitle(b), 'es'));
    return result;
  }, [entries, query, sort]);
  const preview = visible.find(e => e.slug === selected) || visible[0];
  return <div className={`dt-archive dt-archive--${section}`}>
    <header className="dt-archive-head"><div className="dt-kicker"><span>{DT_COPY[section].kicker}</span><span>{dtNumber(entries.length)} {DT_COPY[section].unit}</span></div><h1 className={`dt-name--${section}`}><DesktopName section={section}/></h1><p>{DT_COPY[section].description}</p></header>
    {section !== 'ed' && <div className="dt-tools">
      <label className="dt-search"><span aria-hidden="true">⌕</span><span className="dt-sr">Buscar</span><input type="search" value={query} onChange={e => setQuery(e.target.value)} placeholder="Buscar" autoComplete="off"/></label>
      <span className="dt-result-count" role="status">{dtNumber(visible.length)} / {dtNumber(entries.length)}</span>
      <label className="dt-sort"><span className="dt-sr">Ordenar</span><select value={sort} onChange={e => setSort(e.target.value)}><option value="original">{section === 'ib' ? 'Capítulos' : 'Publicación'}</option><option value="year">Año</option><option value="title">Título</option></select></label>
      <div className="dt-view" role="group" aria-label="Vista"><button aria-label="Lista" aria-pressed={mode === 'list'} onClick={() => setMode('list')}><svg viewBox="0 0 20 20" aria-hidden="true"><path d="M3 5h14M3 10h14M3 15h14"/></svg></button><button aria-label="Cuadrícula" aria-pressed={mode === 'grid'} onClick={() => setMode('grid')}><svg viewBox="0 0 20 20" aria-hidden="true"><path d="M3 3h5v5H3zM12 3h5v5h-5zM3 12h5v5H3zM12 12h5v5h-5z"/></svg></button></div>
    </div>}
    {section === 'ed' ? <div className="dt-editorials">{entries.map((entry, i) => <DesktopEditorialCard key={entry.slug} entry={entry} index={i}/>)}</div> : <div className={`dt-archive-content dt-archive-content--${mode}`}>
      <div className={`dt-items dt-items--${mode}`}>{visible.map(entry => <DesktopLink key={entry.slug} to={`/${section}/${entry.slug}`} data-slug={entry.slug} className={`dt-item ${preview?.slug === entry.slug ? 'is-preview' : ''}`} onPointerEnter={() => setSelected(entry.slug)} onFocus={() => setSelected(entry.slug)}><span className="dt-item-num">{dtNumber(entries.indexOf(entry) + 1)}</span>{mode === 'grid' && <div className="dt-item-image"><img src={dtImage(entry)} alt="" loading="lazy"/></div>}<div className="dt-item-copy"><h2>{dtTitle(entry)}</h2><span>{dtText(entry.director)}</span></div><span className="dt-item-year">{entry.year}</span><span className="dt-item-arrow" aria-hidden="true">↗</span></DesktopLink>)}{!visible.length && <p className="dt-empty" role="status">Sin resultados. <button onClick={() => setQuery('')}>Ver todas</button></p>}</div>
      {mode === 'list' && preview && <aside className="dt-preview" aria-label="Vista previa"><DesktopLink to={`/${section}/${preview.slug}`} className="dt-preview-link" aria-label={`${DT_COPY[section].cta}: ${dtTitle(preview)}`}><div className="dt-preview-image" key={preview.slug}><img src={dtImage(preview)} alt=""/><span className="dt-preview-open" aria-hidden="true">↗</span>{section === 'ib' && <span className="dt-preview-year">{preview.year}</span>}</div><div className="dt-preview-meta"><span>{section === 'ib' ? 'Cap.' : 'N°'} {dtNumber(entries.indexOf(preview) + 1)}</span><span>{preview.year} · {dtText(preview.director)}</span></div><h2>{preview.title}</h2><p>{preview.excerpt}</p><span className="dt-preview-cta">{DT_COPY[section].cta} <span aria-hidden="true">→</span></span></DesktopLink></aside>}
    </div>}
    <DesktopFooter/>
  </div>;
}
function DesktopReader({ section, slug, scrollRef }) {
  const entries = dtEntries(section);
  const entry = entries.find(e => e.slug === slug);
  const index = entries.indexOf(entry);
  const progress = React.useRef(null);
  const article = React.useRef(null);
  const imageTrigger = React.useRef(null);
  const [lightbox, setLightbox] = React.useState(null);
  React.useEffect(() => {
    const scroller = scrollRef.current;
    let frame;
    const update = () => {
      if (frame) return;
      frame = requestAnimationFrame(() => {
        frame = null;
        if (!article.current || !progress.current) return;
        const start = article.current.getBoundingClientRect().top - scroller.getBoundingClientRect().top + scroller.scrollTop;
        const distance = article.current.offsetHeight - scroller.clientHeight;
        const amount = Math.min(1, Math.max(0, (scroller.scrollTop - start) / Math.max(1, distance)));
        progress.current.style.setProperty('--read', amount);
        progress.current.setAttribute('aria-valuenow', Math.round(amount * 100));
      });
    };
    const resize = new ResizeObserver(update);
    if (article.current) resize.observe(article.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); };
  }, [slug]);
  if (!entry) return <div className="dt-not-found"><h1>Nota no encontrada</h1><DesktopLink to={`/${section}`}>← Índice</DesktopLink></div>;
  const film = (window.CRITICAS || []).find(e => e.slug === slug)?.film || {};
  const director = dtText(entry.director || film.director);
  const runtime = entry.runtime || film.runtime;
  const country = dtText(entry.country || film.country);
  const images = (entry.blocks || []).filter(b => (b.type || b.kind) === 'img');
  const related = (entry.relatedFull || entry.related || []).map(r => dtResolve(typeof r === 'string' ? r : r.slug)).filter(Boolean).filter(r => r.entry.slug !== slug);
  const blocks = (entry.blocks || []).filter(b => !['h', 'h1', 'meta'].includes(b.type || b.kind));
  const Presentation = section === 'vv' ? DesktopCinemaReader : section === 'ib' ? DesktopChronicleReader : DesktopPaperReader;
  const progressNode = <div ref={progress} className="dt-progress" role="progressbar" aria-label="Progreso de lectura" aria-valuemin={0} aria-valuemax={100} aria-valuenow={0}><i/></div>;
  return <div className={`dt-reader dt-reader--${section}`}>
    <Presentation entry={entry} entries={entries} index={index} director={director} runtime={runtime} country={country} articleRef={article} progress={progressNode} related={related}>
      <article id="dt-article" ref={article} tabIndex={-1} className="dt-article" onClick={event => {
        const link = event.target.closest('a');
        if (!link || event.defaultPrevented || event.button !== 0 || event.metaKey || event.ctrlKey || event.shiftKey || event.altKey) return;
        const url = new URL(link.href, location.href);
        if ((url.origin === location.origin || /^(www\.)?rintana\.com$/.test(url.hostname)) && /^\/(vv|ib|ed|about)(\/|$)/.test(url.pathname)) {
          event.preventDefault(); window.rtGo(url.pathname);
        }
      }}>
        {blocks.map((block, i) => {
          const type = block.type || block.kind;
          const text = block.text ? renderMarkdownLinks(block.text, `dt-${i}`) : null;
          if (type === 'img') return <figure key={i} className="dt-figure"><button onClick={event => { imageTrigger.current = event.currentTarget; setLightbox(images.indexOf(block)); }} aria-label={`Ampliar fotograma${block.alt ? `: ${block.alt}` : ''}`}><img src={block.src} alt={block.alt || ''} loading="lazy" decoding="async"/><span aria-hidden="true">↗</span></button>{block.alt && <figcaption>{block.alt}</figcaption>}</figure>;
          if (type === 'pull' || type === 'note') return <blockquote key={i}>{text}</blockquote>;
          if (type === 'h2' || type === 'h3') { const Tag = type; return <Tag key={i} id={`dt-heading-${i}`}>{text}</Tag>; }
          if (type === 'crossout') return <p key={i}><s>{text}</s></p>;
          return <p key={i} data-block={i}>{text}</p>;
        })}<div className="dt-end"><span>Fin del texto</span><span aria-hidden="true">×</span></div>
      </article>
    </Presentation>
    <DesktopFooter/>{lightbox !== null && <DesktopLightbox images={images} index={lightbox} onChange={setLightbox} onClose={() => { setLightbox(null); requestAnimationFrame(() => imageTrigger.current?.focus({ preventScroll: true })); }}/>}
  </div>;
}
function DesktopLightbox({ images, index, onChange, onClose }) {
  const dialog = React.useRef(null);
  React.useEffect(() => { const element = dialog.current; element.showModal(); return () => element.close(); }, []);
  const image = images[index];
  const previous = () => onChange((index - 1 + images.length) % images.length);
  const next = () => onChange((index + 1) % images.length);
  return <dialog ref={dialog} className="dt-lightbox" aria-label="Fotogramas" onCancel={e => { e.preventDefault(); onClose(); }} onClick={e => { if (e.target === dialog.current) onClose(); }} onKeyDown={e => { if (e.key === 'ArrowLeft') { e.preventDefault(); previous(); } if (e.key === 'ArrowRight') { e.preventDefault(); next(); } }}><div className="dt-lightbox-bar"><span>{dtNumber(index + 1)} / {dtNumber(images.length)}</span><button onClick={onClose} autoFocus aria-label="Cerrar fotograma">Cerrar <span aria-hidden="true">×</span></button></div><figure><img src={image.src} alt={image.alt || ''}/>{image.alt && <figcaption>{image.alt}</figcaption>}</figure>{images.length > 1 && <div className="dt-lightbox-nav"><button onClick={previous} aria-label="Fotograma anterior">←</button><button onClick={next} aria-label="Fotograma siguiente">→</button></div>}</dialog>;
}
function DesktopFooter() {
  return <footer className="dt-footer"><DesktopLink to="/" className="dt-brand">RINTANA<span aria-hidden="true">●</span></DesktopLink><span>Cine · Crítica</span><DesktopLink to="/about">Detrás de Escenas ↗</DesktopLink></footer>;
}
function DesktopAbout({ onPick, onHome }) {
  const root = React.useRef(null);
  // Enhance the existing biography's navigation only inside the desktop tree.
  React.useEffect(() => {
    const links = [...root.current.querySelectorAll('.de-goto-name')].map(name => name.parentElement.parentElement);
    const onKey = event => {
      if (event.key === 'Enter' || event.key === ' ') { event.preventDefault(); event.currentTarget.click(); }
    };
    links.forEach(link => { link.tabIndex = 0; link.setAttribute('role', 'link'); link.addEventListener('keydown', onKey); });
    return () => links.forEach(link => link.removeEventListener('keydown', onKey));
  }, []);
  return <div className="dt-about" ref={root}><h1 className="dt-sr">Detrás de Escenas</h1><DBSection onPickFilm={s => window.rtGo(`/vv/${s}`)} onPickSection={onPick} onHome={onHome}/></div>;
}
window.DesktopExperience = DesktopExperience;
