// Client-side PowerPoint renderer for the Slides tab.
// Renders an uploaded .pptx straight to HTML in the browser using PPTXjs — so
// the slides show on ANY device with no PowerPoint installed and without
// depending on Microsoft's Office Online viewer. If the client-side render
// can't run (old browser, odd file), it falls back to the Office viewer, and
// finally to a download link — so something always works.

(function(){
  // ---- load PPTXjs + deps once, lazily ----
  let depsPromise = null;
  function loadScript(src){
    return new Promise((res, rej)=>{
      const s = document.createElement('script');
      s.src = src; s.async = false;
      s.onload = res; s.onerror = ()=>rej(new Error('load '+src));
      document.head.appendChild(s);
    });
  }
  function loadCss(href){
    return new Promise((res)=>{
      const l = document.createElement('link');
      l.rel = 'stylesheet'; l.href = href; l.onload = res; l.onerror = res;
      document.head.appendChild(l);
    });
  }
  function loadPptxDeps(){
    if(depsPromise) return depsPromise;
    const V = 'https://cdn.jsdelivr.net/gh/meshesha/PPTXjs@v1.21.1';
    depsPromise = (async ()=>{
      if(!window.jQuery) await loadScript('https://cdn.jsdelivr.net/npm/jquery@3.6.4/dist/jquery.min.js');
      if(!window.JSZip)  await loadScript('https://cdn.jsdelivr.net/npm/jszip@3.10.1/dist/jszip.min.js');
      if(!window.JSZipUtils) await loadScript('https://cdn.jsdelivr.net/npm/jszip-utils@0.1.0/dist/jszip-utils.min.js');
      await loadScript(V + '/js/filereader.js');
      await loadCss(V + '/css/pptxjs.css');
      await loadScript(V + '/js/pptxjs.js');
      await loadScript(V + '/js/divs2slides.js');
      if(!(window.jQuery && window.jQuery.fn && window.jQuery.fn.pptxToHtml))
        throw new Error('PPTXjs unavailable');
      return window.jQuery;
    })().catch(err=>{ depsPromise = null; throw err; });
    return depsPromise;
  }

  const { useState, useRef, useEffect, useLayoutEffect } = React;

  function PptxDeck({ url, index, onCount, deckName }){
    const hostRef = useRef(null);   // PPTXjs renders here (offscreen-ish)
    const wrapRef = useRef(null);   // visible scaling wrapper
    const slidesRef = useRef([]);
    const [phase, setPhase] = useState('loading'); // loading | ready | office | error
    const [forceOffice, setForceOffice] = useState(false);
    const [n, setN] = useState(0);

    // render the deck once per URL
    useEffect(()=>{
      let cancelled = false;
      setPhase('loading'); slidesRef.current = []; setN(0);
      (async ()=>{
        let $;
        try { $ = await loadPptxDeps(); }
        catch(e){ if(!cancelled) setPhase('office'); return; }   // deps blocked → Office viewer
        try {
          const host = hostRef.current; if(!host) return;
          host.innerHTML = '';
          const id = 'pptx_' + Math.random().toString(36).slice(2);
          host.id = id;
          // PPTXjs (v1.21.1) fetches the URL itself; the file is same-origin on
          // the church's own domain, so no PowerPoint or cloud service is needed.
          $('#'+id).pptxToHtml({ pptxFileUrl: url, slideMode:false, keyBoardShortCut:false, mediaProcess:true });
          // PPTXjs is async with no callback — poll for the rendered slides
          const started = Date.now();
          const poll = setInterval(()=>{
            if(cancelled){ clearInterval(poll); return; }
            const sl = host.querySelectorAll('.slide');
            if(sl.length){
              clearInterval(poll);
              slidesRef.current = Array.prototype.slice.call(sl);
              setN(sl.length); onCount && onCount(sl.length);
              setPhase('ready');
            } else if(Date.now()-started > 8000){
              clearInterval(poll); setPhase('office');           // took too long → Office viewer
            }
          }, 150);
        } catch(e){ if(!cancelled) setPhase('office'); }
      })();
      return ()=>{ cancelled = true; };
    }, [url]);

    // show only the active slide and scale it to fit the stage
    const fit = ()=>{
      const wrap = wrapRef.current, slides = slidesRef.current;
      if(!wrap || !slides.length) return;
      const cur = slides[Math.min(index, slides.length-1)];
      slides.forEach((el,k)=>{ el.style.display = (k===Math.min(index,slides.length-1))?'block':'none'; });
      if(!cur) return;
      const sw = cur.offsetWidth || 960, sh = cur.offsetHeight || 540;
      const scale = Math.min(wrap.clientWidth / sw, wrap.clientHeight / sh);
      const host = hostRef.current;
      host.style.transformOrigin = 'top left';
      host.style.transform = 'scale(' + scale + ')';
      host.style.width = sw + 'px'; host.style.height = sh + 'px';
      host.style.left = ((wrap.clientWidth - sw*scale)/2) + 'px';
      host.style.top  = ((wrap.clientHeight - sh*scale)/2) + 'px';
    };
    useLayoutEffect(()=>{ if(phase==='ready') fit(); }, [index, phase, n]);
    useEffect(()=>{
      if(phase!=='ready') return;
      window.addEventListener('resize', fit);
      let ro = null;
      if(window.ResizeObserver && wrapRef.current){ ro = new ResizeObserver(fit); ro.observe(wrapRef.current); }
      return ()=>{ window.removeEventListener('resize', fit); if(ro) ro.disconnect(); };
    }, [phase, n]);

    if(phase === 'office' || forceOffice){
      return (
        <div className="pptx-fallback">
          <iframe className="slide-frame" key={url}
            src={`https://view.officeapps.live.com/op/embed.aspx?src=${encodeURIComponent(url)}`}
            title={deckName||'Presentation'} frameBorder="0" allowFullScreen></iframe>
          <a className="pptx-dl" href={url} download target="_blank" rel="noopener">Download slides</a>
        </div>
      );
    }

    return (
      <div className="pptx-wrap" ref={wrapRef}>
        {phase==='loading' && <div className="pptx-loading"><span></span>Opening slides…</div>}
        <div className="pptx-host" ref={hostRef} style={{position:'absolute'}}></div>
        {phase==='ready' && (
          <div className="pptx-esc">
            <button onClick={()=>setForceOffice(true)} title="Open in Microsoft viewer instead">Microsoft viewer</button>
            <a href={url} download target="_blank" rel="noopener" title="Download the file">Download</a>
          </div>
        )}
      </div>
    );
  }

  window.PptxDeck = PptxDeck;
})();
