import React, { useEffect, useState } from 'react';
import { ChatGlyph } from '@orchard/frontend-react-components';
import { useAppConfig, Segment } from '@theorchard/suite-frontend';
import { useTheme, themes, rgbToHex } from '@theorchard/suite-theming';
import {
    BRAND_AWAL,
    EVENT_HELP_CLICKED,
    FEATURE_ZENDESK_TOKEN_AUTH,
    HEADER_TERM,
} from 'src/constants';
import IdentityContext from 'src/context';
import { services } from 'src/services/user';
import { formatMessage } from 'src/utils';
import { getAccountDetails } from '../utils';

export const NO_ZENDESK_KEY_MSG =
    'Failed to initialize the Zendesk help button. No "zendeskKey" has been defined in the app configuration';
const CLASSNAME = 'ZendeskButton';
const SCRIPT_ID = 'ze-snippet';

const getThemeColor = (tc: Record<string, string>, colorV2: string) => {
    const cValue = tc?.[colorV2];
    return cValue ? rgbToHex(cValue) : undefined;
};

const ZendeskButton: React.FC = () => {
    const { identity } = React.useContext(IdentityContext);
    const config = useAppConfig();
    const { theme } = useTheme();
    const themeColors = themes[theme]?.colors || {};

    const zendeskKey = config?.zendeskKey;
    const zendeskTicketFormIds = config?.zendeskTicketFormIds;

    const [isScriptLoaded, setIsScriptLoaded] = useState(false);
    const [isWidgetOpen, setIsWidgetOpen] = useState(false);

    const widgetColors = {
        button: getThemeColor(themeColors, 'midnight-650'),
        resultLists: getThemeColor(themeColors, 'midnight-450'),
        header: getThemeColor(themeColors, 'midnight-850'),
        articleLinks: getThemeColor(themeColors, 'midnight-850'),
    };

    useEffect(() => {
        if (!zendeskKey || document.getElementById(SCRIPT_ID) || isScriptLoaded)
            return;

        window.zESettings = {
            webWidget: {
                offset: { horizontal: '20px', vertical: '40px' },
                position: { horizontal: 'right', vertical: 'top' },
            },
        };

        const script = document.createElement('script');
        script.id = SCRIPT_ID;
        script.setAttribute('data-testid', 'ZendeskScript');
        script.src = `https://static.zdassets.com/ekr/snippet.js?key=${zendeskKey}`;
        script.async = true;
        script.onload = () => {
            window.zE?.('webWidget', 'hide');

            window.zE?.('webWidget:on', 'open', () => {
                void Segment.trackEvent(EVENT_HELP_CLICKED);
                setIsWidgetOpen(true);
            });

            window.zE?.('webWidget:on', 'close', () => {
                window.zE?.('webWidget', 'hide');
                setIsWidgetOpen(false);
            });

            setIsScriptLoaded(true);
        };
        script.onerror = () => {
            console.warn('There was an error loading zendesk'); // eslint-disable-line no-console
        };

        document.body.appendChild(script);
    }, [zendeskKey, isScriptLoaded]);

    useEffect(() => {
        if (!isScriptLoaded) return;

        const account = getAccountDetails(identity);

        window.zE?.('webWidget', 'identify', {
            name: account.contactName,
            email: account.contactEmail,
            organization: account.defaultBrand || config.brand,
        });

        let contactFormConfig;
        if (zendeskTicketFormIds) {
            contactFormConfig = {
                ticketForms: zendeskTicketFormIds
                    .split(/\s*,\s*/)
                    .map(id => ({ id })),
            };
        } else {
            contactFormConfig = {
                fields: [
                    { id: 'email', prefill: { '*': account.contactEmail } },
                ],
            };
        }

        window.zE?.('webWidget', 'updateSettings', {
            webWidget: {
                contactForm: contactFormConfig,
            },
        });

        if (
            config.brand === BRAND_AWAL &&
            identity.hasFeatureFlag(FEATURE_ZENDESK_TOKEN_AUTH)
        ) {
            window.zE?.('webWidget', 'updateSettings', {
                webWidget: {
                    authenticate: {
                        jwtFn: (callback: (token: string) => void) => {
                            if (!identity.identityId) return;
                            void services
                                .getGqlZendeskToken(identity.identityId)
                                .then(token => {
                                    if (token) callback(token);
                                    else
                                        console.warn(
                                            'Can not get zendesk auth token'
                                        ); // eslint-disable-line no-console
                                });
                        },
                    },
                },
            });
        }

        if (identity.identity?.localization)
            window.zE?.(
                'webWidget',
                'setLocale',
                identity.identity.localization
            );
    }, [isScriptLoaded, identity, config.brand, zendeskTicketFormIds]);

    if (!zendeskKey) {
        console.warn(NO_ZENDESK_KEY_MSG); // eslint-disable-line no-console
        return null;
    }

    return (
        <button
            type="button"
            id="zendeskButton"
            className={`${CLASSNAME} Header-navItem zE-${
                isWidgetOpen ? 'Open' : 'Closed'
            }`}
            data-testid={CLASSNAME}
            onClick={() => {
                window.zE?.('webWidget', 'show');
                window.zE?.('webWidget', 'toggle');

                if (config.brand === BRAND_AWAL) {
                    window.zE?.('webWidget', 'updateSettings', {
                        webWidget: {
                            answerBot: {
                                suppress: true,
                            },
                        },
                    });
                    window.zE?.('webWidget', 'helpCenter:setSuggestions', {
                        search: 'workstation',
                    });
                }

                window.zE?.('webWidget', 'updateSettings', {
                    webWidget: {
                        color: widgetColors,
                    },
                });
            }}
        >
            <ChatGlyph />
            <span>{formatMessage(`${HEADER_TERM}.help`)}</span>
        </button>
    );
};

export default ZendeskButton;
