/* Player / Preview stage */
const { useRef: usePR, useEffect: usePE, useState: usePS } = React;

function Player({ currentTime, totalDuration, activeClip, media, textOverlays, isPlaying, onPlayToggle, onStep }) {
  const TEXT_OVERLAY_Y_OFFSET_PX = 24;
  const clip = activeClip;
  const asset = clip ? media.find((m) => m.id === clip.mediaId) : null;
  const videoRef = usePR(null);
  const prevVisualRef = usePR(null);
  const [videoSrc, setVideoSrc] = usePS("");
  const [videoReady, setVideoReady] = usePS(false);
  const [holdFrame, setHoldFrame] = usePS("");
  const isClipLive =
    !!clip &&
    currentTime >= clip.start &&
    currentTime < clip.start + clip.duration;
  const localClipTime = clip
    ? Math.max(
        0,
        (isClipLive ? currentTime - clip.start : 0) + (clip.trimIn || 0),
      )
    : 0;

  usePE(() => {
    const video = videoRef.current;
    const nextVisual = asset && (asset.type === "video" || asset.type === "image") ? asset : null;
    const prevVisual = prevVisualRef.current;

    if (!nextVisual) {
      setVideoSrc("");
      setVideoReady(false);
      setHoldFrame("");
      if (video) video.pause();
      prevVisualRef.current = null;
      return;
    }

    if (nextVisual.type === "image") {
      setVideoSrc("");
      setVideoReady(false);
      setHoldFrame("");
      if (video) video.pause();
      prevVisualRef.current = nextVisual;
      return;
    }

    if (videoSrc !== nextVisual.url) {
      let fallbackFrame = "";

      if (
        prevVisual &&
        prevVisual.type === "video" &&
        video &&
        video.readyState >= 2 &&
        video.videoWidth > 0 &&
        video.videoHeight > 0
      ) {
        try {
          const canvas = document.createElement("canvas");
          canvas.width = video.videoWidth;
          canvas.height = video.videoHeight;
          const ctx = canvas.getContext("2d");
          if (ctx) {
            ctx.drawImage(video, 0, 0, canvas.width, canvas.height);
            fallbackFrame = canvas.toDataURL("image/jpeg", 0.9);
          }
        } catch (_) {
          /* ignore frame-capture failures */
        }
      } else if (prevVisual && prevVisual.type === "image") {
        fallbackFrame = prevVisual.url;
      }

      setHoldFrame(fallbackFrame);
      setVideoReady(false);
      setVideoSrc(nextVisual.url);
    }

    prevVisualRef.current = nextVisual;
  }, [asset, videoSrc]);

  usePE(() => {
    const video = videoRef.current;
    if (!video || !clip || !asset || asset.type !== "video" || videoSrc !== asset.url || !videoReady) {
      if (video) video.pause();
      return;
    }

    const maxLocal = Math.max(0, clip.duration - 0.05);
    const seekTime = Math.min(localClipTime, maxLocal);
    if (Math.abs((video.currentTime || 0) - seekTime) > 0.15) {
      try {
        video.currentTime = seekTime;
      } catch (_) {
        /* ignore browser seek races */
      }
    }

    if (isPlaying && isClipLive) {
      video.play().catch(() => {
        /* ignore autoplay race in prototype */
      });
    } else {
      video.pause();
    }
  }, [clip, asset, localClipTime, isPlaying, isClipLive, videoSrc, videoReady]);

  const tcCur = formatTC(currentTime);
  const tcTotal = formatTC(totalDuration);
  const activeTextOverlays = (Array.isArray(textOverlays) ? textOverlays : []).filter((cue) => {
    const end = Number.isFinite(cue.end) ? cue.end : Infinity;
    return currentTime >= cue.start && currentTime < end;
  });

  return (
    <section className="panel">
      <div className="panel-header">
        <div style={{ display: "flex", alignItems: "center", gap: 8 }}>
          <span style={{ fontSize: 11, textTransform: "uppercase", letterSpacing: "0.1em", color: "var(--text-2)", fontWeight: 600 }}>Player</span>
        </div>
        <div className="panel-meta">{tcCur} / {tcTotal}</div>
      </div>

      <div className="player-wrap">
        <div className="stage-wrap">
          <div className="stage">
            <div className="stage-inner">
              {asset ? (
                asset.type === "video" ? (
                  <>
                    {holdFrame && !videoReady && (
                      <img
                        className="stage-hold-frame"
                        src={holdFrame}
                        alt=""
                        aria-hidden="true"
                      />
                    )}
                    <video
                      ref={videoRef}
                      src={videoSrc}
                      muted
                      playsInline
                      preload="auto"
                      onLoadedData={() => {
                        setVideoReady(true);
                        setHoldFrame("");
                      }}
                      onCanPlay={() => {
                        setVideoReady(true);
                        setHoldFrame("");
                      }}
                      style={{ opacity: videoReady ? 1 : 0 }}
                    />
                  </>
                ) : (
                  <img src={asset.url} alt={asset.name} />
                )
              ) : (
                <div className="stage-empty">Drop clips on the timeline<br/>to preview</div>
              )}
            </div>
            <div className="stage-overlay" />
            {activeTextOverlays.length > 0 && (
              <div className="stage-trailer-copy">
                {activeTextOverlays.map((cue) => (
                  <span
                    key={cue.id}
                    className="stage-trailer-line"
                    style={{ left: `${cue.x}%`, top: `calc(${cue.y}% - ${TEXT_OVERLAY_Y_OFFSET_PX}px)` }}
                  >
                    {cue.text}
                  </span>
                ))}
              </div>
            )}
            <div className="stage-hud-b">
              <div>{tcCur}</div>
            </div>
          </div>
        </div>
        <div className="player-controls">
          <button className="shuttle-btn" onClick={() => onStep(-1)} title="Back 0.5s"><Icon.SkipBack/></button>
          <button className="play-btn" onClick={onPlayToggle}>
            {isPlaying ? <Icon.Pause/> : <Icon.Play/>}
            <span>{isPlaying ? "Pause" : "Play"}</span>
          </button>
          <button className="shuttle-btn" onClick={() => onStep(1)} title="Forward 0.5s"><Icon.SkipFwd/></button>
        </div>
      </div>
    </section>
  );
}

function formatTC(s) {
  const safe = Math.max(0, s);
  const m = Math.floor(safe / 60).toString().padStart(2, "0");
  const sec = Math.floor(safe % 60).toString().padStart(2, "0");
  const f = Math.floor((safe % 1) * 24).toString().padStart(2, "0");
  return `${m}:${sec}:${f}`;
}

window.Player = Player;
window.formatTC = formatTC;
