import React from 'react';
import { fireEvent, screen, within } from '@testing-library/react';
import { Identity } from '@theorchard/suite-frontend';
import { createIdentity, renderInAppContext } from '@theorchard/suite-testing';
import * as abacusReferenceAgreementTypesQuery from 'src/apollo/queries/abacus-reference-agreement-types';
import PayeeFieldsPayoneer, {
    PayeeFieldsPayoneerPropTypes,
} from '../payee-fields-payoneer';

describe('<PayeeFieldsPayoneer> layout', () => {
    const defaultProps: PayeeFieldsPayoneerPropTypes = {
        changeHandler: jest.fn(),
        agreementFieldProps: {
            agreementTypeId: '1',
        },
        data: {
            accountPayeeId: '1',
            payoneerProgram: {
                payoneerProgramId: 12345,
                payoneerProgramName: 'Payoneer Program Name',
            },
            payoneerPayeeId: '67812110',
            paymentPendingInCurrentStatementPeriod: null,
        },
    };

    const render = (
        props: PayeeFieldsPayoneerPropTypes,
        mockIdentity?: Partial<Identity>
    ) =>
        renderInAppContext(<PayeeFieldsPayoneer {...props} />, {
            identity: createIdentity(mockIdentity),
        });

    it('renders with default props', () => {
        const { container } = render(defaultProps);
        expect(container).toBeDefined();

        const agreementTypeDropdown = container.querySelector(
            '#agreementTypeDropdown'
        );
        expect(agreementTypeDropdown).toBeDefined();
        expect(
            agreementTypeDropdown?.classList.contains('Select--is-disabled')
        ).toBe(false);

        expect(screen.getByText('Agreement type')).toBeDefined();
        expect(screen.getByText('Payoneer Program')).toBeDefined();
        expect(screen.getByText('Payoneer Program Name')).toBeDefined();
        expect(screen.getByText('Payoneer Program ID')).toBeDefined();
        expect(screen.getByText('12345')).toBeDefined();
        expect(screen.getByText('Select Agreement Type')).toBeDefined();
        expect(container.querySelector('#HelpTooltip')).toBeDefined();
        expect(container.querySelector('.ReleasePayeeModal')).toBeDefined();
    });

    it('when not onboarded to Payoneer', () => {
        const { container } = render({
            ...defaultProps,
            agreementFieldProps: {
                ...defaultProps.agreementFieldProps,
                agreementTypeId: '',
            },
            data: {
                ...defaultProps.data,
                payoneerProgram: null,
                payoneerPayeeId: null,
            },
        });

        const agreementTypeDropdown = container.querySelector(
            '#agreementTypeDropdown'
        );
        expect(
            agreementTypeDropdown?.classList.contains('Select--is-disabled')
        ).toBe(false);
        expect(screen.getAllByTestId('hintEmptyPayoneerProgram')).toBeDefined();
        expect(container.querySelector('#HelpTooltip')).toBeFalsy();
        expect(container.querySelector('.ReleasePayeeModal')).toBeFalsy();
    });

    it('Agreement type is always available for editing', () => {
        const { container } = render({
            ...defaultProps,
        });

        const agreementTypeDropdown = container.querySelector(
            '#agreementTypeDropdown'
        );
        expect(
            agreementTypeDropdown?.classList.contains('Select--is-disabled')
        ).toBe(false);
    });

    describe('allowedAgreementTypeIds filtering', () => {
        const mockAgreementTypes = [
            { agreementType: 'AWAL Core', referenceAgreementTypeId: '1' },
            { agreementType: 'AWAL +', referenceAgreementTypeId: '2' },
            { agreementType: 'AWAL Recordings', referenceAgreementTypeId: '3' },
        ];

        beforeEach(() => {
            jest.spyOn(
                abacusReferenceAgreementTypesQuery,
                'useReferenceAgreementTypes'
            ).mockReturnValue({
                data: { abacusReferenceAgreementTypes: mockAgreementTypes },
                loading: false,
            });
        });

        afterEach(jest.restoreAllMocks);

        const openDropdown = (container: HTMLElement) => {
            const input = container.querySelector(
                '#agreementTypeDropdown input'
            );
            if (input) fireEvent.keyDown(input, { key: 'ArrowDown' });
        };

        it('filters agreement type options when allowedAgreementTypeIds provided', () => {
            const { container } = render({
                ...defaultProps,
                agreementFieldProps: {
                    ...defaultProps.agreementFieldProps,
                    allowedAgreementTypeIds: ['1', '3'],
                },
                data: {
                    ...defaultProps.data,
                    payoneerPayeeId: null,
                },
            });
            openDropdown(container);

            const menuList = within(
                container.querySelector('.Select__menu-list')!
            );

            expect(menuList.getByText('AWAL Core')).toBeDefined();
            expect(menuList.queryByText('AWAL +')).toBeNull();
            expect(menuList.getByText('AWAL Recordings')).toBeDefined();
        });
    });

    describe('agreement type disabled state', () => {
        it('disables agreement type when disabled is true', () => {
            const { container } = render({
                ...defaultProps,
                agreementFieldProps: {
                    ...defaultProps.agreementFieldProps,
                    disabled: true,
                },
                data: {
                    ...defaultProps.data,
                    payoneerPayeeId: null,
                },
            });

            expect(
                container
                    .querySelector('#agreementTypeDropdown')
                    ?.classList.contains('Select--is-disabled')
            ).toBe(true);
        });

        it('enables agreement type when disabled is false and no payoneerPayeeId', () => {
            const { container } = render({
                ...defaultProps,
                agreementFieldProps: {
                    ...defaultProps.agreementFieldProps,
                    disabled: false,
                },
                data: {
                    ...defaultProps.data,
                    payoneerPayeeId: null,
                },
            });

            expect(
                container
                    .querySelector('#agreementTypeDropdown')
                    ?.classList.contains('Select--is-disabled')
            ).toBe(false);
        });

        it('enables agreement type even with payoneerPayeeId', () => {
            const { container } = render({
                ...defaultProps,
                agreementFieldProps: {
                    ...defaultProps.agreementFieldProps,
                    disabled: false,
                },
            });

            expect(
                container
                    .querySelector('#agreementTypeDropdown')
                    ?.classList.contains('Select--is-disabled')
            ).toBe(false);
        });
    });
});
