// src/components/AchievementsList.test.tsx
import React from 'react';
import { screen } from '@testing-library/react';
import { describe, it, expect } from 'vitest';
import { AchievementsList } from './AchievementsList';
import { createMockUserAchievement } from '../tests/utils/mockFactories';
import { renderWithProviders } from '../tests/utils/renderWithProviders';

describe('AchievementsList', () => {
  it('should render the list of achievements with correct details', () => {
    const mockAchievements = [
      createMockUserAchievement({
        achievement_id: 1,
        name: 'Recipe Creator',
        description: 'Create your first recipe.',
        icon: 'chef-hat',
        points_value: 25,
      }),
      createMockUserAchievement({
        achievement_id: 2,
        name: 'List Maker',
        icon: 'list',
        points_value: 15,
      }),
      createMockUserAchievement({ achievement_id: 3, name: 'Unknown Achievement', icon: 'star' }), // This icon is not in the component's map
      createMockUserAchievement({ achievement_id: 4, name: 'No Icon Achievement', icon: '' }), // Triggers the fallback for missing name
    ];

    renderWithProviders(<AchievementsList achievements={mockAchievements} />);

    expect(screen.getByRole('heading', { name: /achievements/i })).toBeInTheDocument();

    // Check first achievement
    expect(screen.getByText('Recipe Creator')).toBeInTheDocument();
    expect(screen.getByText('Create your first recipe.')).toBeInTheDocument();
    expect(screen.getByText('+25 Points')).toBeInTheDocument();
    expect(screen.getByText('🧑‍🍳')).toBeInTheDocument(); // Icon for 'chef-hat'

    // Check second achievement
    expect(screen.getByText('List Maker')).toBeInTheDocument();
    expect(screen.getByText('📋')).toBeInTheDocument(); // Icon for 'list'

    // Check achievement with default icon
    expect(screen.getByText('Unknown Achievement')).toBeInTheDocument();
    // We expect at least one trophy (for unknown achievement).
    // Since we added another one that produces a trophy (No Icon), we use getAllByText.
    expect(screen.getAllByText('🏆').length).toBeGreaterThan(0);

    // Check achievement with missing icon (empty string)
    expect(screen.getByText('No Icon Achievement')).toBeInTheDocument();
    // Verify the specific placeholder class is rendered, ensuring the early return in Icon component is hit
    const noIconCard = screen.getByText('No Icon Achievement').closest('.bg-white');
    expect(noIconCard?.querySelector('.icon-placeholder')).toBeInTheDocument();
  });

  it('should render a message when there are no achievements', () => {
    renderWithProviders(<AchievementsList achievements={[]} />);
    expect(
      screen.getByText('No achievements earned yet. Keep exploring to unlock them!'),
    ).toBeInTheDocument();
  });
});
