/**
 * @jest-environment jsdom
 */

import * as React from 'react';
import 'jest-canvas-mock';
import { fireEvent, render, screen } from '@testing-library/react';

import { SelectComponent, InputOption } from '../../../src/ts';

describe('Select Component', () => {
    const options = ['Red', 'Green', 'Blue'].map(function (e) {
        return new InputOption(e, e);
    });

    test('Default selection', () => {
        render(
            <SelectComponent options={options} defaultSelection={'Green'} />
        );

        const greenOption = screen.getByRole('option', {
            name: 'Green',
        }) as HTMLOptionElement;
        const redOption = screen.getByRole('option', {
            name: 'Red',
        }) as HTMLOptionElement;
        expect(greenOption.selected).toBe(true);
        expect(redOption.selected).toBe(false);
    });

    test('No default', () => {
        render(<SelectComponent options={options} />);
        const redOption = screen.getByRole('option', {
            name: 'Red',
        }) as HTMLOptionElement;
        expect(redOption.selected).toBe(true);
    });

    test('No options', () => {
        render(<SelectComponent />);

        const allOptions = screen.getAllByRole('option') as HTMLOptionElement[];

        expect(allOptions.length).toBe(1);
        expect(allOptions[0].value).toBe('none');
    });

    test('Disabled', () => {
        render(<SelectComponent options={options} disabled={true} />);

        const selectOptions = screen.getAllByRole(
            'option'
        ) as HTMLOptionElement[];
        const greenOption = screen.getByRole('option', {
            name: 'Green',
        }) as HTMLOptionElement;

        let selectedValue = null;
        for (const option in selectOptions) {
            if (selectOptions[option].selected == true) {
                selectedValue = selectOptions[option].value;
            }
        }

        fireEvent.click(greenOption);

        for (const option in selectOptions) {
            if (selectOptions[option].selected == true) {
                expect(selectOptions[option].value).toBe(selectedValue);
            }
        }
    });

    test('Select', () => {
        const selectionHandler = jest.fn();
        render(
            <SelectComponent options={options} onSelection={selectionHandler} />
        );

        const redOption = screen.getByRole('option', {
            name: 'Red',
        }) as HTMLOptionElement;

        expect(redOption.selected).toBe(true);

        fireEvent.change(screen.getByRole('combobox'), {
            target: { value: 'Green' },
        });
        expect(selectionHandler).toBeCalledWith('Green');
    });

    test('Select Component with a label', () => {
        const selectionHandler = jest.fn();
        render(
            <SelectComponent
                labelForEmptyOption={'A label'}
                options={options}
                onSelection={selectionHandler}
            />
        );

        expect(screen.getByText('A label')).toBeTruthy();
    });
});
