import * as React from 'react';
import zh from './i18n/zh';
import { useEffect, useState } from 'react';
import { IntlProvider } from 'react-intl';
import { Skeleton } from 'antd';
import { AuthInfo, DeployInfo, handleI18nMessages, LoginInfo, PageStep, Platfrom, UserConfig } from './common';
import { HomeStep } from './components/homeStep';
import { TencentLoginStep } from './components/tencentLoginStep';
import { CommonLoginStep } from './components/commonLoginStep';
import { InfoStep } from './components/infoStep';
import { v4 as uuidv4 } from 'uuid';
import ReactGA from 'react-ga';
// @ts-ignore
import { RpcBrowser } from '@sap-devx/webview-rpc/out.browser/rpc-browser';
// @ts-ignore
import '@sap-devx/webview-rpc/out.browser/rpc-common';

// @ts-ignore
const vscode = acquireVsCodeApi();
const rpc = new RpcBrowser(window, vscode);

export const App = () => {
    const [languageMap, setLanguageMap] = useState<{ [key: string]: string }>(zh);
    const [language, setLanguage] = useState<string>('zh-cn');
    const [loading, setLoading] = useState<boolean>(true);
    const [step, setStep] = useState<PageStep>(PageStep.HOME);
    const [platform, setPlatform] = useState<Platfrom>(Platfrom.TENCENT);
    const [tencentAuthInfo, setTencentAuthInfo] = useState<AuthInfo | undefined>();
    const [authInfo, setAuthInfo] = useState<UserConfig | undefined>();
    const [info, setInfo] = useState<DeployInfo | undefined>();
    const [supportDeploy, setSupportDeploy] = useState<boolean>(true);
    const [checkSupportInterval, setCheckSupportInterval] = useState<NodeJS.Timeout>();
    const [tencentOnly, setTencentOnly] = useState<boolean>(false);

    const authInvalidHandler = (loginInfo: LoginInfo) => {
        setStep(PageStep.LOGIN);
        setInfo(undefined);
        if (platform === Platfrom.TENCENT) {
            setTencentAuthInfo(data => {
                return { stage: data?.stage, region: data?.region, login: loginInfo } as AuthInfo;
            });
        } else {
            setAuthInfo(data => {
                return { stage: data?.stage, region: data?.region };
            });
        }
    };
    rpc.registerMethod({ func: authInvalidHandler, name: 'authInvalid' });
    rpc.registerMethod({
        func: (val: boolean) => setTencentOnly(val),
        name: 'updateTencentOnly',
    });

    const updateConfig = (data: { region?: string; stage?: string }) => {
        if (platform === Platfrom.TENCENT) {
            setTencentAuthInfo({ ...(tencentAuthInfo as AuthInfo), ...data });
        } else {
            setAuthInfo({ ...authInfo, ...data });
        }
    };

    const selectPlatform = async (type: Platfrom) => {
        setLoading(true);
        if (type === Platfrom.TENCENT) {
            setPlatform(type);
            if (tencentAuthInfo?.user?.uin && !tencentAuthInfo?.user.token) {
                setStep(PageStep.INFO);
            } else {
                const auth = await rpc.invoke('getTencentAuth');
                setTencentAuthInfo(auth);
                if (auth?.login) {
                    setStep(PageStep.LOGIN);
                } else {
                    setStep(PageStep.INFO);
                }
            }
        } else {
            if (platform === type && authInfo?.accountId) {
                setStep(PageStep.INFO);
            } else {
                setPlatform(type);
                const config = await rpc.invoke('getAccountConfig', [type]);
                setAuthInfo(config);
                if (config?.accountId) {
                    setStep(PageStep.INFO);
                } else {
                    setStep(PageStep.LOGIN);
                }
            }
        }

        setLoading(false);
    };

    const triggerLogout = async () => {
        setLoading(true);
        setStep(PageStep.HOME);
        await rpc.invoke('logout', [platform]);
        if (platform === Platfrom.TENCENT) {
            setTencentAuthInfo({ stage: tencentAuthInfo?.stage!, region: tencentAuthInfo?.region! });
        } else {
            setAuthInfo({ stage: authInfo?.stage, region: authInfo?.region });
        }
        setLoading(false);
    };

    const checkProjectSupport = async () => {
        const support = await rpc.invoke('checkSupport');
        setSupportDeploy(support);
    };

    const initGA = () => {
        const sessionId = uuidv4();
        ReactGA.initialize(
            [
                {
                    trackingId: 'UA-65952334-7',
                    gaOptions: {
                        userId: sessionId,
                        siteSpeedSampleRate: 100,
                    },
                },
            ],
            {
                titleCase: false,
                alwaysSendToDefaultTracker: false,
            }
        );
    };

    const init = async () => {
        initGA();

        const languageRes = await rpc.invoke('getVscodeEnv');
        setLanguage(languageRes);
        setLanguageMap(handleI18nMessages(languageRes));

        const { platform, config, tencentOnly } = await rpc.invoke('getHomeInit');
        setPlatform(platform);
        setTencentOnly(tencentOnly);

        let tokenAvailable = true;
        if (platform === Platfrom.TENCENT) {
            // 检查Token是否过期
            if (config?.accountId && config?.token) {
                tokenAvailable = await rpc.invoke('checkTencentTokenValid', [
                    config.accessKeyId,
                    config.accessKeySecret,
                    config.token,
                ]);
            }
            setTencentAuthInfo({
                region: config.region,
                stage: config.stage,
                user: config?.accountId
                    ? {
                          uin: config.accountId,
                          secretId: config.accessKeyId,
                          secretKey: config.accessKeySecret,
                          token: config?.token,
                      }
                    : undefined,
            });
        } else {
            setAuthInfo(config);
        }
        setLoading(false);

        // 已有平台登录信息则自动跳转
        if (tokenAvailable && config?.accountId) {
            setStep(PageStep.INFO);
        }
    };

    useEffect(() => {
        init();

        const intv = setInterval(async () => {
            await checkProjectSupport();
        }, 3000);
        setCheckSupportInterval(intv);

        return () => {
            if (checkSupportInterval) {
                clearInterval(checkSupportInterval);
            }
        };
    // eslint-disable-next-line react-hooks/exhaustive-deps
    }, []);

    return (
        <IntlProvider locale={language} messages={languageMap}>
            <div className='App'>
                {loading ? (
                    <Skeleton active paragraph={{ rows: 4 }} />
                ) : (
                    <div className='container'>
                        {step === PageStep.HOME && (
                            <HomeStep rpc={rpc} tencentOnly={tencentOnly} selectPlatform={selectPlatform} />
                        )}

                        {step === PageStep.LOGIN && platform === Platfrom.TENCENT && (
                            <TencentLoginStep
                                rpc={rpc}
                                setStep={setStep}
                                tencentAuthInfo={tencentAuthInfo}
                                setTencentAuthInfo={setTencentAuthInfo}
                            />
                        )}

                        {step === PageStep.LOGIN && platform !== Platfrom.TENCENT && (
                            <CommonLoginStep
                                rpc={rpc}
                                platform={platform}
                                setStep={setStep}
                                authInfo={authInfo}
                                setAuthInfo={setAuthInfo}
                            />
                        )}

                        {step === PageStep.INFO && (
                            <InfoStep
                                rpc={rpc}
                                language={language}
                                languageMap={languageMap}
                                platform={platform}
                                isSupport={supportDeploy}
                                tencentOnly={tencentOnly}
                                deployInfo={info}
                                setInfo={setInfo}
                                setStep={setStep}
                                logout={triggerLogout}
                                updateConfig={updateConfig}
                                initRegion={
                                    platform === Platfrom.TENCENT ? tencentAuthInfo?.region! : authInfo?.region!
                                }
                                initStage={platform === Platfrom.TENCENT ? tencentAuthInfo?.stage! : authInfo?.stage!}
                            />
                        )}
                    </div>
                )}
            </div>
        </IntlProvider>
    );
};
