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

describe('WaveformVisualizer Component', () => {
  const mockOnSeek = vi.fn();

  beforeEach(() => {
    vi.clearAllMocks();
  });

  it('renders canvas', () => {
    render(<WaveformVisualizer progress={50} onSeek={mockOnSeek} />);

    const canvas = screen.getByRole('img', { hidden: true });
    expect(canvas).toBeInTheDocument();
  });

  it('calls onSeek when canvas is clicked', () => {
    render(<WaveformVisualizer progress={50} onSeek={mockOnSeek} />);

    const canvas = screen.getByRole('img', { hidden: true });

    // Mock getBoundingClientRect
    const mockRect = {
      left: 0,
      top: 0,
      width: 100,
      height: 64,
    };
    canvas.getBoundingClientRect = vi.fn(() => mockRect as DOMRect);

    fireEvent.click(canvas, { clientX: 50 });

    expect(mockOnSeek).toHaveBeenCalled();
  });

  it('uses waveformData when provided', () => {
    const waveformData = [0.5, 0.7, 0.3, 0.9];

    render(
      <WaveformVisualizer
        waveformData={waveformData}
        progress={50}
        onSeek={mockOnSeek}
      />,
    );

    const canvas = screen.getByRole('img', { hidden: true });
    expect(canvas).toBeInTheDocument();
  });

  it('generates mock data when waveformData is not provided', () => {
    render(<WaveformVisualizer progress={50} onSeek={mockOnSeek} />);

    const canvas = screen.getByRole('img', { hidden: true });
    expect(canvas).toBeInTheDocument();
  });

  it('applies custom height', () => {
    render(
      <WaveformVisualizer progress={50} onSeek={mockOnSeek} height={100} />,
    );

    const canvas = screen.getByRole('img', { hidden: true });
    expect(canvas).toHaveStyle({ height: '100px' });
  });

  it('clamps seek percentage between 0 and 100', () => {
    render(<WaveformVisualizer progress={50} onSeek={mockOnSeek} />);

    const canvas = screen.getByRole('img', { hidden: true });
    const mockRect = {
      left: 0,
      top: 0,
      width: 100,
      height: 64,
    };
    canvas.getBoundingClientRect = vi.fn(() => mockRect as DOMRect);

    // Click outside bounds (negative)
    fireEvent.click(canvas, { clientX: -10 });
    expect(mockOnSeek).toHaveBeenCalledWith(0);

    // Click outside bounds (too large)
    fireEvent.click(canvas, { clientX: 200 });
    expect(mockOnSeek).toHaveBeenCalledWith(100);
  });
});
