import React from 'react';
import { screen } from '@testing-library/react';
import { renderInAppContext } from '@theorchard/suite-testing';
import * as paymentHoldResponse from 'src/__fixtures__/graphql/payment-hold-response.json';
import * as identityQuery from 'src/apollo/queries/identity';
import PaymentHoldHistory, {
    type PaymentHoldHistoryProps,
} from '../payment-hold-history';

const historyResponse =
    paymentHoldResponse.abacusPaymentHold.paymentHoldHistory;

describe('<PaymentHoldHistory>', () => {
    const defaultProps: PaymentHoldHistoryProps = {
        holdHistory: historyResponse,
        includeHeader: false,
    };

    const mockIdentityResponse = {
        identityById: {
            name: 'Joe User',
        },
    };

    beforeEach(() => {
        jest.spyOn(identityQuery, 'useGetIdentityByIdQuery').mockImplementation(
            // @ts-expect-error: data fixture does not exactly match type
            identityId => ({
                data:
                    identityId === 'sax-ingestion'
                        ? null
                        : mockIdentityResponse,
                loading: false,
                error: null,
            })
        );
    });

    const render = (props: PaymentHoldHistoryProps) =>
        renderInAppContext(<PaymentHoldHistory {...props} />);

    it('renders when there is a payment hold history', async () => {
        expect.assertions(historyResponse.length);
        render(defaultProps);

        await screen.findByText(historyResponse[0].reason);

        historyResponse.forEach(item =>
            expect(screen.getByText(item.reason)).toBeTruthy()
        );
    });

    it('renders the name of the user who created each payment hold', async () => {
        render(defaultProps);
        const [user] = await screen.findAllByText('Joe User');
        expect(user).toBeInTheDocument();
    });

    it('renders the creatorName field as is when identity query comes back null', async () => {
        render({
            holdHistory: historyResponse.map(h => ({
                ...h,
                lastModifiedBy: 'sax-ingestion',
            })),
            includeHeader: false,
        });

        const users = await screen.findAllByText('sax-ingestion');
        users.forEach(user => expect(user).toBeInTheDocument());
    });

    it('does not render when there is no payment hold history', () => {
        const props = { holdHistory: [] };
        render(props);
        expect(
            screen.getByTestId('paymentHoldHistoryContentTestid').innerHTML
        ).toEqual('');
    });

    it('renders the header when requested', async () => {
        const props = { ...defaultProps, includeHeader: true };
        render(props);
        expect(
            await screen.findByTestId('paymentHoldHistoryHeaderTestid')
        ).toBeDefined();
    });

    it('does not render the header when requested if history is empty', () => {
        const props = { holdHistory: [], includeHeader: true };
        render(props);
        expect(
            screen.queryAllByTestId('paymentHoldHistoryHeaderTestid').length
        ).toEqual(0);
    });
});
