import React from 'react';
import { screen, render, cleanup } from '@testing-library/react';

import { Icon, iconSources } from './Icon';

// before each test, clear the rendered icon
beforeEach(() => {
  cleanup();
});

describe('Icon', () => {
  // Icon should render a default icon when no icon is provided
  it('should render a default icon when no icon is provided', async () => {
    render(<Icon isDecorative={false} />);

    // Expect that there is an svg on the page with the title "generic file icon" (the default icon)
    expect(screen.getByTitle('generic file icon')).toBeInTheDocument();
  });

  // Icon should pass through props to the rendered icon
  it('should pass through props to the rendered icon', async () => {
    render(<Icon className="test-class" data-testid="test-icon" />);

    // Expect that there is an svg on the page with the class "test-class"
    expect(screen.getByTestId('test-icon')).toHaveClass('test-class');
  });

  // Icon should pass through svg props to the rendered icon
  it('should pass through svg props to the rendered icon', async () => {
    render(<Icon height={24} width={24} data-testid="test-icon" />);

    // Expect that there is an svg on the page with the height and width of 24
    expect(screen.getByTestId('test-icon')).toHaveAttribute('height', '24');
    expect(screen.getByTestId('test-icon')).toHaveAttribute('width', '24');
  });

  // Icon should render the correct icon when a resource source and icon are provided
  it('should render the correct icon when a resource source and icon are provided', async () => {
    // Get the sources from the icon sources
    const sources = Object.keys(iconSources) as (keyof typeof iconSources)[];

    // Loop through the sources
    for (const source of sources) {
      // Get the icons from the current source
      const icons = Object.keys(iconSources[source]);

      // Loop through the icons
      for (const icon of icons) {
        const resourceSource = source as keyof typeof iconSources;
        const iconOption = icon as keyof (typeof iconSources)[keyof typeof iconSources];

        render(<Icon resourceSource={resourceSource} icon={iconOption} isDecorative={false} />);

        // Expect that there is an svg on the page with the title of the current icon (converting _ or - to spaces and adding "icon" to the end)
        expect(screen.getByTitle(`${icon.replace(/[_-]/g, ' ')} icon`)).toBeInTheDocument();

        // Clear the rendered icon
        cleanup();
      }
    }
  });

  it('should render passed componentIcon and resourceSource is set to component', async () => {
    const Component = () => <div data-testid="test-icon" />;
    const { getByTestId } = render(
      <Icon resourceSource="component" componentIcon={(<Component />) as React.ReactNode} />,
    );
    expect(getByTestId('test-icon')).toBeInTheDocument();
  });
});
