import { fireEvent, render } from '@testing-library/react';
import TimeOffsetPicker from '../time-offset-picker';
import type { RenderResult } from '@testing-library/react';
import type { TimeOffsetPickerProps } from '../time-offset-picker';

describe('<TimeOffsetPicker/>', () => {
    const onChange = jest.fn();
    const formatHours = jest.fn();
    const formatMinutes = jest.fn();
    const options = ['01:00', '00:45', '00:30', '00:15'];

    const defaultProps: TimeOffsetPickerProps = {
        options,
        onChange,
        formatHours,
        formatMinutes,
        value: '01:00',
        enabled: true,
        disabledMessage: 'Oh no! Anyway...',
    };

    const renderWrapper = (props: Partial<TimeOffsetPickerProps> = {}) =>
        render(<TimeOffsetPicker {...defaultProps} {...props} />);

    afterEach(jest.resetAllMocks);

    test('matches snapshot', () => {
        expect(renderWrapper().container).toMatchSnapshot();
    });

    describe('non-HH:MM value', () => {
        test('throws exception', () => {
            expect(() => renderWrapper({ value: 'stringy' })).toThrowError();
        });
    });

    describe('non-HH:MM options', () => {
        test('throws exception', () => {
            expect(() =>
                renderWrapper({ options: ['stringy'] })
            ).toThrowError();
        });
    });

    describe('user selects option', () => {
        const selectionIndex = 1;
        let wrapper: RenderResult;

        beforeEach(() => {
            wrapper = renderWrapper();
            const selectControl =
                wrapper.container.getElementsByClassName('Select__control');
            fireEvent.mouseDown(selectControl[0]);

            const selectMenu =
                wrapper.container.getElementsByClassName('Select__menu');
            const selectOptions =
                selectMenu[0].getElementsByClassName('Select__option');
            fireEvent.click(selectOptions[selectionIndex]);
        });

        test('calls onChange with value', () => {
            expect(onChange).toHaveBeenCalledWith(options[selectionIndex]);
        });
    });

    describe('not enabled', () => {
        const selectionIndex = 1;
        let wrapper: RenderResult;

        beforeEach(() => {
            wrapper = renderWrapper({ enabled: false });
            const selectControl =
                wrapper.container.getElementsByClassName('Select__control');
            fireEvent.mouseDown(selectControl[0]);

            const selectMenu =
                wrapper.container.getElementsByClassName('Select__menu');
            const selectOptions =
                selectMenu[0].getElementsByClassName('Select__option');
            fireEvent.click(selectOptions[selectionIndex]);
        });

        test('does not call onChange', () =>
            expect(onChange).not.toHaveBeenCalled());
    });
});
