import React from 'react';
import { waitFor } from '@testing-library/react';
import { renderComponent } from 'lib/test-helpers/render-helper';
import * as reactRouterDom from 'react-router-dom';
import { GET_VENDOR_AGREEMENT_QUERY } from '../../queries/get-vendor-agreement';
import { GET_TW_PROFILE_QUERY } from '../../queries/tw-profile';
import { USER_FEATURES } from '../../constants';
import withPaymentsActivated from '../with-payments-activated';

// @ts-ignore
jest.spyOn(reactRouterDom, 'Redirect').mockImplementation(() => 'Redirect');

const TestComponent = () => <>Content</>;

const Component = withPaymentsActivated(TestComponent);

const getMocks = (vendorAgreementResult: Object | null, transferWiseProfileResult: Object | null) => [
    {
        request: {
            query: GET_VENDOR_AGREEMENT_QUERY,
            variables: {
                optInPreferenceId: 2,
            },
        },
        result: {
            data: {
                getVendorAgreement: vendorAgreementResult,
            },
        },
    },
    {
        request: {
            query: GET_TW_PROFILE_QUERY,
        },
        result: {
            data: {
                transferWiseProfile: transferWiseProfileResult,
            },
        },
    },
];

describe('useEnsurePaymentsActivated', () => {
    describe('when the payouts feature flag is disabled', () => {
        describe('on initial render', () => {
            it('returns the correct value and navigates to the index page', async () => {
                const { container } = renderComponent({
                    Component,
                    mocks: getMocks(null, null),
                });

                await waitFor(() => {
                    expect(container).not.toBeEmptyDOMElement();
                });

                expect(container).toHaveTextContent('Redirect');
            });
        });
    });

    describe('when the payouts feature flag is enabled', () => {
        const featureFlags = [USER_FEATURES.COLLABORATOR_PAYOUTS];

        describe('after queries have returned', () => {
            describe('and there is no vendor agreement', () => {
                describe('and no profile', () => {
                    it('returns the correct value and navigates to the index page', async () => {
                        const { container } = renderComponent({
                            Component,
                            mocks: getMocks(null, null),
                            featureFlags,
                        });

                        await waitFor(() => {
                            expect(container).not.toBeEmptyDOMElement();
                        });

                        expect(container).toHaveTextContent('Redirect');
                    });
                });

                describe('and a profile with verified status', () => {
                    it('returns the correct value and navigates to the index page', async () => {
                        const { container } = renderComponent({
                            Component,
                            mocks: getMocks(null, {
                                status: 'VERIFIED',
                                profileId: 123,
                            }),
                            featureFlags,
                        });

                        await waitFor(() => {
                            expect(container).not.toBeEmptyDOMElement();
                        });

                        expect(container).toHaveTextContent('Redirect');
                    });
                });
            });

            describe('and there is a vendor agreement', () => {
                describe('and no profile', () => {
                    it('returns the correct value and navigates to the index page', async () => {
                        const { container } = renderComponent({
                            Component,
                            mocks: getMocks({ vendorAgreementId: 123 }, null),
                            featureFlags,
                        });

                        await waitFor(() => {
                            expect(container).not.toBeEmptyDOMElement();
                        });

                        expect(container).toHaveTextContent('Redirect');
                    });
                });

                describe('and a profile with a non-verified status', () => {
                    it('returns the correct value and navigates to the index page', async () => {
                        const { container } = renderComponent({
                            Component,
                            mocks: getMocks(
                                { vendorAgreementId: 123 },
                                { status: 'UNVERIFIED', profileId: 456 }
                            ),
                            featureFlags,
                        });

                        await waitFor(() => {
                            expect(container).not.toBeEmptyDOMElement();
                        });

                        expect(container).toHaveTextContent('Redirect');
                    });
                });

                describe('and a profile with verified status', () => {
                    it("returns the correct value and doesn't navigate", async () => {
                        const { container } = renderComponent({
                            Component,
                            mocks: getMocks(
                                { vendorAgreementId: 123 },
                                { status: 'VERIFIED', profileId: 456 }
                            ),
                            featureFlags,
                        });

                        await waitFor(() => {
                            expect(container).not.toBeEmptyDOMElement();
                        });

                        expect(container).toHaveTextContent('Content');
                    });
                });
            });
        });
    });
});

