'use client';

/**
 * useVideoPositionCache - Manages video playback position caching
 *
 * Saves position periodically during playback and restores on load.
 */

import { useCallback, useEffect, useRef } from 'react';

import { useMediaCacheStore } from '../../../stores/mediaCache';

// =============================================================================
// TYPES
// =============================================================================

export interface UseVideoPositionCacheOptions {
  /** Unique key for caching (e.g., video URL or stream key) */
  cacheKey: string | null;
  /** Current playback time in seconds */
  currentTime: number;
  /** Video duration in seconds */
  duration: number;
  /** Whether video is currently playing */
  isPlaying: boolean;
  /** Whether video is ready to play */
  isReady: boolean;
  /** Callback to seek to a specific time */
  onSeek: (time: number) => void;
}

export interface UseVideoPositionCacheReturn {
  /** Manually save current position */
  savePosition: () => void;
  /** Clear saved position */
  clearPosition: () => void;
}

// =============================================================================
// CONSTANTS
// =============================================================================

/** Save interval in seconds */
const SAVE_INTERVAL = 5;

/** Minimum offset from end to restore (avoid restoring at the very end) */
const END_BUFFER = 1;

// =============================================================================
// HOOK
// =============================================================================

export function useVideoPositionCache(
  options: UseVideoPositionCacheOptions
): UseVideoPositionCacheReturn {
  const { cacheKey, currentTime, duration, isPlaying, isReady, onSeek } = options;

  // Get stable function references from store
  const saveVideoPosition = useMediaCacheStore.getState().saveVideoPosition;
  const getVideoPosition = useMediaCacheStore.getState().getVideoPosition;

  const lastSavedTimeRef = useRef<number>(0);
  const hasRestoredRef = useRef<boolean>(false);

  // Restore position when ready
  useEffect(() => {
    if (!isReady || !cacheKey || hasRestoredRef.current) return;

    const savedPosition = getVideoPosition(cacheKey);
    if (savedPosition && savedPosition > 0 && duration > 0) {
      // Only restore if position is valid (not at the end)
      if (savedPosition < duration - END_BUFFER) {
        onSeek(savedPosition);
      }
    }
    hasRestoredRef.current = true;
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [isReady, cacheKey, duration, onSeek]);

  // Reset restored flag when cache key changes
  useEffect(() => {
    hasRestoredRef.current = false;
    lastSavedTimeRef.current = 0;
  }, [cacheKey]);

  // Save position periodically during playback
  useEffect(() => {
    if (!cacheKey || !isPlaying || currentTime <= 0) return;

    const timeSinceLastSave = currentTime - lastSavedTimeRef.current;
    if (timeSinceLastSave >= SAVE_INTERVAL || timeSinceLastSave < 0) {
      saveVideoPosition(cacheKey, currentTime);
      lastSavedTimeRef.current = currentTime;
    }
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [cacheKey, isPlaying, currentTime]);

  const savePosition = useCallback(() => {
    if (cacheKey && currentTime > 0) {
      saveVideoPosition(cacheKey, currentTime);
      lastSavedTimeRef.current = currentTime;
    }
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [cacheKey, currentTime]);

  const clearPosition = useCallback(() => {
    if (cacheKey) {
      saveVideoPosition(cacheKey, 0);
    }
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [cacheKey]);

  return {
    savePosition,
    clearPosition,
  };
}
