import { useEffect, useRef } from "react";
import { getLocalTimeWithinSegment } from "../lib/timeline";
import type { VideoSegment } from "../types/lecture";
import type { PauseMode, ViewportMode } from "../types/player";

interface VideoSkeletonPlayerProps {
  segment: VideoSegment | null;
  nextSegment: VideoSegment | null;
  globalTimeSec: number;
  lectureDurationSec: number;
  pauseMode: PauseMode;
  viewportMode: ViewportMode;
  onGlobalTimeChange: (nextTime: number) => void;
  onSegmentError: (message: string) => void;
  onAutoplayBlocked: () => void;
  onTogglePlayback: () => void;
}

function attemptPlay(
  video: HTMLVideoElement,
  onAutoplayBlocked: () => void
) {
  try {
    const playResult = video.play();
    if (playResult && typeof playResult.catch === "function") {
      void playResult.catch(() => {
        onAutoplayBlocked();
      });
    }
  } catch {
    onAutoplayBlocked();
  }
}

export function VideoSkeletonPlayer({
  segment,
  nextSegment,
  globalTimeSec,
  lectureDurationSec,
  pauseMode,
  viewportMode,
  onGlobalTimeChange,
  onSegmentError,
  onAutoplayBlocked,
  onTogglePlayback
}: VideoSkeletonPlayerProps) {
  const videoRef = useRef<HTMLVideoElement | null>(null);
  const localTimeRef = useRef(0);

  const desiredLocalTime = segment
    ? getLocalTimeWithinSegment(segment, globalTimeSec)
    : 0;

  useEffect(() => {
    const video = videoRef.current;
    if (!video || !segment) {
      return;
    }

    const timeDifference = Math.abs(video.currentTime - desiredLocalTime);
    if (timeDifference > 0.45) {
      video.currentTime = desiredLocalTime;
      localTimeRef.current = desiredLocalTime;
    }
  }, [desiredLocalTime, segment?.id]);

  useEffect(() => {
    const video = videoRef.current;
    if (!video) {
      return;
    }

    if (pauseMode === "playing") {
      attemptPlay(video, onAutoplayBlocked);
      return;
    }

    video.pause();
  }, [onAutoplayBlocked, pauseMode, segment?.id]);

  if (!segment) {
    return (
      <div className={`video-stage video-stage--${viewportMode}`}>
        <div className="video-stage__placeholder">
          <p className="eyebrow">Video pending</p>
          <p>No active segment is available at this lecture time.</p>
        </div>
      </div>
    );
  }

  return (
    <div className={`video-stage video-stage--${viewportMode}`}>
      <div
        className="video-stage__window"
        role="button"
        tabIndex={0}
        aria-label={pauseMode === "playing" ? "Pause video" : "Resume video"}
        onClick={onTogglePlayback}
        onKeyDown={(event) => {
          if (event.key === " " || event.key === "Enter") {
            event.preventDefault();
            onTogglePlayback();
          }
        }}
      >
        <video
          key={segment.id}
          ref={videoRef}
          className="video-stage__video"
          preload="auto"
          autoPlay
          muted
          playsInline
          controls={false}
          poster={segment.poster}
          src={segment.src}
          onLoadedMetadata={(event) => {
            const video = event.currentTarget;
            video.currentTime = desiredLocalTime;
            localTimeRef.current = desiredLocalTime;

            if (pauseMode === "playing") {
              attemptPlay(video, onAutoplayBlocked);
            }
          }}
          onTimeUpdate={(event) => {
            const video = event.currentTarget;
            const cappedLocalTime = Math.min(video.currentTime, segment.durationSec);
            localTimeRef.current = cappedLocalTime;
            onGlobalTimeChange(segment.startTimeSec + cappedLocalTime);

            if (
              cappedLocalTime >= segment.durationSec - 0.08 &&
              segment.startTimeSec + segment.durationSec < lectureDurationSec
            ) {
              onGlobalTimeChange(segment.startTimeSec + segment.durationSec);
            }
          }}
          onEnded={() => {
            onGlobalTimeChange(segment.startTimeSec + segment.durationSec);
          }}
          onError={() => {
            onSegmentError(`Failed to load ${segment.id}. Retry by resuming playback.`);
          }}
        />

        <div className="video-stage__meta">
          <span>{segment.id}</span>
          <span>
            {Math.min(localTimeRef.current, segment.durationSec).toFixed(1)} /{" "}
            {segment.durationSec.toFixed(1)}s
          </span>
        </div>
      </div>

      <div className="video-stage__next">
        <span>Up next</span>
        <strong>{nextSegment?.id ?? "End of lecture"}</strong>
      </div>
    </div>
  );
}
