import { useMsal } from "@azure/msal-react";
import { AuthError } from "@azure/msal-browser";
import { AppDispatch } from "app/store";
import Footer from "components/footer";
import Header from "components/header";
import {
  selectLoginApiCallStatus,
  changeLocalStorageKeyforIdToken,
} from "features/login";
import React, { useEffect } from "react";
import { useDispatch, useSelector } from "react-redux";
import { useNavigate } from "react-router-dom";

const AuthPage: React.FC = (): JSX.Element => {
  const { instance } = useMsal();
  const dispatch: AppDispatch = useDispatch();
  const navigate = useNavigate();
  const status = useSelector(selectLoginApiCallStatus);

  // TODO 将来的にトークンの取得処理をoperations.ts側に移動させたい。useEffect内で非同期処理を行いたくない。
  useEffect(() => {
    if (status !== "none") {
      // ログイン処理で、何回か本画面が描画される契機があるが、認証処理は一度だけ実施すればよいため認証処理実行済みであれば何もしない
      return;
    }

    (async () => {
      try {
        const loginResult = await instance.handleRedirectPromise();

        // eslint-disable-next-line
        console.log({ loginResult }); // TODO:loading画面から遷移できない事象の調査用ログ。事象解消後削除（eslint-disable含めて）する。

        if (loginResult && loginResult.account) {
          const { homeAccountId, idTokenClaims } = loginResult.account;
          if (idTokenClaims && idTokenClaims.aud) {
            const localStorageKeyforIdToken = `${homeAccountId}-${
              import.meta.env.VITE_B2C_KNOWNAUTHORITIES
            }-idtoken-${idTokenClaims.aud}----`;

            // AADB2Cログイン画面以外から本画面に遷移した場合用にIDトークン取得用キーをstateに保存
            dispatch(
              changeLocalStorageKeyforIdToken({
                localStorageKeyforIdToken,
              })
            );

            // トークン取得と設定を行う
            navigate("/login");
          }
        }
      } catch (e) {
        // eslint-disable-next-line
        console.log({ e }); // TODO:loading画面から遷移できない事象の調査用ログ。事象解消後削除（eslint-disable含めて）する。

        // AAD B2Cの多要素認証画面やパスワードリセット画面で「cancel」をクリックすると、handleRedirectPromise()にてエラーが発生するため、
        // それをハンドリングして適切な画面遷移処理を行う。
        if (e instanceof AuthError) {
          // エラーコードはerrorMessageの中の一部として埋め込まれており完全一致で取得するのは筋が悪いため、部分一致で取得する。
          // TODO 他にもAADB2Cのエラーコードを使用する箇所が出てきた場合、定数化すること
          if (e.errorMessage.startsWith("AADB2C90091")) {
            navigate("/");
          }
        }
      }
    })();
  }, [instance, navigate, status, dispatch]);

  return (
    <>
      <Header />
      <h3>loading ...</h3>
      <Footer />
    </>
  );
};

export default AuthPage;
