'use client';

import { useEffect, useRef, forwardRef, useImperativeHandle } from 'react';

export interface HlsVideoHandle {
  play(): void;
  pause(): void;
  get paused(): boolean;
}

const HlsVideo = forwardRef<
  HlsVideoHandle,
  { url: string; className?: string; onError?: () => void; onLoaded?: () => void }
>(
  ({ url, className, onError, onLoaded }, ref) => {
    const videoRef = useRef<HTMLVideoElement>(null);

    useImperativeHandle(ref, () => ({
      play: () => videoRef.current?.play(),
      pause: () => videoRef.current?.pause(),
      get paused() {
        return videoRef.current?.paused ?? true;
      },
    }));

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

      let hlsInstance: { destroy(): void } | null = null;
      let cancelled = false;

      (async () => {
        const { default: Hls } = await import('hls.js');
        if (cancelled) return;
        if (Hls.isSupported()) {
          const hls = new Hls({ enableWorker: false, lowLatencyMode: true });
          hls.on(Hls.Events.ERROR, (_e: unknown, data: { fatal?: boolean }) => {
            if (data.fatal) onError?.();
          });
          hls.on(Hls.Events.MANIFEST_PARSED, () => onLoaded?.());
          hls.loadSource(url);
          hls.attachMedia(video);
          hlsInstance = hls;
        } else if (video.canPlayType('application/vnd.apple.mpegurl')) {
          video.src = url;
        }
      })();

      return () => {
        cancelled = true;
        hlsInstance?.destroy();
      };
    }, [url, onError, onLoaded]);

    return (
      <video
        ref={videoRef}
        autoPlay
        muted
        playsInline
        onError={() => onError?.()}
        onCanPlay={() => onLoaded?.()}
        onLoadedData={() => onLoaded?.()}
        onPlaying={() => onLoaded?.()}
        className={className}
      />
    );
  },
);

HlsVideo.displayName = 'HlsVideo';
export default HlsVideo;
