'use client';

/**
 * VideoPlayer — composable shell over `media-chrome` web components.
 *
 * The shell is just a `<MediaController>` wrapper + a `<CanvasDispatcher>`
 * that mounts the right media element (`<video>`, `<youtube-video>`,
 * `<vimeo-video>`, `<hls-video>`, `<iframe>`) into the `media` slot.
 *
 * Custom layouts: pass `children` to replace the default control bar.
 * `controls={false}` opts out of any control surface (useful for
 * iframe sources where the embed renders its own UI).
 */

import { useCallback, useEffect, useMemo, useRef, type CSSProperties } from 'react';
import { MediaController } from 'media-chrome/react';
import { cn } from '@djangocfg/ui-core/lib';
import './styles/video-player.css';

import type { VideoPlayerProps, AspectRatioValue } from './types';
import { parseEmbedUrl } from './utils/parse-embed-url';
import { CanvasDispatcher } from './canvas/canvas-dispatcher';
import {
  ControlsBar,
  PlayButton,
  SeekBar,
  Volume,
  PlaybackRate,
  Pip,
  Fullscreen,
} from './parts';

function aspectRatioStyle(ar: AspectRatioValue): CSSProperties | undefined {
  if (ar === 'fill') return { height: '100%' };
  if (ar === 'auto') return undefined;
  return { aspectRatio: String(ar) };
}

export function VideoPlayer({
  source,
  controls = true,
  aspectRatio = 16 / 9,
  className,
  children,
  autoFocus = false,
  ...settings
}: VideoPlayerProps) {
  const normalized = useMemo(
    () => (typeof source === 'string' ? parseEmbedUrl(source) : source),
    [source],
  );

  const isIframe = normalized.type === 'iframe';
  const isYouTube = normalized.type === 'youtube';
  // For iframe embeds media-chrome cannot drive the inner player — hide the
  // control bar to avoid a non-functional UI.
  const showControls = controls && !isIframe;

  // MediaController is a custom element; without `tabindex` it cannot take
  // focus, so its built-in keyboard shortcuts (space/arrows/f) never fire.
  // We type the ref through the element interface (HTMLElement methods are
  // all we use) — media-chrome's full MediaController type pulls private
  // fields we don't need to see.
  const controllerRef = useRef<HTMLElement | null>(null);

  // Click-to-play overlay for YouTube — the underlying YT iframe is made
  // `pointer-events: none` via CSS to suppress YouTube's own hover-state /
  // UI (title bar, pause-screen, branding tray; ToS forbids hiding them,
  // but we can make them inert). This overlay restores click-to-toggle
  // by dispatching media-chrome request events the controller listens for.
  const onYouTubeShieldClick = useCallback(() => {
    const el = controllerRef.current;
    if (!el) return;
    const paused = el.hasAttribute('mediapaused');
    const eventName = paused ? 'mediaplayrequest' : 'mediapauserequest';
    el.dispatchEvent(new CustomEvent(eventName, { bubbles: true, composed: true }));
  }, []);

  useEffect(() => {
    if (!autoFocus) return;
    const el = controllerRef.current;
    if (!el) return;
    if (!el.hasAttribute('tabindex')) el.setAttribute('tabindex', '0');
    el.focus({ preventScroll: true });
  }, [autoFocus]);

  return (
    <MediaController
      ref={(el) => {
        controllerRef.current = el as unknown as HTMLElement | null;
      }}
      // Fade controls + scrim after 2.5s of inactivity while playing;
      // they reappear on mousemove / pause / focus (media-chrome built-in).
      autohide="2.5"
      className={cn(
        'video-player relative block w-full overflow-hidden rounded-lg bg-black',
        'focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring/50',
        className,
      )}
      style={aspectRatioStyle(aspectRatio)}
    >
      <CanvasDispatcher source={normalized} {...settings} />
      {isYouTube && (
        // Transparent click-shield over the YT iframe. The iframe itself
        // is pointer-events:none (see video-player.css); this div absorbs
        // pointer events and forwards a play/pause request to media-chrome,
        // so users still get click-to-toggle without ever interacting with
        // YouTube's own UI.
        <div
          className="vp-yt-click-shield"
          onClick={onYouTubeShieldClick}
          aria-hidden="true"
        />
      )}
      {children ??
        (showControls && (
          <ControlsBar>
            <PlayButton />
            <SeekBar />
            <Volume iconOnly />
            <PlaybackRate />
            <Pip />
            <Fullscreen />
          </ControlsBar>
        ))}
    </MediaController>
  );
}
