/**
 * useTransitionPreview Hook
 *
 * Manages transition video preview state in the constructor.
 * Used to preview forward and reverse transitions before navigation.
 */

import { useState, useCallback, useMemo } from 'react';

/**
 * Transition preview state
 */
export interface TransitionPreviewState {
  /** Resolved video URL for playback */
  videoUrl: string;
  /** Raw storage path for cache lookup */
  storageKey: string;
  /** Playback mode: none (forward), reverse (auto-reverse), separate (use reverseVideoUrl) */
  reverseMode: 'none' | 'reverse' | 'separate';
  /** Resolved URL for separate reverse video */
  reverseVideoUrl?: string;
  /** Raw storage path for reverse video cache lookup */
  reverseStorageKey?: string;
  /** Duration in seconds */
  durationSec?: number;
  /** Display title for the preview */
  title: string;
}

/**
 * Navigation element with transition configuration
 */
interface TransitionElement {
  type: string;
  label?: string;
  navLabel?: string;
  transitionVideoUrl?: string;
  transitionReverseMode?: 'auto_reverse' | 'separate_video';
  reverseVideoUrl?: string;
  transitionDurationSec?: number;
}

interface UseTransitionPreviewOptions {
  /** Function to check if element type is a navigation type */
  isNavigationElementType: (type: string) => boolean;
  /** Callback when error occurs (no video configured, etc.) */
  onError?: (message: string) => void;
}

interface UseTransitionPreviewResult {
  /** Current preview state (null if not previewing) */
  preview: TransitionPreviewState | null;
  /** Pending navigation page ID (used for actual navigation after preview) */
  pendingPageId: string;
  /** Open transition preview for an element */
  openPreview: (
    element: TransitionElement,
    direction: 'forward' | 'back',
  ) => void;
  /** Open transition preview with a specific target page */
  openPreviewWithTarget: (
    element: TransitionElement,
    direction: 'forward' | 'back',
    targetPageId: string,
  ) => void;
  /** Close the preview */
  closePreview: () => void;
  /** Whether a preview is currently active */
  isActive: boolean;
}

/**
 * Hook for managing transition preview state.
 * Handles opening previews for forward and back navigation.
 *
 * @example
 * const {
 *   preview,
 *   pendingPageId,
 *   openPreview,
 *   closePreview,
 *   isActive,
 * } = useTransitionPreview({
 *   isNavigationElementType,
 *   onError: setErrorMessage,
 * });
 *
 * // Open preview when clicking element
 * const handleClick = () => {
 *   openPreviewWithTarget(element, 'forward', targetPage.id);
 * };
 *
 * // Use with useTransitionPlayback hook
 * useTransitionPlayback({
 *   transition: preview,
 *   onComplete: (targetId) => {
 *     switchToPage(targetId);
 *     closePreview();
 *   },
 * });
 */
export function useTransitionPreview({
  isNavigationElementType,
  onError,
}: UseTransitionPreviewOptions): UseTransitionPreviewResult {
  const [preview, setPreview] = useState<TransitionPreviewState | null>(null);
  const [pendingPageId, setPendingPageId] = useState('');

  const openPreview = useCallback(
    (element: TransitionElement, direction: 'forward' | 'back') => {
      if (!isNavigationElementType(element.type)) {
        return;
      }

      // Check if transition video is configured
      if (!element.transitionVideoUrl) {
        onError?.(
          'Select transition video asset to preview transition playback.',
        );
        return;
      }

      // Check for separate reverse video if needed
      if (
        direction === 'back' &&
        element.transitionReverseMode === 'separate_video' &&
        !element.reverseVideoUrl
      ) {
        onError?.(
          'Select back-transition asset or switch reverse mode to Auto Reverse.',
        );
        return;
      }

      const previewState: TransitionPreviewState = {
        videoUrl: element.transitionVideoUrl,
        storageKey: element.transitionVideoUrl, // Raw storage path for cache lookup
        reverseMode:
          direction === 'forward'
            ? 'none'
            : element.transitionReverseMode === 'separate_video'
              ? 'separate'
              : 'reverse',
        reverseVideoUrl: element.reverseVideoUrl,
        reverseStorageKey: element.reverseVideoUrl,
        durationSec: element.transitionDurationSec,
        title: `${element.navLabel || element.label || 'Transition'} · ${direction}`,
      };

      setPreview(previewState);
    },
    [isNavigationElementType, onError],
  );

  const openPreviewWithTarget = useCallback(
    (
      element: TransitionElement,
      direction: 'forward' | 'back',
      targetPageId: string,
    ) => {
      setPendingPageId(targetPageId);
      openPreview(element, direction);
    },
    [openPreview],
  );

  const closePreview = useCallback(() => {
    setPreview(null);
    setPendingPageId('');
  }, []);

  const isActive = useMemo(() => preview !== null, [preview]);

  return {
    preview,
    pendingPageId,
    openPreview,
    openPreviewWithTarget,
    closePreview,
    isActive,
  };
}

/**
 * Get navigation direction from element configuration.
 * Maps navType and element type to forward/back.
 */
export function getTransitionDirection(element: {
  type: string;
  navType?: 'forward' | 'back';
}): 'forward' | 'back' {
  if (element.navType === 'back') return 'back';
  if (element.navType === 'forward') return 'forward';

  // Infer from element type
  if (element.type === 'navigation_prev') return 'back';
  return 'forward';
}

export default useTransitionPreview;
