import React from 'react';
import { fireEvent, screen } from '@testing-library/react';
import { renderInAppContext } from '@theorchard/suite-testing';
import referenceAgreementTypes from 'src/__fixtures__/graphql/reference-agreement-types.json';
import { referencePaymentEntities } from 'src/__fixtures__/graphql/reference-payment-entity';
import * as refAgreementTypesModule from 'src/apollo/queries/abacus-reference-agreement-types';
import * as refPaymentEntitiesQuery from 'src/apollo/queries/reference-payment-entity';
import NewPaymentGroupFormFields from 'src/components/payment-group/new-payment-group-form-fields';

describe('<NewPaymentGroupFormFields />', () => {
    afterEach(jest.restoreAllMocks);

    beforeEach(() => {
        jest.spyOn(
            refPaymentEntitiesQuery,
            'useReferencePaymentEntities'
        ).mockReturnValue({
            data: referencePaymentEntities,
            loading: false,
            error: undefined,
        });
        jest.spyOn(
            refAgreementTypesModule,
            'useReferenceAgreementTypes'
        ).mockReturnValue({
            data: referenceAgreementTypes,
            loading: false,
            error: undefined,
        });
    });

    const defaultProps = {
        changeHandler: jest.fn(),
        errors: {},
        formData: {},
    };

    const render = (props = defaultProps) =>
        renderInAppContext(<NewPaymentGroupFormFields {...props} />);

    it('renders the group name input field', () => {
        render();

        expect(screen.getByTestId('payment-group-name')).toBeDefined();
    });

    it('select payment currency values', () => {
        render();

        const paymentCurrencySelect = screen
            .getByTestId('currencySelect')
            .querySelector('input') as HTMLInputElement;
        fireEvent.change(paymentCurrencySelect, { target: { value: 'aud' } });
        fireEvent.keyDown(paymentCurrencySelect, {
            key: 'Enter',
        });

        fireEvent.change(paymentCurrencySelect, { target: { value: 'usd' } });
        fireEvent.keyDown(paymentCurrencySelect, {
            key: 'Enter',
        });

        expect(screen.getByText('AUD (Australian Dollar)')).toBeDefined();
        expect(screen.getByText('USD (US Dollar)')).toBeDefined();
    });

    it('select paid by values', async () => {
        render({
            ...defaultProps,
            formData: { groupName: 'Test', referencePaymentEntities: '4' },
        });

        const paymentEntitySelect = screen
            .getByTestId('Dropdown_paymentEntity')
            .querySelector('input') as HTMLInputElement;

        fireEvent.change(paymentEntitySelect, {
            target: { value: 'KNR' },
        });
        expect(screen.getByText('KNR-NL')).toBeDefined();
        expect(screen.getByText('KNR-UK')).toBeDefined();

        fireEvent.click(screen.getByText('KNR-NL'));
        expect(screen.getByText('KNR-NL')).toBeDefined();
    });

    it('select payment schedule values', () => {
        render();

        const paymentSchedule = screen
            .getByTestId('Dropdown_paymentSchedule')
            .querySelector('input') as HTMLInputElement;
        fireEvent.change(paymentSchedule, {
            target: { value: '45 days after month end' },
        });
        fireEvent.keyDown(paymentSchedule, {
            key: 'Enter',
        });

        expect(screen.getByText('45 days after month end')).toBeDefined();
    });

    it('select agreement types values', () => {
        render();

        const agreementTypeSelect = screen
            .getByTestId('Dropdown_agreementType')
            .querySelector('input') as HTMLInputElement;
        fireEvent.change(agreementTypeSelect, { target: { value: '4' } });
        fireEvent.keyDown(agreementTypeSelect, {
            key: 'Enter',
        });

        fireEvent.change(agreementTypeSelect, { target: { value: '5' } });
        fireEvent.keyDown(agreementTypeSelect, {
            key: 'Enter',
        });

        expect(screen.getByText('Orchard')).toBeDefined();
        expect(screen.getByText('Altafonte')).toBeDefined();
    });
});
