import { render, screen, waitFor } from '@testing-library/react';
import { describe, it, expect, vi, beforeEach } from 'vitest';
import { BrowserRouter } from 'react-router-dom';
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
import { DashboardPage } from './DashboardPage';

// Mock useAuthStore
const mockUser = {
  id: '1',
  username: 'testuser',
  email: 'test@example.com',
  first_name: 'Test',
};

vi.mock('@/stores/auth', () => ({
  useAuthStore: () => ({
    user: mockUser,
    isAuthenticated: true,
  }),
}));

// Mock useLibraryStore
const mockItems = [
  { id: '1', title: 'Track 1', description: 'Description 1' },
  { id: '2', title: 'Track 2', description: 'Description 2' },
  { id: '3', title: 'Track 3', description: 'Description 3' },
];

const mockFetchItems = vi.fn();

vi.mock('@/stores/library', () => ({
  useLibraryStore: () => ({
    items: mockItems,
    fetchItems: mockFetchItems,
    isLoading: false,
  }),
}));

const createTestQueryClient = () =>
  new QueryClient({
    defaultOptions: {
      queries: { retry: false },
      mutations: { retry: false },
    },
  });

const TestWrapper = ({ children }: { children: React.ReactNode }) => {
  const queryClient = createTestQueryClient();
  return (
    <QueryClientProvider client={queryClient}>
      <BrowserRouter>{children}</BrowserRouter>
    </QueryClientProvider>
  );
};

describe('DashboardPage Component', () => {
  beforeEach(() => {
    vi.clearAllMocks();
  });

  it('renders dashboard page correctly', () => {
    render(
      <TestWrapper>
        <DashboardPage />
      </TestWrapper>,
    );

    expect(screen.getByText('Dashboard')).toBeInTheDocument();
  });

  it('displays greeting with user name', () => {
    render(
      <TestWrapper>
        <DashboardPage />
      </TestWrapper>,
    );

    expect(screen.getByText(/Bonjour, Test !/i)).toBeInTheDocument();
  });

  it('displays statistics cards', () => {
    render(
      <TestWrapper>
        <DashboardPage />
      </TestWrapper>,
    );

    expect(screen.getByText('Pistes écoutées')).toBeInTheDocument();
    expect(screen.getByText('Messages envoyés')).toBeInTheDocument();
    expect(screen.getByText('Favoris')).toBeInTheDocument();
    expect(screen.getByText('Amis actifs')).toBeInTheDocument();
  });

  it('displays statistics values', () => {
    render(
      <TestWrapper>
        <DashboardPage />
      </TestWrapper>,
    );

    expect(screen.getByText('1,234')).toBeInTheDocument();
    expect(screen.getByText('567')).toBeInTheDocument();
    expect(screen.getByText('89')).toBeInTheDocument();
    expect(screen.getByText('45')).toBeInTheDocument();
  });

  it('displays recent activity section', () => {
    render(
      <TestWrapper>
        <DashboardPage />
      </TestWrapper>,
    );

    expect(screen.getByText('Activité récente')).toBeInTheDocument();
    expect(screen.getByText('Nouvelle piste ajoutée')).toBeInTheDocument();
    expect(screen.getByText('Message reçu de @alice')).toBeInTheDocument();
    expect(screen.getByText('Nouveau favori ajouté')).toBeInTheDocument();
  });

  it('displays recent tracks section', () => {
    render(
      <TestWrapper>
        <DashboardPage />
      </TestWrapper>,
    );

    expect(screen.getByText('Pistes récentes')).toBeInTheDocument();
    expect(screen.getByText('Track 1')).toBeInTheDocument();
    expect(screen.getByText('Track 2')).toBeInTheDocument();
    expect(screen.getByText('Track 3')).toBeInTheDocument();
  });

  it('calls fetchItems on mount', async () => {
    render(
      <TestWrapper>
        <DashboardPage />
      </TestWrapper>,
    );

    await waitFor(() => {
      expect(mockFetchItems).toHaveBeenCalledWith({ limit: 5 });
    });
  });

  it('renders page with correct structure', () => {
    render(
      <TestWrapper>
        <DashboardPage />
      </TestWrapper>,
    );

    // Vérifier que la page a la structure correcte avec padding
    const pageContent = screen.getByText('Dashboard').closest('.p-6');
    expect(pageContent).toBeInTheDocument();
  });

  it('displays statistics with correct format', () => {
    render(
      <TestWrapper>
        <DashboardPage />
      </TestWrapper>,
    );

    // Vérifier que les statistiques sont affichées avec leurs valeurs
    expect(screen.getByText('1,234')).toBeInTheDocument();
    expect(screen.getByText('567')).toBeInTheDocument();
  });
});
