import { describe, it, expect, vi } from 'vitest';
import { render, waitFor } from '@testing-library/react';
import { VideoPlayer } from './VideoPlayer';

describe('VideoPlayer', () => {
  const defaultProps = {
    src: 'https://example.com/video.mp4',
  };

  it('renders video player container', () => {
    const { container } = render(<VideoPlayer {...defaultProps} />);
    expect(container.querySelector('.video-player')).toBeInTheDocument();
  });

  it('renders video element', () => {
    const { container } = render(<VideoPlayer {...defaultProps} />);
    const video = container.querySelector('video');
    expect(video).toBeInTheDocument();
  });

  it('renders with autoplay prop', () => {
    const { container } = render(<VideoPlayer {...defaultProps} autoplay />);
    const video = container.querySelector('video');
    // VideoElement handles autoplay programmatically via play() method
    expect(video).toBeInTheDocument();
  });

  it('renders with muted prop', () => {
    const { container } = render(<VideoPlayer {...defaultProps} muted />);
    const video = container.querySelector('video');
    // Muted state is managed through VideoElement
    expect(video).toBeInTheDocument();
  });

  it('applies loop when enabled', () => {
    const { container } = render(<VideoPlayer {...defaultProps} loop />);
    const video = container.querySelector('video');
    expect(video).toHaveAttribute('loop');
  });

  it('applies custom className', () => {
    const className = 'custom-player';
    const { container } = render(<VideoPlayer {...defaultProps} className={className} />);
    expect(container.querySelector('.video-player')).toHaveClass('video-player', className);
  });

  it('calls onPlay callback when play event fires', async () => {
    const onPlay = vi.fn();
    const { container } = render(<VideoPlayer {...defaultProps} onPlay={onPlay} />);

    const video = container.querySelector('video') as HTMLVideoElement;
    video.dispatchEvent(new Event('play'));

    await waitFor(() => {
      expect(onPlay).toHaveBeenCalled();
    });
  });

  it('calls onPause callback when pause event fires', async () => {
    const onPause = vi.fn();
    const { container } = render(<VideoPlayer {...defaultProps} onPause={onPause} />);

    const video = container.querySelector('video') as HTMLVideoElement;
    video.dispatchEvent(new Event('pause'));

    await waitFor(() => {
      expect(onPause).toHaveBeenCalled();
    });
  });

  it('calls onEnded callback when ended event fires', async () => {
    const onEnded = vi.fn();
    const { container } = render(<VideoPlayer {...defaultProps} onEnded={onEnded} />);

    const video = container.querySelector('video') as HTMLVideoElement;
    video.dispatchEvent(new Event('ended'));

    await waitFor(() => {
      expect(onEnded).toHaveBeenCalled();
    });
  });

  it('calls onTimeUpdate callback with current time', async () => {
    const onTimeUpdate = vi.fn();
    const { container } = render(<VideoPlayer {...defaultProps} onTimeUpdate={onTimeUpdate} />);

    const video = container.querySelector('video') as HTMLVideoElement;
    Object.defineProperty(video, 'currentTime', { value: 10.5, configurable: true });
    video.dispatchEvent(new Event('timeupdate'));

    await waitFor(() => {
      expect(onTimeUpdate).toHaveBeenCalledWith(10.5);
    });
  });

  it('renders with subtitles prop', () => {
    const subtitles = [
      { src: 'subtitles-en.vtt', srcLang: 'en', label: 'English' },
      { src: 'subtitles-tr.vtt', srcLang: 'tr', label: 'Türkçe' },
    ];
    const { container } = render(<VideoPlayer {...defaultProps} subtitles={subtitles} />);

    const video = container.querySelector('video') as HTMLVideoElement;
    // Subtitles are added dynamically by VideoElement
    expect(video).toBeInTheDocument();
  });

  it('renders without errors', () => {
    const onError = vi.fn();
    const { container } = render(<VideoPlayer {...defaultProps} onError={onError} />);

    const video = container.querySelector('video') as HTMLVideoElement;
    expect(video).toBeInTheDocument();
    // Error handling is tested separately in integration tests
  });

  it('hides controls when controls prop is false', () => {
    const { container } = render(<VideoPlayer {...defaultProps} controls={false} />);
    const controls = container.querySelector('.controls');
    expect(controls).not.toBeInTheDocument();
  });

  it('applies custom style', () => {
    const style = { width: '800px', height: '450px' };
    const { container } = render(<VideoPlayer {...defaultProps} style={style} />);
    const playerElement = container.querySelector('.video-player') as HTMLElement;
    expect(playerElement.style.width).toBe('800px');
    expect(playerElement.style.height).toBe('450px');
  });
});
