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_RENEW_AFTER,
} from 'src/apollo/type-constants/contract';
import {
    RenewPeriodicallyPropTypes,
    RenewPeriodically,
} from 'src/components/contract-lifecycle-shared/renew-periodically';

describe('<RenewPeriodically/>', () => {
    const defaultProps: RenewPeriodicallyPropTypes = {
        contractLifecycleSchedule: {
            renewalType: `${AbacusContractLifecycleScheduleRenewalType.RENEW_PERIODICALLY}`,
            renewalOffsetDetailType: CONTRACT_INTERVAL_TYPES.MONTHS.value,
        },
        errors: {},
        handleFormChange: jest.fn(),
        isDisabled: false,
        isEditForm: false,
    };

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

    it('displays the renewalOffsetDetailInterval if present', () => {
        const contractLifecycleSchedule = {
            renewalType: `${AbacusContractLifecycleScheduleRenewalType.RENEW_PERIODICALLY}`,
            renewalOffsetDetailInterval: 123,
            renewalOffsetDetailType: CONTRACT_INTERVAL_TYPES.YEARS.value,
        };

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

        const renewAfterInput = screen.getByTestId('renewal-offset-interval');
        const renewAfterType = screen.getByText(
            CONTRACT_INTERVAL_TYPES.YEARS.label
        );

        expect(renewAfterInput).toBeInTheDocument();
        expect(
            screen.getByDisplayValue(
                contractLifecycleSchedule.renewalOffsetDetailInterval
            )
        ).toBeInTheDocument();
        expect(renewAfterType.classList).toContain('active');
    });

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

        const renewAfterInput = screen
            .getByTestId('renewal-offset-interval')
            .querySelector('input')!;

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

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

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

        const years = screen.getByText(CONTRACT_INTERVAL_TYPES.YEARS.label);
        fireEvent.click(years);

        expect(defaultProps.handleFormChange).toHaveBeenCalledWith(
            'renewalOffsetDetailType',
            CONTRACT_INTERVAL_TYPES.YEARS.value
        );
    });

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

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

        const renewAfterInput = screen.getByTestId('renewal-offset-interval');
        const error = screen.getByText(errors.renewalOffsetDetailInterval);

        expect(renewAfterInput.className).toContain('error');
        expect(error).toBeInTheDocument();
    });

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

        const renewAfterInput = screen
            .getByTestId('renewal-offset-interval')
            .querySelector('input')!;
        const renewAfterTypeMonth = screen.getByText(
            CONTRACT_INTERVAL_TYPES.MONTHS.label
        );
        const renewAfterTypeYear = screen.getByText(
            CONTRACT_INTERVAL_TYPES.YEARS.label
        );

        expect(renewAfterInput).toBeDisabled();
        expect(renewAfterTypeMonth).toBeDisabled();
        expect(renewAfterTypeYear).toBeDisabled();
    });

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

            const renewAfterLabel = screen.getByText('Renew After');
            const renewAfterInput = screen.getByTestId(
                'renewal-offset-interval'
            );
            const renewAfterType = screen.getByTestId('renewal-offset-type');

            expect(renewAfterLabel).toBeInTheDocument();
            expect(renewAfterInput).toBeInTheDocument();
            expect(renewAfterType).toBeInTheDocument();
            expect(renewAfterInput.innerHTML).toContain('e.g. 1');
            expect(renewAfterType.textContent).toEqual('MonthsYears');
        });

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

            const renewAfterInput = screen.getByTestId(
                'renewal-offset-interval'
            );
            fireEvent.mouseOver(renewAfterInput);

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

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

            const renewAfterInput = screen.getByTestId(
                'renewal-offset-interval'
            );
            fireEvent.mouseOver(renewAfterInput);

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