import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';
import { render, screen, fireEvent, act } from '@testing-library/react';
import { GenerationCard } from './generation-card';
import type { GenerationResponse } from '@/lib/api';

// Mock dependencies
vi.mock('@/hooks/use-websocket', () => ({
  useGenerationWebSocket: () => ({ lastMessage: null })
}));

interface SliderMockProps {
  value: number[];
  onValueChange: (v: number[]) => void;
  className?: string;
}

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}
    />
  )
}));

// Mock Audio element
const mockPlay = vi.fn().mockResolvedValue(undefined);
const mockPause = vi.fn();

describe('User Story Verification: Playback Control', () => {
  const originalPlay = window.HTMLMediaElement.prototype.play;
  const originalPause = window.HTMLMediaElement.prototype.pause;

  beforeEach(() => {
    window.HTMLMediaElement.prototype.play = mockPlay;
    window.HTMLMediaElement.prototype.pause = mockPause;
  });

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

  const mockGeneration: GenerationResponse = {
    id: 'test-gen-123',
    status: 'completed',
    prompt: 'A test track',
    audio_path: '/music/test.wav',
    created_at: new Date().toISOString(),
    metadata: {
      prompt: 'A test track',
      analysis: {
        style: 'lo-fi',
        tempo: 90,
        mood: 'chill'
      }
    }
  };

  it('Scenario: User initiates playback and updates UI', async () => {
    render(<GenerationCard generation={mockGeneration} />);

    // 1. Validate Initial State
    // "play" button should be visible
    const playButton = screen.getByLabelText('Play');
    expect(playButton).toBeInTheDocument();
    // "pause" button should NOT be visible
    expect(screen.queryByLabelText('Pause')).not.toBeInTheDocument();
    
    // Card should NOT have the highlight class (checking specifically for the ring-primary class)
    const card = screen.getByText('A test track').closest('.bg-card');
    expect(card).not.toHaveClass('ring-primary');

    // 2. Action: Press "play" button
    await act(async () => {
      fireEvent.click(playButton);
    });

    // 3. Verify Functionality: Initiate playback
    expect(mockPlay).toHaveBeenCalledTimes(1);

    // 4. Validate UI Rendering: Update to reflect playing state
    // "pause" button SHOULD be visible/enabled
    const pauseButton = screen.getByLabelText('Pause');
    expect(pauseButton).toBeInTheDocument();
    // "play" button should NOT be visible
    expect(screen.queryByLabelText('Play')).not.toBeInTheDocument();

    // 5. Validate UI Rendering: Visual Highlight
    // Card SHOULD have the highlight class
    expect(card).toHaveClass('ring-primary');
    expect(card).toHaveClass('border-primary');
    expect(card).toHaveClass('shadow-[0_0_15px_rgba(var(--primary),0.2)]');

    // 6. Action: Press "pause" button
    await act(async () => {
      fireEvent.click(pauseButton);
    });

    // 7. Verify Functionality: Pause playback
    expect(mockPause).toHaveBeenCalledTimes(1);

    // 8. Validate UI Rendering: Return to paused state
    expect(screen.getByLabelText('Play')).toBeInTheDocument();
    expect(card).not.toHaveClass('ring-primary');
  });
});
