import React from 'react';
import { MockedProvider } from '@apollo/client/testing';
import { renderHook, waitFor } from '@testing-library/react';
import createCache from 'src/apollo/cache';
import getAccountSubaccountsQuery from '../get-account-subaccounts.gql';
import { useAccountSubaccounts } from '../index';

const page = (
    offset: number,
    subaccounts: Array<{ subaccountId: number; name: string }>,
    totalCount: number
) => ({
    request: {
        query: getAccountSubaccountsQuery,
        variables: { vendorId: 101, limit: 200, offset },
    },
    result: {
        data: {
            vendor: {
                __typename: 'Vendor',
                subaccounts: {
                    __typename: 'SubaccountsResults',
                    totalCount,
                    subaccounts: subaccounts.map(s => ({
                        __typename: 'Subaccount',
                        ...s,
                    })),
                },
            },
        },
    },
});

const wrapper =
    (mocks: ReturnType<typeof page>[]) =>
    ({ children }: { children: React.ReactNode }) => (
        <MockedProvider mocks={mocks} cache={createCache()}>
            {children}
        </MockedProvider>
    );

describe('useAccountSubaccounts', () => {
    it('pages through and accumulates every subaccount past the first page', async () => {
        const mocks = [
            page(
                0,
                [
                    { subaccountId: 1, name: 'A' },
                    { subaccountId: 2, name: 'B' },
                ],
                3
            ),
            page(2, [{ subaccountId: 3, name: 'C' }], 3),
        ];

        const { result } = renderHook(() => useAccountSubaccounts(101), {
            wrapper: wrapper(mocks),
        });

        await waitFor(() => expect(result.current.subaccounts).toHaveLength(3));
        expect(result.current.subaccounts.map(s => s.name)).toEqual([
            'A',
            'B',
            'C',
        ]);
        expect(result.current.loading).toBe(false);
    });

    it('stays loading while more pages remain', async () => {
        const mocks = [
            page(0, [{ subaccountId: 1, name: 'A' }], 2),
            page(1, [{ subaccountId: 2, name: 'B' }], 2),
        ];

        const { result } = renderHook(() => useAccountSubaccounts(101), {
            wrapper: wrapper(mocks),
        });

        // After the first page lands, one of two is loaded, so loading holds.
        await waitFor(() =>
            expect(result.current.subaccounts.length).toBeGreaterThan(0)
        );
        await waitFor(() => expect(result.current.subaccounts).toHaveLength(2));
        expect(result.current.loading).toBe(false);
    });
});
