/**
 * Navigation Helpers
 *
 * Shared utilities for page navigation in RuntimePresentation and constructor.tsx.
 * Handles target page resolution, back navigation detection, and transition blocking.
 */

import type { RuntimePage } from '../types/runtime';
import type {
  NavigableElement,
  NavigationTarget,
  TransitionPhase,
} from '../types/presentation';

/**
 * Resolve target page from element navigation properties.
 * Supports both targetPageSlug (new) and targetPageId (legacy).
 *
 * @param element - Element with navigation properties
 * @param pages - Available pages to search
 * @returns The target page or undefined if not found
 */
export const resolveNavigationTarget = (
  element: NavigableElement,
  pages: RuntimePage[],
): NavigationTarget | null => {
  const targetPageSlug = element.targetPageSlug;
  const legacyTargetPageId = element.targetPageId;

  let targetPage: RuntimePage | undefined;

  if (targetPageSlug) {
    targetPage = pages.find((p) => p.slug === targetPageSlug);
  } else if (legacyTargetPageId) {
    targetPage = pages.find((p) => p.id === legacyTargetPageId);
  }

  if (!targetPage) {
    return null;
  }

  const isBack = isBackNavigation(element);

  return {
    page: targetPage,
    pageId: targetPage.id,
    transitionVideoUrl: element.transitionVideoUrl,
    isBack,
  };
};

/**
 * Determine if navigation direction is "back".
 * Elements with navType='back' or type='navigation_prev' navigate backwards.
 *
 * @param element - Element to check
 * @returns true if this is a back navigation
 */
export const isBackNavigation = (element: NavigableElement): boolean => {
  return element.navType === 'back' || element.type === 'navigation_prev';
};

/**
 * Get navigation direction based on element properties.
 *
 * @param element - Element with navigation properties
 * @returns 'back' or 'forward'
 */
export const getNavigationDirection = (
  element: NavigableElement,
): 'back' | 'forward' => {
  return isBackNavigation(element) ? 'back' : 'forward';
};

/**
 * Check if transition is actively blocking navigation.
 * Navigation should be blocked during preparing, playing, or reversing phases.
 *
 * @param transitionPhase - Current transition phase
 * @param isBuffering - Whether video is buffering
 * @returns true if navigation should be blocked
 */
export const isTransitionBlocking = (
  transitionPhase: TransitionPhase,
  isBuffering: boolean,
): boolean => {
  const activePhases: TransitionPhase[] = ['preparing', 'playing', 'reversing'];
  return activePhases.includes(transitionPhase) || isBuffering;
};

/**
 * Check if element has a playable transition.
 * A transition is playable if it has a video URL, and for back navigation,
 * either supports reverse or has a separate reverse video.
 *
 * @param element - Element with transition properties
 * @param direction - Navigation direction
 * @returns true if element has a playable transition
 */
export const hasPlayableTransition = (
  element: {
    transitionVideoUrl?: string;
    transitionReverseMode?: string;
    reverseVideoUrl?: string;
  },
  direction: 'back' | 'forward' = 'forward',
): boolean => {
  if (!element.transitionVideoUrl) {
    return false;
  }

  // For back navigation with separate_video mode, need reverse video
  if (
    direction === 'back' &&
    element.transitionReverseMode === 'separate_video' &&
    !element.reverseVideoUrl
  ) {
    return false;
  }

  return true;
};

/**
 * Check if element is a navigation element type.
 *
 * @param elementType - Element type to check
 * @returns true if element is a navigation type
 */
export const isNavigationType = (elementType: string): boolean => {
  return (
    elementType === 'navigation_next' ||
    elementType === 'navigation_prev' ||
    elementType === 'navigation'
  );
};
