import React, { memo } from 'react';
import { useHistory, useLocation } from 'react-router-dom';
import { Base64 } from 'js-base64';
import qs from 'qs';
import classNames from 'classnames';
import useLang from '@Hooks/useLang';
import useMessage from '@Hooks/useMessage';
import usaDidMount from '@Hooks/useDidMount';
import useReduxApi from '@Hooks/useReduxApi';
import Loading from '@Components/Base/Loading';
import { UserOAuthResponse, OAuthResult, APIError } from './types';
import Styles from './index.module.css';

function OAuth(): React.ReactElement {
  /* Global & Local State */
  const { i18n } = useLang();
  const reduxMessage = useMessage();
  const reduxUser = useReduxApi('user');
  const routeHistory = useHistory();
  const routeLocation = useLocation();
  /* Functions */
  const onOAuthSuccess = (token: string): void => {
    reduxUser('postUserTokenInfoSignIn', [token]);
  };
  const onOAuthFailed = (error: APIError): void => {
    reduxMessage.error(error);
    routeHistory.push('/');
  };
  const parseQuery = (base64String: string): OAuthResult => {
    const result = Base64.decode(base64String);
    const json: OAuthResult = JSON.parse(result);
    return json;
  };
  const validateByType = (query: UserOAuthResponse): void => {
    if (Object.keys(query).length > 0) {
      if (query.error) {
        const parseResult = parseQuery(query.error);
        const error: APIError = {
          code: parseResult.code,
          message: parseResult.message,
          errorStack: parseResult.errorStack,
          errorMessage: parseResult.errorMessage,
        };
        onOAuthFailed(error);
        return;
      }
      if (query.success) {
        const parseResult = parseQuery(query.success);
        onOAuthSuccess(parseResult.token);
      }
    }
  };
  const initialize = async (): Promise<void> => {
    const resultQuery: UserOAuthResponse = qs.parse(routeLocation.search, {
      ignoreQueryPrefix: true,
    });
    if (Object.keys(resultQuery).length > 0) {
      validateByType(resultQuery);
    } else {
      routeHistory.push('/');
    }
  };
  /* Hooks */
  usaDidMount(() => {
    initialize();
  });
  /* Main */
  return (
    <div className={classNames(Styles.oAuthContainer)}>
      <Loading
        typeIcon="basic"
        typePosition="absolute"
        typeBackground="white"
        isLoading
        text={i18n.t('frontend.global.property.validate')}
      />
    </div>
  );
}
export default memo(OAuth);
