import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';
import { render, screen, fireEvent } from '@testing-library/react';
import { AudioPlayer } from './audio-player';

// Mock the Slider component
// We mock it to expose its props (value, onValueChange) for easier testing
interface SliderMockProps {
  value: number[];
  onValueChange: (v: number[]) => void;
  className?: string;
  [key: string]: unknown;
}
vi.mock('@/components/ui/slider', () => ({
  Slider: ({ value, onValueChange, className, ...props }: SliderMockProps) => (
    <input 
      type="range"
      data-testid="mock-slider"
      value={value[0]} 
      onChange={(e) => onValueChange([parseFloat(e.target.value)])}
      className={className}
      {...props}
    />
  )
}));

describe('AudioPlayer', () => {
  const originalPlay = window.HTMLMediaElement.prototype.play;
  const originalPause = window.HTMLMediaElement.prototype.pause;

  beforeEach(() => {
    window.HTMLMediaElement.prototype.play = vi.fn().mockResolvedValue(undefined);
    window.HTMLMediaElement.prototype.pause = vi.fn();
  });

  afterEach(() => {
    window.HTMLMediaElement.prototype.play = originalPlay;
    window.HTMLMediaElement.prototype.pause = originalPause;
    vi.clearAllMocks();
  });

  it('renders correctly with given src', () => {
    render(<AudioPlayer src="/test-audio.wav" />);
    
    // Check for Play button
    expect(screen.getByRole('button', { name: /play/i })).toBeInTheDocument();
    
    // Check if audio element exists with correct src
    const audioEl = document.querySelector('audio');
    expect(audioEl).toBeInTheDocument();
    expect(audioEl).toHaveAttribute('src', '/test-audio.wav');
  });

  it('toggles play and pause', () => {
    render(<AudioPlayer src="/test-audio.wav" />);
    
    const playButton = screen.getByRole('button', { name: /play/i });

    // Click Play
    fireEvent.click(playButton);
    expect(window.HTMLMediaElement.prototype.play).toHaveBeenCalled();
    expect(screen.getByRole('button', { name: /pause/i })).toBeInTheDocument();

    // Click Pause
    const pauseButton = screen.getByRole('button', { name: /pause/i });
    fireEvent.click(pauseButton);
    expect(window.HTMLMediaElement.prototype.pause).toHaveBeenCalled();
    expect(screen.getByRole('button', { name: /play/i })).toBeInTheDocument();
  });

  it('handles volume changes', () => {
    render(<AudioPlayer src="/test-audio.wav" />);
    const audioEl = document.querySelector('audio');
    expect(audioEl?.volume).toBe(1);

    const volumeSlider = screen.getByLabelText('Volume');

    if (volumeSlider) {
      fireEvent.change(volumeSlider, { target: { value: 0.5 } });
      expect(audioEl?.volume).toBe(0.5);
    }
  });

  it('toggles mute', () => {
    render(<AudioPlayer src="/test-audio.wav" />);
    const audioEl = document.querySelector('audio');
    
    const muteButton = screen.getByRole('button', { name: /mute/i });

    fireEvent.click(muteButton);
    expect(audioEl?.muted).toBe(true);
    expect(screen.getByRole('button', { name: /unmute/i })).toBeInTheDocument();

    const unmuteButton = screen.getByRole('button', { name: /unmute/i });
    fireEvent.click(unmuteButton);
    expect(audioEl?.muted).toBe(false);
  });
});