'use client';

import { RefObject, useEffect } from 'react';
import { AlertTriangle, Loader2 } from 'lucide-react';
import type { DetectionResultLog } from '@/types';
import { useDetectionThumbnails } from './useDetectionThumbnails';
import BoundingBoxOverlay from '@/components/annotation/boundingBoxOverlay';
import {
  MediaPlayer,
  MediaProvider,
  Poster,
  isVideoProvider,
  type MediaPlayerInstance,
  useMediaProvider,
} from '@vidstack/react';
import {
  DefaultVideoLayout,
  defaultLayoutIcons,
} from '@vidstack/react/player/layouts/default';

interface AnnotatedVideoPlayerProps {
  videoRef: RefObject<MediaPlayerInstance | null>;
  logs: DetectionResultLog[];
  visibleLogs: DetectionResultLog[];
  videoWidth: number;
  videoHeight: number;
  videoUrl: string | null;
  isLoading: boolean;
  isError: boolean;
  onRetry: () => void;
  onTimeUpdate: () => void;
  onVideoFrame: (mediaTime: number) => void;
  onSeeked: () => void;
}

function VideoFrameSync({
  onVideoFrame,
}: Pick<AnnotatedVideoPlayerProps, 'onVideoFrame'>) {
  const provider = useMediaProvider();

  useEffect(() => {
    if (!isVideoProvider(provider)) return;

    const video = provider.video;
    let callbackId: number;

    const update = (_now: number, metadata: VideoFrameCallbackMetadata) => {
      onVideoFrame(metadata.mediaTime);
      callbackId = video.requestVideoFrameCallback(update);
    };

    callbackId = video.requestVideoFrameCallback(update);

    return () => video.cancelVideoFrameCallback(callbackId);
  }, [onVideoFrame, provider]);

  return null;
}

export default function AnnotatedVideoPlayer({
  videoRef,
  logs,
  visibleLogs,
  videoWidth,
  videoHeight,
  videoUrl,
  isLoading,
  isError,
  onRetry,
  onTimeUpdate,
  onVideoFrame,
  onSeeked,
}: AnnotatedVideoPlayerProps) {
  const thumbnails = useDetectionThumbnails(logs);

  return (
    <div className="relative overflow-hidden rounded-lg border bg-black">
      {videoUrl ? (
        <MediaPlayer
          ref={videoRef}
          src={{ src: videoUrl, type: 'video/mp4' }}
          viewType="video"
          streamType="on-demand"
          crossOrigin
          playsInline
          onTimeUpdate={onTimeUpdate}
          onSeeked={onSeeked}
          className="detection-video-player aspect-video w-full"
        >
          <MediaProvider>
            <Poster className="vds-poster" />
          </MediaProvider>
          <VideoFrameSync onVideoFrame={onVideoFrame} />
          <BoundingBoxOverlay
            detections={visibleLogs}
            videoWidth={videoWidth}
            videoHeight={videoHeight}
          />
          <DefaultVideoLayout
            thumbnails={thumbnails}
            icons={defaultLayoutIcons}
          />
        </MediaPlayer>
      ) : (
        <div className="flex aspect-video w-full flex-col items-center justify-center gap-3 text-center text-muted-foreground">
          {isError ? (
            <>
              <AlertTriangle className="h-7 w-7 text-destructive" />
              <p className="text-sm font-medium text-destructive">
                Failed to load the annotated video.
              </p>
              <button
                type="button"
                onClick={onRetry}
                className="text-xs font-semibold uppercase tracking-wider text-primary hover:underline"
              >
                Retry
              </button>
            </>
          ) : (
            <>
              <Loader2 className="h-7 w-7 animate-spin text-primary" />
              <p className="text-xs">
                {isLoading
                  ? 'Loading annotated video...'
                  : 'Preparing video...'}
              </p>
            </>
          )}
        </div>
      )}
    </div>
  );
}
