import {
  useEffect,
  useRef,
  useState,
  type CSSProperties,
  type ReactNode,
} from 'react';

export interface VideoChapter {
  /** Stable id — React key. */
  id: string;
  /** Display label. */
  label: string;
  /** Chapter start time in seconds. */
  startSeconds: number;
}

export interface VideoCaption {
  /** Stable id. */
  id: string;
  /** Caption start in seconds. */
  start: number;
  /** Caption end in seconds. */
  end: number;
  /** Display text. */
  text: string;
}

export interface VideoPlayerProps {
  /** Video source URL. */
  src: string;
  /** Optional poster image. */
  poster?: string;
  /** Optional chapter list — rendered as buttons under the player. */
  chapters?: VideoChapter[];
  /**
   * Optional in-memory caption track. When provided, the active line is
   * rendered as an aria-live caption strip below the video.
   * Hosts that prefer real <track> elements can pass `captionsTrackUrl`
   * instead via the `slot` prop and skip this list.
   */
  captions?: VideoCaption[];
  /** Slot rendered above the chapter list — e.g. native <track>. */
  slot?: ReactNode;
  width?: number;
  height?: number;
  ariaLabel?: string;
  className?: string;
  style?: CSSProperties;
}

/**
 * `<VideoPlayer>` — minimal token-themed video wrapper with chapter
 * navigation + optional caption rail.
 *
 * Wave 13.G.4. Uses the native `<video controls>` element; chapters
 * are rendered as discrete "seek-to" buttons. Captions are passed in
 * pure JS for the simple case — hosts wanting WebVTT pass a `<track>`
 * via the `slot` prop.
 */
export function VideoPlayer({
  src,
  poster,
  chapters,
  captions,
  slot,
  width = 480,
  height = 270,
  ariaLabel,
  className,
  style,
}: VideoPlayerProps) {
  const ref = useRef<HTMLVideoElement>(null);
  const [activeCaption, setActiveCaption] = useState<VideoCaption | null>(null);

  // Tick the active caption as the video plays.
  useEffect(() => {
    if (!captions || captions.length === 0) return;
    const el = ref.current;
    if (!el) return;
    const onTime = () => {
      const t = el.currentTime;
      const hit = captions.find((c) => t >= c.start && t < c.end);
      setActiveCaption(hit ?? null);
    };
    el.addEventListener('timeupdate', onTime);
    return () => el.removeEventListener('timeupdate', onTime);
  }, [captions]);

  const seek = (s: number) => {
    const el = ref.current;
    if (!el) return;
    el.currentTime = s;
    void el.play().catch(() => {});
  };

  return (
    <div
      data-testid="bl-video-player"
      className={className}
      style={{
        display: 'inline-flex',
        flexDirection: 'column',
        gap: 8,
        ...style,
      }}
    >
      <video
        ref={ref}
        src={src}
        poster={poster}
        controls
        width={width}
        height={height}
        aria-label={ariaLabel}
        data-testid="bl-video-player-video"
        style={{
          width,
          height,
          borderRadius: 12,
          background: 'var(--bl-surface-muted, #000)',
        }}
      >
        {slot}
        Your browser does not support the video element.
      </video>
      {captions && captions.length > 0 && (
        <div
          aria-live="polite"
          data-testid="bl-video-player-caption"
          style={{
            minHeight: 22,
            padding: '4px 8px',
            borderRadius: 8,
            background: 'var(--bl-surface-muted, rgba(0,0,0,0.05))',
            fontSize: 13,
            color: 'var(--bl-text-secondary, #555)',
            textAlign: 'center',
            fontFamily: 'ui-sans-serif, system-ui, sans-serif',
          }}
        >
          {activeCaption?.text ?? ''}
        </div>
      )}
      {chapters && chapters.length > 0 && (
        <nav
          aria-label="Chapters"
          data-testid="bl-video-player-chapters"
          style={{
            display: 'flex',
            flexWrap: 'wrap',
            gap: 6,
            fontFamily: 'ui-sans-serif, system-ui, sans-serif',
          }}
        >
          {chapters.map((c) => (
            <button
              key={c.id}
              type="button"
              onClick={() => seek(c.startSeconds)}
              data-testid="bl-video-player-chapter"
              data-chapter-id={c.id}
              style={{
                padding: '4px 10px',
                fontSize: 12,
                fontWeight: 500,
                borderRadius: 999,
                border: '1px solid var(--bl-border, rgba(0,0,0,0.12))',
                background: 'var(--bl-surface-card, #fff)',
                color: 'var(--bl-text-secondary, #555)',
                cursor: 'pointer',
              }}
            >
              <span style={{ opacity: 0.6 }}>{formatTime(c.startSeconds)}</span>{' '}
              {c.label}
            </button>
          ))}
        </nav>
      )}
    </div>
  );
}

function formatTime(s: number): string {
  if (!Number.isFinite(s) || s < 0) return '0:00';
  const mm = Math.floor(s / 60);
  const ss = Math.floor(s % 60);
  return `${mm}:${ss.toString().padStart(2, '0')}`;
}
