import { fireEvent, render, screen } from '@testing-library/react';
import dayjs from 'dayjs';
import utc from 'dayjs/plugin/utc';
import React from 'react';
import DateTimePicker from '../date-time-picker';
import type { DateTimePickerProps } from '../date-time-picker';

dayjs.extend(utc);

describe('<DateTimePicker>', () => {
    const date = '2023-08-30';
    const time = '02:38:13';
    const dateInput = `${date}T${time}Z`;
    const onDateTimeChange = jest.fn();

    const defaultProps: DateTimePickerProps = {
        dateTime: dayjs(dateInput).toDate(),
        onDateTimeChange,
        disabledMessage: 'Oh no! Anyway...',
    };

    afterEach(jest.resetAllMocks);

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

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

    describe('onDateTimeChange', () => {
        describe('when time changed', () => {
            const value = '01:00:00';

            beforeEach(() => {
                const { container } = renderWrapper();

                const selectControl =
                    container.getElementsByClassName('Select__control');
                fireEvent.mouseDown(selectControl[0]);

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

            test('is invoked with date changes', () => {
                const dateCall: Date = onDateTimeChange.mock.calls[0][0];
                expect(
                    dayjs(dateCall).utc().format('YYYY-MM-DDTHH:mm:ss[Z]')
                ).toEqual(`${date}T${value}Z`);
            });
        });

        describe('when date changed', () => {
            const day = 27;
            const value = `2023-08-${day}`;

            beforeEach(() => {
                const { container } = renderWrapper();
                const selectControl = container.getElementsByClassName(
                    'SuiteDatePicker-indicator-calendar'
                );
                fireEvent.click(selectControl[0]);

                container.getElementsByClassName('DateSelect-calendar');
                const dayElements = screen.getAllByText(day, {
                    selector: '.DateSelect-calendar-date[role="button"]',
                });

                fireEvent.mouseDown(dayElements[2]);
            });

            test('onDateTimeChange is invoked with date changes', () => {
                const [[dateTime]] = onDateTimeChange.mock.calls;
                expect(dateTime).toEqual(
                    dayjs.utc(`${value}T${time}Z`).toDate()
                );
            });
        });
    });
});
