// media.jsx — smart media component with video/image/placeholder fallback
// Probes asset existence; when missing, renders a clearly-labeled placeholder
// so you always know what to drop in.

const { useState, useEffect, useRef, useCallback, createContext, useContext } = React;

// ——— asset probe (cached) ———
const _assetCache = new Map();
function useAssetExists(path) {
  const [state, setState] = useState(() => _assetCache.has(path) ? _assetCache.get(path) : null);
  useEffect(() => {
    if (!path) return;
    if (_assetCache.has(path)) { setState(_assetCache.get(path)); return; }
    let cancelled = false;
    fetch(path, { method: 'HEAD' })
      .then(r => {
        if (cancelled) return;
        const ok = r.ok;
        _assetCache.set(path, ok);
        setState(ok);
      })
      .catch(() => { if (!cancelled) { _assetCache.set(path, false); setState(false); } });
    return () => { cancelled = true; };
  }, [path]);
  return state; // null = probing, true/false once known
}

// ——— Placeholder card ———
function AssetPlaceholder({ label, aspect = '3/4', icon = '·', note }) {
  return (
    <div
      className="lx-placeholder"
      style={{ aspectRatio: aspect }}
      role="img"
      aria-label={`Missing asset: ${label}`}
    >
      <div className="lx-placeholder-bg" />
      <div className="lx-placeholder-inner">
        <div className="lx-placeholder-icon">{icon}</div>
        <div className="lx-placeholder-label">ASSET NEEDED</div>
        <div className="lx-placeholder-file">{label}</div>
        {note && <div className="lx-placeholder-note">{note}</div>}
      </div>
    </div>
  );
}

// ——— Smart Media: video → image → placeholder ———
// Props:
//   video — path like "assets/hero.mp4" (optional)
//   poster — path like "assets/hero.jpg" (optional, also used as image fallback)
//   image — path like "assets/hero.jpg" (if you only want static image)
//   label — friendly name shown in placeholder
//   aspect — aspect ratio string like "3/4" or "16/9"
//   hoverPlay — bool; pause until hovered (for tiles)
//   note — small descriptive text in placeholder
function Media({ video, poster, image, label, aspect = '16/9', hoverPlay = false, forceVideo = false, note, icon, className = '', children }) {
  const videoOk = useAssetExists(video);
  const posterOk = useAssetExists(poster || image);
  const videoRef = useRef(null);
  const containerRef = useRef(null);
  const [videoFailed, setVideoFailed] = useState(false);

  const play = useCallback(() => {
    const v = videoRef.current;
    if (!v) return;
    v.muted = true;
    v.defaultMuted = true;
    v.playsInline = true;
    try { v.play(); } catch (_) {}
  }, []);
  const pause = useCallback(() => {
    const v = videoRef.current;
    if (!v) return;
    try { v.pause(); } catch (_) {}
  }, []);

  useEffect(() => {
    if (!hoverPlay) return;
    const el = containerRef.current;
    if (!el) return;
    const enter = () => play();
    const leave = () => { pause(); if (videoRef.current) videoRef.current.currentTime = 0; };
    el.addEventListener('mouseenter', enter);
    el.addEventListener('mouseleave', leave);
    el.addEventListener('touchstart', enter, { passive: true });
    return () => {
      el.removeEventListener('mouseenter', enter);
      el.removeEventListener('mouseleave', leave);
      el.removeEventListener('touchstart', enter);
    };
  }, [hoverPlay, play, pause]);

  // Mobile browsers can ignore autoPlay on first paint; aggressively retry play
  // for forced hero videos while keeping playback muted + inline.
  useEffect(() => {
    if (!forceVideo || hoverPlay) return;
    const v = videoRef.current;
    if (!v) return;
    v.muted = true;
    v.defaultMuted = true;
    v.playsInline = true;
    v.setAttribute('playsinline', 'true');
    v.setAttribute('webkit-playsinline', 'true');
    v.setAttribute('x5-playsinline', 'true');
    const tryPlay = () => { try { v.play(); } catch (_) {} };
    tryPlay();
    const t1 = setTimeout(tryPlay, 120);
    const t2 = setTimeout(tryPlay, 600);
    const t3 = setTimeout(tryPlay, 1400);
    v.addEventListener('loadeddata', tryPlay);
    v.addEventListener('canplay', tryPlay);
    document.addEventListener('visibilitychange', tryPlay, { passive: true });
    window.addEventListener('pageshow', tryPlay, { passive: true });
    window.addEventListener('touchend', tryPlay, { passive: true });
    return () => {
      clearTimeout(t1);
      clearTimeout(t2);
      clearTimeout(t3);
      v.removeEventListener('loadeddata', tryPlay);
      v.removeEventListener('canplay', tryPlay);
      document.removeEventListener('visibilitychange', tryPlay);
      window.removeEventListener('pageshow', tryPlay);
      window.removeEventListener('touchend', tryPlay);
    };
  }, [forceVideo, hoverPlay]);

  // Ensure seamless loop (hero + tiles); some WebViews ignore the loop attribute alone
  useEffect(() => {
    if (videoOk !== true) return;
    const v = videoRef.current;
    if (!v) return;
    v.loop = true;
    const onEnded = () => {
      v.currentTime = 0;
      try { v.play(); } catch (_) {}
    };
    v.addEventListener('ended', onEnded);
    return () => v.removeEventListener('ended', onEnded);
  }, [videoOk]);

  // Decide what to render
  if (forceVideo && video && !videoFailed) {
    return (
      <div ref={containerRef} className={`lx-media lx-media-video ${className}`} style={{ aspectRatio: aspect }}>
        <video
          ref={videoRef}
          src={video}
          poster={posterOk ? (poster || image) : undefined}
          muted
          loop={true}
          playsInline
          preload={hoverPlay ? 'none' : 'metadata'}
          autoPlay={!hoverPlay}
          onError={() => setVideoFailed(true)}
        />
        {children}
      </div>
    );
  }
  if (videoOk === true) {
    return (
      <div ref={containerRef} className={`lx-media lx-media-video ${className}`} style={{ aspectRatio: aspect }}>
        <video
          ref={videoRef}
          src={video}
          poster={posterOk ? (poster || image) : undefined}
          muted
          loop={true}
          playsInline
          preload={hoverPlay ? 'none' : 'metadata'}
          autoPlay={!hoverPlay}
          onError={() => setVideoFailed(true)}
        />
        {children}
      </div>
    );
  }
  if (posterOk === true) {
    return (
      <div ref={containerRef} className={`lx-media lx-media-image ${className}`} style={{ aspectRatio: aspect, backgroundImage: `url(${poster || image})` }}>
        {children}
      </div>
    );
  }
  if (videoOk === null && posterOk === null) {
    // still probing — avoid flash of placeholder
    return (
      <div ref={containerRef} className={`lx-media lx-media-probing ${className}`} style={{ aspectRatio: aspect }}>
        {children}
      </div>
    );
  }
  return (
    <div ref={containerRef} className={`lx-media lx-media-empty ${className}`} style={{ aspectRatio: aspect }}>
      <AssetPlaceholder label={label} aspect={aspect} icon={icon} note={note} />
      {children}
    </div>
  );
}

Object.assign(window, { Media, AssetPlaceholder, useAssetExists });
