import React from 'react';
import * as apollo from '@apollo/client';
import { render, screen } from '@testing-library/react';
import { Identity, IdentityContext } from '@theorchard/suite-identity';
import { MemoryRouter } from 'react-router-dom';
import { mockContext } from '../../../../__mocks__';
import { MainNavUserModal, Props } from '../mainNavUserModal';

vi.mock('@theorchard/suite-auth', () => ({
    useAuthClient: vi.fn(),
}));

vi.mock('@theorchard/suite-config', () => ({
    useAppConfig: vi.fn(),
}));

vi.mock('@theorchard/suite-components', async () => ({
    ...(await vi.importActual('@theorchard/suite-components')),
    useToast: () => vi.fn(),
}));

describe('<MainNavUserModal>', () => {
    const defaultProps: Props = {
        isOpen: true,
        onRequestClose: vi.fn(),
    };

    const renderComponent = (props?: Partial<Props>, identity?: Partial<Identity>) =>
        render(<MainNavUserModal {...defaultProps} {...props} />, {
            wrapper: ({ children }) => (
                <IdentityContext.Provider
                    value={{
                        identity: {
                            ...mockContext.identity,
                            ...identity,
                        },
                    }}
                >
                    <MemoryRouter>{children}</MemoryRouter>
                </IdentityContext.Provider>
            ),
        });

    beforeEach(() => {
        vi.spyOn(apollo, 'useQuery').mockReturnValue({
            loading: true,
            data: undefined,
        } as apollo.QueryResult);
        vi.spyOn(apollo, 'useMutation').mockReturnValue([
            vi.fn(),
            { loading: false, data: undefined } as apollo.MutationResult,
        ]);
    });

    afterEach(() => {
        vi.restoreAllMocks();
    });

    test('renders its default state', () => {
        renderComponent();

        expect(screen.getByTestId('MainNavUserModal-content')).toBeInTheDocument();
    });

    test('renders default country name', () => {
        renderComponent();

        expect(screen.getByText('English')).toBeInTheDocument();
    });

    test('renders Japanese country name', () => {
        renderComponent({}, { locale: 'ja' });

        expect(screen.getByText('Japanese')).toBeInTheDocument();
    });

    test('renders uppercase number format', () => {
        renderComponent();

        expect(screen.getByText('US')).toBeInTheDocument();
    });

    test('render the date format', () => {
        renderComponent();

        expect(screen.getByText('YYYY/MM/DD')).toBeInTheDocument();
    });

    test('renders a link to the SettingsApp', () => {
        renderComponent();

        const anchor = screen.getByText('Update in Settings app');
        expect(anchor).toBeInTheDocument();
    });

    test('renders the default US link to the Privacy Policy', () => {
        const r = renderComponent();

        const a = r.getByTestId('MainNavUserModal-privacyPolicyLink');
        expect(a).toHaveAttribute('href', 'https://www.sonymusic.com/privacy-policy/');
    });

    test('renders the spanish link to the Privacy Policy when loginCountryCode has a map-matching value', () => {
        const r = renderComponent({}, { loginCountryCode: 'ES' });

        const a = r.getByTestId('MainNavUserModal-privacyPolicyLink');
        expect(a).toHaveAttribute('href', 'https://www.sonymusic.es/privacidad/');
    });

    describe('employee tag in the header', () => {
        test('renders employee tag', () => {
            renderComponent({}, { isEmployee: true });

            expect(screen.getByText('Employee')).toBeInTheDocument();
        });

        test('does not render employee tag', () => {
            renderComponent({}, { isEmployee: false });

            expect(screen.queryByText('Employee')).not.toBeInTheDocument();
        });
    });
});
