import { describe, it, expect, vi, beforeEach } from 'vitest';
import { render, screen, waitFor } from '@testing-library/react';
import { PlaybackSummary } from './PlaybackSummary';
import { getPlaybackSummary } from '../services/playbackAnalyticsService';

// Mock du service
vi.mock('../services/playbackAnalyticsService', () => ({
  getPlaybackSummary: vi.fn(),
}));

const mockGetPlaybackSummary = vi.mocked(getPlaybackSummary);

const mockSummary = {
  total_plays: 1234,
  completion_rate: 75.5,
  average_play_time: 245, // 4m 5s
};

describe('PlaybackSummary', () => {
  beforeEach(() => {
    vi.clearAllMocks();
    mockGetPlaybackSummary.mockResolvedValue(mockSummary);
  });

  it('should render loading state initially', () => {
    mockGetPlaybackSummary.mockReturnValue(new Promise(() => {})); // Never resolve
    render(<PlaybackSummary trackId={123} />);
    expect(screen.getByText('Résumé des Analytics')).toBeInTheDocument();
    expect(screen.getByRole('status')).toBeInTheDocument(); // LoadingSpinner has role="status"
  });

  it('should render summary data after successful fetch', async () => {
    render(<PlaybackSummary trackId={123} />);

    await waitFor(() => {
      expect(screen.getByText('Résumé des Analytics')).toBeInTheDocument();
    });

    // Vérifier les statistiques
    expect(screen.getByText('1 234')).toBeInTheDocument(); // total_plays formaté
    expect(screen.getByText('4m 5s')).toBeInTheDocument(); // average_play_time formaté
    expect(screen.getByText('75.5%')).toBeInTheDocument(); // completion_rate
  });

  it('should render error state', async () => {
    mockGetPlaybackSummary.mockRejectedValue(new Error('Failed to fetch'));
    render(<PlaybackSummary trackId={123} />);

    await waitFor(() => {
      expect(screen.getByText('Failed to fetch')).toBeInTheDocument();
    });
  });

  it('should render no data message if summary is null', async () => {
    mockGetPlaybackSummary.mockResolvedValue(null as any);
    render(<PlaybackSummary trackId={123} />);

    await waitFor(() => {
      expect(
        screen.getByText('Aucune donnée de lecture disponible pour ce track.'),
      ).toBeInTheDocument();
    });
  });

  it('should re-fetch data when trackId changes', async () => {
    const { rerender } = render(<PlaybackSummary trackId={123} />);
    await waitFor(() =>
      expect(mockGetPlaybackSummary).toHaveBeenCalledWith(123),
    );

    rerender(<PlaybackSummary trackId={456} />);
    await waitFor(() =>
      expect(mockGetPlaybackSummary).toHaveBeenCalledWith(456),
    );
    expect(mockGetPlaybackSummary).toHaveBeenCalledTimes(2);
  });

  it('should format time correctly for seconds', async () => {
    mockGetPlaybackSummary.mockResolvedValue({
      ...mockSummary,
      average_play_time: 45,
    });
    render(<PlaybackSummary trackId={123} />);
    await waitFor(() => {
      expect(screen.getByText('45s')).toBeInTheDocument();
    });
  });

  it('should format time correctly for minutes', async () => {
    mockGetPlaybackSummary.mockResolvedValue({
      ...mockSummary,
      average_play_time: 125, // 2m 5s
    });
    render(<PlaybackSummary trackId={123} />);
    await waitFor(() => {
      expect(screen.getByText('2m 5s')).toBeInTheDocument();
    });
  });

  it('should format time correctly for hours', async () => {
    mockGetPlaybackSummary.mockResolvedValue({
      ...mockSummary,
      average_play_time: 3665, // 1h 1min 5s = 1h 1min
    });
    render(<PlaybackSummary trackId={123} />);
    await waitFor(() => {
      expect(screen.getByText('1h 1min')).toBeInTheDocument();
    });
  });

  it('should format numbers with thousand separators', async () => {
    mockGetPlaybackSummary.mockResolvedValue({
      ...mockSummary,
      total_plays: 1234567,
    });
    render(<PlaybackSummary trackId={123} />);
    await waitFor(() => {
      expect(screen.getByText('1 234 567')).toBeInTheDocument();
    });
  });

  it('should display all three statistics cards', async () => {
    render(<PlaybackSummary trackId={123} />);

    await waitFor(() => {
      expect(screen.getByText('Lectures totales')).toBeInTheDocument();
      expect(screen.getByText('Temps de lecture moyen')).toBeInTheDocument();
      expect(screen.getByText('Taux de complétion')).toBeInTheDocument();
    });
  });

  it('should apply custom className', async () => {
    const { container } = render(
      <PlaybackSummary trackId={123} className="custom-class" />,
    );
    await waitFor(() => {
      expect(container.firstChild).toHaveClass('custom-class');
    });
  });

  it('should handle zero values', async () => {
    mockGetPlaybackSummary.mockResolvedValue({
      total_plays: 0,
      completion_rate: 0,
      average_play_time: 0,
    });
    render(<PlaybackSummary trackId={123} />);
    await waitFor(() => {
      expect(screen.getByText('0')).toBeInTheDocument();
      expect(screen.getByText('0.0%')).toBeInTheDocument();
      expect(screen.getByText('0s')).toBeInTheDocument();
    });
  });
});
