// VideoScreen (BUILD_PLAN.md 2.3, 3.2). Renders Bunny's token-authenticated iframe
// embed inside the existing frame/tabs/exit layout; the old custom play/scrub
// controls are retired in favour of Bunny's own player chrome. Furthest playback
// position is tracked via the Bunny player's timeupdate events (through player.js)
// and periodically posted to the `record-progress` Edge Function, which also runs
// the module auto-unlock check (3.3) server-side.
const AY_PROGRESS_POST_INTERVAL_MS = 15000;
// After this long on the spinner, add a hint so a slow connection doesn't read as a broken site.
const AY_SLOW_HINT_MS = 8000;

// Loading indicator for both loading phases (token mint, then the Bunny iframe itself
// downloading on a slow connection -- which used to show as a blank black frame).
function AyVideoLoading({ label }) {
  const [slow, setSlow] = React.useState(false);
  React.useEffect(() => {
    const t = setTimeout(() => setSlow(true), AY_SLOW_HINT_MS);
    return () => clearTimeout(t);
  }, []);
  return (
    <div className="ay-video-status ay-video-loading" role="status" aria-live="polite">
      <span className="ay-spinner" aria-hidden="true" />
      <span>{label}</span>
      {slow && <span className="ay-video-loading-hint">Still working — this can take a moment on a slow connection.</span>}
    </div>
  );
}

