import React from 'react';
import { fireEvent, screen } from '@testing-library/react';
import { renderInAppContext } from '@theorchard/suite-testing';
import { AbacusContractLifecycleScheduleRenewalType } from 'src/apollo/definitions/globalTypes';
import {
    CONTRACT_INTERVAL_TYPES,
    TOOLTIP_TERMINATION_NOTICE,
} from 'src/apollo/type-constants/contract';
import {
    TerminationNoticePropTypes,
    TerminationNotice,
} from 'src/components/contract-lifecycle-shared/termination-notice';

describe('<TerminationNotice/>', () => {
    const defaultProps: TerminationNoticePropTypes = {
        contractLifecycleSchedule: {
            renewalType: `${AbacusContractLifecycleScheduleRenewalType.CONTINUOUSLY_ACTIVE}`,
        },
        errors: {},
        handleFormChange: jest.fn(),
        isDisabled: false,
        isEditForm: false,
    };

    const renderComponent = (
        props: TerminationNoticePropTypes = defaultProps
    ) => renderInAppContext(<TerminationNotice {...props} />);

    it('displays the terminationNoticeDetailInterval if present', () => {
        const contractLifecycleSchedule = {
            renewalType: `${AbacusContractLifecycleScheduleRenewalType.CONTINUOUSLY_ACTIVE}`,
            terminationNoticeDetailInterval: 123,
            terminationNoticeDetailType: CONTRACT_INTERVAL_TYPES.DAYS.value,
        };

        renderComponent({ ...defaultProps, contractLifecycleSchedule });

        const terminationNoticeInput = screen.getByTestId(
            'termination-notice-interval'
        );
        const terminationNoticeType = screen.getByText(
            CONTRACT_INTERVAL_TYPES.DAYS.label
        );

        expect(terminationNoticeInput).toBeInTheDocument();
        expect(
            screen.getByDisplayValue(
                contractLifecycleSchedule.terminationNoticeDetailInterval
            )
        ).toBeInTheDocument();
        expect(terminationNoticeType.classList).toContain('active');
    });

    it('handles a terminationNoticeDetailInterval input change', () => {
        renderComponent();

        const terminationNoticeInput = screen
            .getByTestId('termination-notice-interval')
            .querySelector('input')!;

        fireEvent.change(terminationNoticeInput, { target: { value: 123 } });

        expect(defaultProps.handleFormChange).toHaveBeenCalledWith(
            'terminationNoticeDetailInterval',
            123
        );
    });

    it('handles a terminationNoticeDetailType button click', () => {
        renderComponent();

        const months = screen.getByText(CONTRACT_INTERVAL_TYPES.MONTHS.label);
        fireEvent.click(months);

        expect(defaultProps.handleFormChange).toHaveBeenCalledWith(
            'terminationNoticeDetailType',
            CONTRACT_INTERVAL_TYPES.MONTHS.value
        );
    });

    it('displays an error if present', () => {
        const errors = { terminationNoticeDetailInterval: 'i am an error' };

        renderComponent({ ...defaultProps, errors });

        const terminationNoticeInput = screen.getByTestId(
            'termination-notice-interval'
        );
        const error = screen.getByText(errors.terminationNoticeDetailInterval);

        expect(terminationNoticeInput.classList).toContain('error');
        expect(error).toBeInTheDocument();
    });

    it('is disabled when specified', () => {
        renderComponent({ ...defaultProps, isDisabled: true });

        const terminationNoticeInput = screen
            .getByTestId('termination-notice-interval')
            .querySelector('input')!;
        const terminationNoticeTypeDay = screen.getByText(
            CONTRACT_INTERVAL_TYPES.DAYS.label
        );
        const terminationNoticeTypeMonth = screen.getByText(
            CONTRACT_INTERVAL_TYPES.MONTHS.label
        );

        expect(terminationNoticeInput).toBeDisabled();
        expect(terminationNoticeTypeDay).toBeDisabled();
        expect(terminationNoticeTypeMonth).toBeDisabled();
    });

    describe('create form', () => {
        it('renders with placeholder text', () => {
            renderComponent();

            const terminationNoticeLabel = screen.getByText(
                'Termination Notice Period'
            );
            const terminationNoticeInput = screen.getByTestId(
                'termination-notice-interval'
            );
            const terminationNoticeType = screen.getByTestId(
                'termination-notice-type'
            );

            expect(terminationNoticeLabel).toBeInTheDocument();
            expect(terminationNoticeInput).toBeInTheDocument();
            expect(terminationNoticeType).toBeInTheDocument();
            expect(terminationNoticeInput.innerHTML).toContain('e.g. 7');
            expect(terminationNoticeType.textContent).toEqual('DaysMonths');
        });

        it('displays a tooltip message on hover', async () => {
            renderComponent();

            const terminationNoticeInput = screen.getByTestId(
                'termination-notice-interval'
            );
            fireEvent.mouseOver(terminationNoticeInput);

            const tooltip = await screen.findByText(TOOLTIP_TERMINATION_NOTICE);
            expect(tooltip).toBeInTheDocument();
        });
    });

    describe('edit form', () => {
        it('does not display a tooltip message on hover', () => {
            renderComponent({ ...defaultProps, isEditForm: true });

            const terminationNoticeInput = screen.getByTestId(
                'termination-notice-interval'
            );
            fireEvent.mouseOver(terminationNoticeInput);

            const tooltip = screen.queryByText(TOOLTIP_TERMINATION_NOTICE);
            expect(tooltip).not.toBeInTheDocument();
        });
    });
});
