import React from 'react';
import { fireEvent, screen } from '@testing-library/react';
import { renderInAppContext } from '@theorchard/suite-testing';
import { contractAdvancesPaidList } from 'src/__fixtures__/graphql/contract-advances';
import {
    AdvanceFormFieldsPayment,
    AdvanceFormFieldsPaymentPropTypes,
} from 'src/components/advance-form/advance-form-fields-payment';
import {
    ADVANCES_DEFAULT_REFERENCE_PAYMENT_TYPE_ALERT,
    DEFAULT_REFERENCE_PAYMENT_TYPE,
    PAYMENT_CONFIRMATION_ALLOCATED_FUNDS_CHECKBOX_LABEL,
    REFERENCE_PAYMENT_TYPE_ID,
} from 'src/constants';

describe('<ContractFormFields> layout', () => {
    const render = (props: AdvanceFormFieldsPaymentPropTypes) =>
        renderInAppContext(<AdvanceFormFieldsPayment {...props} />);

    const props: AdvanceFormFieldsPaymentPropTypes = {
        changeHandler: jest.fn(),
        formData: {
            ...contractAdvancesPaidList.abacusContractAdvancesPaid.items[0],
            approvalConfirmation: false,
            milestoneReached: 'yes',
            paymentConfirmation: false,
            referencePaymentType: null,
        },
        errors: {
            paymentConfirmation: '',
            withholdingTaxAmount: '',
            usSourceIncomeRate: '',
            vatAmount: '',
            note: '',
            milestoneDate: '',
        },
        amountAfterWithholdingAndVat: 0,
        defaultReferencePaymentTypeIsSelected: false,
    };

    it('renders', () => {
        const { container } = render(props);
        expect(container).toBeDefined();
        expect(screen.getByText('Advance Payment Fields')).toBeDefined();
        expect(
            screen.getByText(
                'The below fields are required for advance payment to be completed successfully'
            )
        ).toBeDefined();
        expect(screen.getByText('WHT')).toBeDefined();
        expect(screen.getByTestId('withholdingTaxAmount')).toBeDefined();
        expect(screen.getByText('VAT')).toBeDefined();
        expect(screen.getByTestId('vatAmount')).toBeDefined();
        expect(screen.getByText('US Source Income %')).toBeDefined();
        expect(screen.getByText('Post Tax Payable Amount')).toBeDefined();
        expect(screen.getByText('Milestone Reached?')).toBeDefined();
        expect(screen.getByText('Yes')).toBeDefined();
        expect(screen.getByText('Milestone Reached On')).toBeDefined();
        expect(screen.getByText('Sep 16, 2022')).toBeDefined();
        expect(screen.getByText('Advance Payment Notes')).toBeDefined();
        expect(screen.getByTestId('paymentNotesTestId')).not.toBeDisabled();
        expect(screen.getByText('Paid via check')).toBeDefined();
        expect(screen.getByText('Approval Confirmation')).toBeDefined();
        expect(
            screen.getByText(
                'I confirm that this advance has the required approvals.'
            )
        ).toBeDefined();
        expect(screen.getByText('Payment Confirmation')).toBeDefined();
        expect(
            screen.getByText(
                "I confirm that this advance has been paid to the customer. Checking this box will apply this advance to the customer's outstanding balance."
            )
        ).toBeDefined();
        expect(screen.getByText('Approval Confirmation')).toBeDefined();
        expect(
            screen.getByTestId('Dropdown_referencePaymentType')
        ).toBeDefined();
    });

    it('hide the approval confirmation and payment confirmation if Payoneer via Abacus is selected as a payment method', () => {
        const { container } = render({
            ...props,
            formData: {
                ...props.formData,
                referencePaymentType: DEFAULT_REFERENCE_PAYMENT_TYPE,
            },
            defaultReferencePaymentTypeIsSelected: true,
        });

        expect(container.querySelector('#approvalConfirmation')).toBeNull();
        expect(container.querySelector('#paymentConfirmation')).toBeNull();
    });

    it('show payment info alert if Payoneer via Abacus is selected as a payment method', () => {
        render({
            ...props,
            formData: {
                ...props.formData,
                referencePaymentType: DEFAULT_REFERENCE_PAYMENT_TYPE,
            },
            defaultReferencePaymentTypeIsSelected: true,
        });

        expect(
            screen.getByText(
                ADVANCES_DEFAULT_REFERENCE_PAYMENT_TYPE_ALERT.title
            )
        ).toBeDefined();
        expect(
            screen.getByText(ADVANCES_DEFAULT_REFERENCE_PAYMENT_TYPE_ALERT.text)
        ).toBeDefined();
    });

    it('enable the approval confirmation and payment confirmation if selected payment method is not Payoneer via Abacus', () => {
        render({
            ...props,
            formData: {
                ...props.formData,
                paymentConfirmation: true,
                approvalConfirmation: true,
                referencePaymentType: {
                    notes: 'Manually via Payoneer Console',
                    referencePaymentTypeId: '2',
                },
            },
        });

        const approvalConfirmation = screen
            .getByTestId('approvalConfirmationTestId')
            .querySelector('input');
        expect(approvalConfirmation).not.toHaveAttribute('disabled');

        if (approvalConfirmation) {
            fireEvent.click(approvalConfirmation);
        }
        const paymentConfirmation = screen
            .getByTestId('paymentConfirmationTestId')
            .querySelector('input');
        expect(paymentConfirmation).not.toHaveAttribute('disabled');
    });

    it('renders payment confirmation for Allocated Funds', () => {
        render({
            ...props,
            formData: {
                ...props.formData,
                paymentConfirmation: true,
                approvalConfirmation: true,
                referencePaymentType: {
                    notes: 'Allocated Funds',
                    referencePaymentTypeId:
                        REFERENCE_PAYMENT_TYPE_ID.ALLOCATED_FUNDS,
                },
            },
        });

        const approvalConfirmation = screen
            .getByTestId('approvalConfirmationTestId')
            .querySelector('input');
        expect(approvalConfirmation).not.toHaveAttribute('disabled');

        if (approvalConfirmation) {
            fireEvent.click(approvalConfirmation);
        }
        const paymentConfirmation = screen
            .getByTestId('paymentConfirmationTestId')
            .querySelector('input');
        expect(paymentConfirmation).not.toHaveAttribute('disabled');

        expect(
            screen.getByText(
                PAYMENT_CONFIRMATION_ALLOCATED_FUNDS_CHECKBOX_LABEL
            )
        ).toBeDefined();
    });

    it('render errors', () => {
        const { container } = render({
            ...props,
            errors: {
                paymentConfirmation: 'Payment confirmation error',
                withholdingTaxAmount: 'WHT error',
                usSourceIncomeRate: 'US Source Income Rate error',
                vatAmount: 'Vat Amount error',
                note: 'Note error',
                milestoneDate: 'Milestone date error',
            },
        });

        expect(container).toBeDefined();
        expect(screen.getByText('Payment confirmation error')).toBeDefined();
        expect(screen.getByText('WHT error')).toBeDefined();
        expect(screen.getByText('Vat Amount error')).toBeDefined();
        expect(screen.getByText('Note error')).toBeDefined();
        expect(screen.getByText('Milestone date error')).toBeDefined();
    });
});