function VideoScreen({ lesson, moduleCode, onExit }) {
  const [modProgress, setModProgress] = React.useState(0);
  const [tab, setTab] = React.useState('video');
  const [status, setStatus] = React.useState('loading'); // loading | ready | error
  const [error, setError] = React.useState('');
  const [embedUrl, setEmbedUrl] = React.useState(null);
  const [frameLoaded, setFrameLoaded] = React.useState(false); // Bunny iframe `load` fired
  // Templates/Extra tabs (5.1): documents for this lesson + per-doc download state.
  const [docs, setDocs] = React.useState([]);
  const [docsStatus, setDocsStatus] = React.useState('loading'); // loading | ready | error
  const [docBusy, setDocBusy] = React.useState(null);   // doc id being fetched
  const [docError, setDocError] = React.useState('');
  // Templates tab previews the selected PDF inline (extras stay download-only).
  const [previewId, setPreviewId] = React.useState(null);
  const [previewUrl, setPreviewUrl] = React.useState(null);
  const [previewError, setPreviewError] = React.useState('');
  const iframeRef = React.useRef(null);
  const playerRef = React.useRef(null);
  // Refs, not state -- these aren't rendered, just read by the post-progress timer.
  const furthestRef = React.useRef(0);
  const durationRef = React.useRef(0);
  const lastSentRef = React.useRef(-1);

  React.useEffect(() => {
    let active = true;
    (async () => {
      const modules = await window.ayaniFetchModules().catch(() => []);
      if (!active) return;
      const mod = modules.find(m => m.code === moduleCode);
      if (mod) setModProgress(mod.progress);
    })();
    return () => { active = false; };
  }, [moduleCode]);

  function postProgress() {
    if (!lesson?.id || durationRef.current <= 0) return;
    if (furthestRef.current === lastSentRef.current) return;
    lastSentRef.current = furthestRef.current;
    window.supabaseClient.functions.invoke('record-progress', {
      body: {
        lesson_id: lesson.id,
        furthest_seconds: furthestRef.current,
        duration_seconds: durationRef.current,
      },
    }).catch(() => {});
  }

  React.useEffect(() => {
    let active = true;
    setDocs([]); setDocsStatus('loading'); setDocError('');
    if (!lesson?.id) { setDocsStatus('ready'); return; }
    window.ayaniFetchDocuments(lesson.id)
      .then(d => { if (active) { setDocs(d); setDocsStatus('ready'); } })
      .catch(() => { if (active) setDocsStatus('error'); });
    return () => { active = false; };
  }, [lesson?.id]);

  async function download(doc) {
    if (docBusy) return;
    setDocBusy(doc.id); setDocError('');
    try {
      const url = await window.ayaniDocumentDownloadUrl(doc);
      // Signed URL carries Content-Disposition: attachment, so navigating an anchor
      // to it downloads without leaving the page.
      const a = document.createElement('a');
      a.href = url; a.rel = 'noopener'; a.style.display = 'none';
      document.body.appendChild(a); a.click(); a.remove();
    } catch (err) {
      setDocError(err.message || 'Could not download this file.');
    }
    setDocBusy(null);
  }

  const templates = docs.filter(d => d.kind === 'template');
  const previewDoc = templates.find(d => d.id === previewId) || templates[0] || null;
  // Templates are PDF-only going forward; anything older just gets a download prompt.
  const previewable = !!previewDoc && /\.pdf$/i.test(previewDoc.filename || '');

  // Mint an inline URL for the template being previewed, only once the tab is opened.
  React.useEffect(() => {
    let active = true;
    setPreviewUrl(null); setPreviewError('');
    if (tab !== 'templates' || !previewable) return;
    window.ayaniDocumentPreviewUrl(previewDoc)
      .then(url => { if (active) setPreviewUrl(url); })
      .catch(err => { if (active) setPreviewError(err.message || 'Could not load this template.'); });
    return () => { active = false; };
  }, [tab, previewDoc?.id]);

  // Switching to a document tab pauses the video (it stays mounted so coming back
  // doesn't re-mint a token or lose the progress tracker).
  function pickTab(next) {
    if (next !== 'video') { try { playerRef.current?.pause(); } catch (_) {} }
    setTab(next);
  }

  // Mint a fresh embed token whenever the lesson changes.
  React.useEffect(() => {
    let active = true;
    setStatus('loading');
    setError('');
    setEmbedUrl(null);
    setFrameLoaded(false);
    furthestRef.current = 0;
    durationRef.current = 0;
    lastSentRef.current = -1;
    playerRef.current = null;

    if (!lesson) { setStatus('error'); setError('No lesson selected.'); return; }

    (async () => {
      const body = lesson.id ? { lesson_id: lesson.id } : { module_code: moduleCode, n: lesson.n };
      const { data, error: fnError } = await window.supabaseClient.functions.invoke('get-playback-token', { body });
      if (!active) return;
      if (fnError) {
        let msg = fnError.message || 'Could not load this video.';
        try { const b = await fnError.context?.json(); if (b?.error) msg = b.error; } catch (_) {}
        setError(msg);
        setStatus('error');
        return;
      }
      setEmbedUrl(data.embed_url);
      setStatus('ready');
    })();

    return () => { active = false; postProgress(); };
  }, [lesson?.id, lesson?.n, moduleCode]);

  // Bunny/player.js requires the iframe to be fully loaded before the Player object
  // is created (constructing it earlier races the embed's own postMessage handshake
  // and 'ready' silently never fires) -- so this waits for the iframe's own `load`
  // event rather than running as soon as the src is set.
  function onFrameLoad() {
    setFrameLoaded(true);
    setupPlayer();
  }

  function setupPlayer() {
    if (!iframeRef.current || !window.playerjs || playerRef.current) return;
    const player = new window.playerjs.Player(iframeRef.current);
    playerRef.current = player;
    player.on('ready', () => {
      player.on('timeupdate', (data) => {
        if (typeof data?.seconds === 'number') furthestRef.current = Math.max(furthestRef.current, data.seconds);
        if (typeof data?.duration === 'number' && data.duration > 0) durationRef.current = data.duration;
      });
      player.on('pause', postProgress);
      player.on('ended', postProgress);
    });
  }

  // Periodic progress post while this lesson's video is on screen. Independent of
  // the player.js handshake above -- postProgress no-ops until duration is known.
  React.useEffect(() => {
    if (status !== 'ready') return;
    const interval = setInterval(postProgress, AY_PROGRESS_POST_INTERVAL_MS);
    return () => { clearInterval(interval); postProgress(); };
  }, [status, embedUrl]);

  return (
    <div className="ay-screen ay-video" data-screen-label="04 Video">
      <AyaniBeam />
      <ExitPanel progress={modProgress} onExit={onExit} />

      <div className="ay-video-tag-pill">{lesson?.title || 'Ayani Introduction – 301 / 01'}</div>
      <div className="ay-video-tabs">
        <button className={`ay-video-tab ${tab === 'video' ? 'is-active' : ''}`} onClick={() => pickTab('video')}>Video</button>
        <button className={`ay-video-tab ${tab === 'templates' ? 'is-active' : ''}`} onClick={() => pickTab('templates')}>Templates</button>
        <button className={`ay-video-tab ${tab === 'extra' ? 'is-active' : ''}`} onClick={() => pickTab('extra')}>Extra</button>
      </div>

      <div className={`ay-video-void ay-video-void--${tab === 'video' ? 'video' : 'docs'}`}>
        {tab === 'templates' && docsStatus === 'ready' && previewDoc && (
          <div className="ay-docs ay-template-view">
            <div className="ay-template-bar">
              <div className="ay-template-picks">
                {templates.map(d => (
                  <button key={d.id} className={`ay-template-pick ${d.id === previewDoc.id ? 'is-active' : ''}`}
                    onClick={() => setPreviewId(d.id)}>{d.label}</button>
                ))}
              </div>
              <button className="ay-template-download" disabled={!!docBusy} onClick={() => download(previewDoc)}>
                {docBusy === previewDoc.id ? 'Preparing…' : 'Download'}
              </button>
            </div>
            <div className="ay-template-frame">
              {previewUrl && <iframe key={previewUrl} src={previewUrl} title={previewDoc.label} />}
              {previewable && !previewUrl && !previewError && <AyVideoLoading label="Loading template…" />}
              {!previewable && <div className="ay-video-status">No preview for {previewDoc.filename} — use Download.</div>}
              {previewError && <div className="ay-video-status is-error">{previewError}</div>}
            </div>
            {docError && <div className="ay-docs-error">{docError}</div>}
          </div>
        )}
        {tab !== 'video' && !(tab === 'templates' && docsStatus === 'ready' && previewDoc) && (
          <div className="ay-docs">
            {docsStatus === 'loading' && <div className="ay-video-status">Loading…</div>}
            {docsStatus === 'error' && <div className="ay-video-status is-error">Could not load documents.</div>}
            {docsStatus === 'ready' && (() => {
              const list = docs.filter(d => d.kind === (tab === 'templates' ? 'template' : 'extra'));
              if (!list.length) return <div className="ay-video-status">No {tab === 'templates' ? 'templates' : 'extra material'} for this lesson yet.</div>;
              return (
                <div className="ay-docs-list">
                  {list.map(d => (
                    <button key={d.id} className="ay-doc" disabled={!!docBusy} onClick={() => download(d)}>
                      <span className="ay-doc-label">{d.label}</span>
                      <span className="ay-doc-file">{d.filename}</span>
                      <span className="ay-doc-action">{docBusy === d.id ? 'Preparing…' : 'Download'}</span>
                    </button>
                  ))}
                </div>
              );
            })()}
            {docError && <div className="ay-docs-error">{docError}</div>}
          </div>
        )}
        {status === 'ready' && embedUrl && (
          <div className={`ay-video-frame ${tab !== 'video' ? 'is-hidden' : ''}`}>
            <iframe
              ref={iframeRef}
              id="ay-bunny-player"
              src={embedUrl}
              allow="autoplay; fullscreen; encrypted-media"
              allowFullScreen
              onLoad={onFrameLoad}
            />
            {!frameLoaded && <AyVideoLoading label="Loading player…" />}
          </div>
        )}
        {tab === 'video' && status === 'loading' && <AyVideoLoading label="Loading video…" />}
        {tab === 'video' && status === 'error' && <div className="ay-video-status is-error">{error}</div>}
      </div>
    </div>
  );
}
window.VideoScreen = VideoScreen;
