import React from 'react';
import { render } from '@testing-library/react';
import { DeliveryStoreDistributionType } from 'src/data/globalTypes';
import * as queries from 'src/data/queries';
import {
    DeliveryRestrictionsProvider,
    useDeliveryRestrictionsContext,
} from '../useDeliveryRestrictionsContext';

jest.mock('src/data/queries', () => ({
    useDeliveryStoresV2Query: jest.fn(),
    useTerritoriesQuery: jest.fn(),
    useDeliveryRestrictionsQuery: jest.fn(),
}));

const deliveryStoresResult = {
    data: [
        {
            __typename: 'DeliveryStore',
            id: '1',
            name: 'Spotify',
            classifications: [],
            distributionTypes: [DeliveryStoreDistributionType.FULL_TRACK],
        },
        {
            __typename: 'DeliveryStore',
            id: '2',
            name: 'Apple',
            classifications: [],
            distributionTypes: [DeliveryStoreDistributionType.FULL_TRACK],
        },
    ],
    loading: false,
    error: undefined,
} as unknown as ReturnType<typeof queries.useDeliveryStoresV2Query>;

const territoriesResult = {
    data: [
        {
            territoryCodeA2: 'US',
            continent: 'North America',
            territoryName: 'United States of America',
            countryName: 'USA',
        },
        {
            territoryCodeA2: 'CA',
            continent: 'North America',
            territoryName: 'Canada',
            countryName: 'Canada',
        },
    ],
    loading: false,
    error: undefined,
} as unknown as ReturnType<typeof queries.useTerritoriesQuery>;

const deliveryRestrictionsResult = {
    data: {
        productId: 123,
        deliveryRestrictions: [
            {
                deliveryStoreRestrictions: [],
                territoryRestrictions: [],
                deliveryStoreCountryRestrictions: [],
                newStoreOptOuts: null,
            },
        ],
        label: {
            activeDeliveryRestrictions: [
                {
                    deliveryStoreRestrictions: [
                        {
                            deliveryStore: { id: '1' },
                            distributionTypes: [{ id: 1 }],
                        },
                    ],
                    territoryRestrictions: [
                        {
                            territory: {
                                continent: 'North America',
                                orchId: '1',
                                countryName: 'USA',
                                territoryName: 'United States of America',
                                territoryCodeA2: 'US',
                                territoryCodeA3: 'USA',
                            },
                        },
                    ],
                    deliveryStoreCountryRestrictions: [
                        {
                            deliveryStore: { id: '1' },
                            territories: [
                                {
                                    continent: 'North America',
                                    orchId: '2',
                                    countryName: 'Canada',
                                    territoryName: 'Canada',
                                    territoryCodeA2: 'CA',
                                    territoryCodeA3: 'CA',
                                },
                            ],
                        },
                    ],
                    newStoreOptOuts: null,
                },
            ],
        },
    },
    loading: false,
    error: undefined,
} as unknown as ReturnType<typeof queries.useDeliveryRestrictionsQuery>;

const Test = () => {
    const { stores, territories, storeTerritories } =
        useDeliveryRestrictionsContext();

    return (
        <>
            <div data-testid="stores">
                {stores.map(store => store.name).join(' ')}
            </div>
            <div data-testid="territories">
                {territories
                    .map(territory => territory.territoryCodeA2)
                    .join(' ')}
            </div>
            <div data-testid="store-territories">
                {storeTerritories
                    .map(storeTerritory => storeTerritory.storeId)
                    .join(' ')}
            </div>
        </>
    );
};

describe('deliveryRestrictionsContext', () => {
    const renderWithProvider = () =>
        render(
            <DeliveryRestrictionsProvider productId={123}>
                <Test />
            </DeliveryRestrictionsProvider>
        );

    beforeEach(() => {
        jest.spyOn(queries, 'useDeliveryStoresV2Query').mockReturnValue(
            deliveryStoresResult
        );

        jest.spyOn(queries, 'useTerritoriesQuery').mockReturnValue(
            territoriesResult
        );

        jest.spyOn(queries, 'useDeliveryRestrictionsQuery').mockReturnValue(
            deliveryRestrictionsResult
        );
    });

    test('should initialize with expected queries params', () => {
        renderWithProvider();

        expect(queries.useDeliveryRestrictionsQuery).toHaveBeenCalledWith(123);
        expect(queries.useDeliveryStoresV2Query).toHaveBeenCalledWith([
            'ACTIVE',
            'ONBOARDING',
            'SUSPENDED',
        ]);
        expect(queries.useTerritoriesQuery).toHaveBeenCalled();
    });

    test('should return context data after applying delivery restrictions', () => {
        const { getByTestId } = renderWithProvider();

        expect(getByTestId('stores').textContent).toBe('Spotify Apple');
        expect(getByTestId('territories').textContent).toBe('US CA');
        expect(getByTestId('store-territories').textContent).toBe('1');
    });
});
