import React from 'react';
import { render } from '@testing-library/react';
import * as AppConfigModule from '@theorchard/suite-frontend';
import { mockAppConfig } from 'lib/test-helpers/factories';
import { createIdentity } from 'lib/test-utils/identity-factory';
import { COMPANY_BRAND_THEORCHARD, BRAND_AWAL } from 'src/constants';
import IdentityContext from 'src/context';
import HelpLink from '../help-link';
import type { Vendor } from 'src/types';

jest.mock('@theorchard/suite-frontend', () => ({
    __esModule: true,
    ...jest.requireActual('@theorchard/suite-frontend'),
}));

// Mock zendesk buttons to easily identify which one is rendered
jest.mock('../../zendesk-button', () => ({
    __esModule: true,
    ZendeskButton: () => <div data-testid="zendesk-button-v1" />,
    ZendeskButtonV2: () => <div data-testid="zendesk-button-v2" />,
}));

const renderHelpLink = (identity: ReturnType<typeof createIdentity>) =>
    render(
        <IdentityContext.Provider
            value={{ identity, hasAuthentication: () => false }}
        >
            <HelpLink />
        </IdentityContext.Provider>
    );

describe.each([
    [false, 'zendesk-button-v1'],
    [true, 'zendesk-button-v2'],
])('HelpLink', (showZendeskWidgetV2: boolean, zendeskTestId: string) => {
    afterEach(() => {
        jest.restoreAllMocks();
    });

    describe('when vendor companyBrand and app config are "theorchard"', () => {
        let identity: ReturnType<typeof createIdentity>;

        beforeEach(() => {
            identity = createIdentity({ id: 1 });
            identity.vendor = {
                companyBrand: { name: COMPANY_BRAND_THEORCHARD },
            } as unknown as Vendor;
            jest.spyOn(identity, 'hasFeatureFlag').mockReturnValue(
                showZendeskWidgetV2
            );
            jest.spyOn(AppConfigModule, 'useAppConfig').mockReturnValue(
                mockAppConfig
            );
        });

        test('renders Nav.Link button', () => {
            const { container, queryByTestId } = renderHelpLink(identity);
            expect(container.querySelector('a')).toBeInTheDocument();
            expect(queryByTestId(zendeskTestId)).toBeNull();
        });
    });

    describe('when vendor companyBrand and app config are "awal"', () => {
        let identity: ReturnType<typeof createIdentity>;

        beforeEach(() => {
            identity = createIdentity({ id: 2 });
            identity.vendor = {
                companyBrand: { name: BRAND_AWAL },
            } as unknown as Vendor;
            jest.spyOn(identity, 'hasFeatureFlag').mockReturnValue(
                showZendeskWidgetV2
            );
            jest.spyOn(AppConfigModule, 'useAppConfig').mockReturnValue({
                ...mockAppConfig,
                brand: 'awal',
            });
        });

        test('renders ZendeskButton button', () => {
            const { getByTestId } = renderHelpLink(identity);
            expect(getByTestId(zendeskTestId)).toBeInTheDocument();
        });
    });

    describe('when theres no vendor companyBrand but app config is AWAL', () => {
        let identity: ReturnType<typeof createIdentity>;

        beforeEach(() => {
            identity = createIdentity({ id: 2 });
            identity.vendor = { id: 123 } as unknown as Vendor;
            jest.spyOn(identity, 'hasFeatureFlag').mockReturnValue(
                showZendeskWidgetV2
            );
            jest.spyOn(AppConfigModule, 'useAppConfig').mockReturnValue({
                ...mockAppConfig,
                brand: 'awal',
            });
        });

        test('renders ZendeskButton as we fallback to config brand', () => {
            const { getByTestId } = renderHelpLink(identity);
            expect(getByTestId(zendeskTestId)).toBeInTheDocument();
        });
    });
});
