/**
 * VideoPlayer - Unified Video Player Component
 *
 * Supports multiple modes:
 * - vidstack: Full-featured player (YouTube, Vimeo, HLS, DASH)
 * - native: Lightweight HTML5 player
 * - streaming: HTTP Range streaming with auth / Blob sources
 *
 * @example
 * // YouTube video
 * <VideoPlayer source={{ type: 'youtube', id: 'dQw4w9WgXcQ' }} />
 *
 * @example
 * // HLS stream
 * <VideoPlayer source={{ type: 'hls', url: 'https://example.com/video.m3u8' }} />
 *
 * @example
 * // HTTP Range streaming with auth (full source)
 * <VideoPlayer
 *   source={{
 *     type: 'stream',
 *     sessionId: 'abc123',
 *     path: '/videos/movie.mp4',
 *     getStreamUrl: (id, path) => `/api/stream/${id}?path=${path}&token=${token}`
 *   }}
 * />
 *
 * @example
 * // HTTP Range streaming (simplified, using VideoPlayerProvider context)
 * <VideoPlayerProvider sessionId={sessionId} getStreamUrl={getStreamUrl}>
 *   <VideoPlayer source={{ type: 'stream', path: '/videos/movie.mp4' }} />
 * </VideoPlayerProvider>
 *
 * @example
 * // Blob/ArrayBuffer
 * <VideoPlayer source={{ type: 'blob', data: arrayBuffer, mimeType: 'video/mp4' }} />
 */

'use client';

import React, { forwardRef, useMemo } from 'react';

import { VidstackProvider, NativeProvider, StreamProvider } from '../providers';
import { useVideoPlayerContext } from '../context';
import { resolvePlayerMode, isSimpleStreamSource, resolveStreamSource } from '../utils';

import type { VideoPlayerProps, VideoPlayerRef, VideoSourceUnion, VidstackProviderProps, NativeProviderProps, StreamProviderProps, SimpleStreamSource } from '../types';

export const VideoPlayer = forwardRef<VideoPlayerRef, VideoPlayerProps & { source: VideoSourceUnion | SimpleStreamSource }>(
  (
    {
      source: rawSource,
      mode = 'auto',
      aspectRatio = 16 / 9,
      autoPlay = false,
      muted = false,
      loop = false,
      playsInline = true,
      controls = true,
      preload = 'metadata',
      theme = 'default',
      showInfo = false,
      className,
      videoClassName,
      disableContextMenu = false,
      showPreloader = true,
      preloaderTimeout = 5000,
      errorFallback,
      onPlay,
      onPause,
      onEnded,
      onError,
      onLoadStart,
      onCanPlay,
      onTimeUpdate,
    },
    ref
  ) => {
    // Get context for simplified stream sources
    const context = useVideoPlayerContext();

    // Resolve simplified stream source to full source using context
    const source = useMemo(() => {
      if (isSimpleStreamSource(rawSource)) {
        const resolved = resolveStreamSource(rawSource, context);
        if (!resolved) {
          // Return a special error source that will trigger error fallback
          return null;
        }
        return resolved;
      }
      return rawSource;
    }, [rawSource, context]);

    // Handle unresolved source
    if (!source) {
      // Render error state
      const errorMessage = 'Stream source requires VideoPlayerProvider with getStreamUrl and sessionId';

      if (typeof errorFallback === 'function') {
        return (
          <div className={className} style={{ aspectRatio: aspectRatio === 'fill' ? undefined : aspectRatio }}>
            {errorFallback({ error: errorMessage })}
          </div>
        );
      }

      if (errorFallback) {
        return (
          <div className={className} style={{ aspectRatio: aspectRatio === 'fill' ? undefined : aspectRatio }}>
            {errorFallback}
          </div>
        );
      }

      // Default error UI
      return (
        <div
          className={className}
          style={{
            aspectRatio: aspectRatio === 'fill' ? undefined : aspectRatio,
            display: 'flex',
            alignItems: 'center',
            justifyContent: 'center',
            backgroundColor: 'black',
            color: 'white',
          }}
        >
          <p>{errorMessage}</p>
        </div>
      );
    }

    // Determine which provider to use
    const resolvedMode = resolvePlayerMode(source, mode);

    // Common props for all providers
    const commonProps = {
      aspectRatio,
      autoPlay,
      muted,
      loop,
      playsInline,
      controls,
      preload,
      className,
      onPlay,
      onPause,
      onEnded,
      onError,
      onLoadStart,
      onCanPlay,
      onTimeUpdate,
    };

    // Render appropriate provider
    switch (resolvedMode) {
      case 'vidstack':
        return (
          <VidstackProvider
            ref={ref}
            source={source as VidstackProviderProps['source']}
            theme={theme}
            showInfo={showInfo}
            errorFallback={errorFallback}
            {...commonProps}
          />
        );

      case 'streaming':
        return (
          <StreamProvider
            ref={ref}
            source={source as StreamProviderProps['source']}
            videoClassName={videoClassName}
            disableContextMenu={disableContextMenu}
            showPreloader={showPreloader}
            preloaderTimeout={preloaderTimeout}
            errorFallback={errorFallback}
            {...commonProps}
          />
        );

      case 'native':
      default:
        return (
          <NativeProvider
            ref={ref}
            source={source as NativeProviderProps['source']}
            videoClassName={videoClassName}
            disableContextMenu={disableContextMenu}
            showPreloader={showPreloader}
            preloaderTimeout={preloaderTimeout}
            {...commonProps}
          />
        );
    }
  }
);

VideoPlayer.displayName = 'VideoPlayer';
