import { useEffect, useRef, useState } from 'react';
import type Player from 'video.js/dist/types/player';
import { usePlayerStore } from '../store/playerStore';

export function useFrameStep(playerRef: React.RefObject<Player | null>) {
  const detectedFps = useRef(30);
  // 안정적인 fps: 재생 중 연속 2회 이상 동일 값이 나와야 확정
  const [stableFps, setStableFps] = useState(30);
  const lastMeasured = useRef(30);
  const stableCount = useRef(0);
  const store = usePlayerStore();

  useEffect(() => {
    const video = playerRef.current?.tech(true)?.el() as HTMLVideoElement | null;
    if (!video || !('requestVideoFrameCallback' in video)) return;

    let frameCount = 0;
    let startTime: number | null = null;
    let handle = 0;

    const measure = (_now: number, meta: { mediaTime: number }) => {
      if (startTime === null) {
        // 첫 호출은 시작점만 기록하고 카운트하지 않음.
        // 카운트에 포함하면 elapsed ≈ 1.001s에 frameCount=31이 되어 31fps로 오감지됨.
        startTime = meta.mediaTime;
        handle = (video as any).requestVideoFrameCallback(measure);
        return;
      }
      frameCount++;
      const elapsed = meta.mediaTime - startTime;
      if (elapsed >= 1.0) {
        const fps = Math.round(frameCount / elapsed);
        if (fps >= 24 && fps <= 120) {
          // 같은 값이 연속 2회 이상 나와야 안정된 fps로 확정
          if (fps === lastMeasured.current) {
            stableCount.current++;
            if (stableCount.current >= 2) {
              detectedFps.current = fps;
              setStableFps(fps);
              store.setFps(fps);
            }
          } else {
            lastMeasured.current = fps;
            stableCount.current = 1;
          }
        }
        frameCount = 0;
        startTime = null;
      }
      handle = (video as any).requestVideoFrameCallback(measure);
    };

    handle = (video as any).requestVideoFrameCallback(measure);
    return () => { (video as any).cancelVideoFrameCallback(handle); };
  // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [playerRef.current]);

  const stepForward = () => {
    const player = playerRef.current;
    if (!player || player.paused() === false) return;
    const step = 1 / detectedFps.current;
    player.currentTime((player.currentTime() ?? 0) + step);
  };

  const stepBackward = () => {
    const player = playerRef.current;
    if (!player || player.paused() === false) return;
    const step = 1 / detectedFps.current;
    player.currentTime(Math.max(0, (player.currentTime() ?? 0) - step));
  };

  return { stepForward, stepBackward, fps: stableFps };
}
