import React, { useCallback } from "react";
import { AppDispatch } from "app/store";
import { decodeToken } from "common/decodeToken";
import { useInterval } from "common/useInterval";
import {
  updateTokenAsync,
  loadAccessToken,
  updateDelegationTokenAsync,
} from "features/auth";
import { DateTime } from "luxon";
import { useDispatch, useSelector } from "react-redux";
import { selectDelegationAccessToken } from "features/auth/selectors";
import { useNavigate } from "react-router-dom";
import { cleanupDelegateAccount } from "features/partner";
import { TOKEN_UPDATE_INTERVAL_MS, TOKEN_UPDATE_TIME } from "./constants";

export const UpdateTokenTimer = () => {
  const dispatch: AppDispatch = useDispatch();
  const navigate = useNavigate();

  const delegattionToken = useSelector(selectDelegationAccessToken);

  // 期限が５分以内であれば更新APIを呼ぶ
  const updateToken = useCallback(async () => {
    // localStorageからトークンを取得
    const jwt = loadAccessToken();
    // 現在時刻を取得
    const now = DateTime.local().toSeconds();
    // selectorに以下の判定処理を移したかったが、初期表示時の値でしか判定できないのでComponent内に置く
    if (jwt) {
      const token = decodeToken(jwt);
      if (token) {
        const { exp } = token;
        if (exp - now <= TOKEN_UPDATE_TIME) {
          await dispatch(updateTokenAsync());
        }
      }
    }

    // 代行操作トークン更新処理
    if (delegattionToken) {
      const token = decodeToken(delegattionToken);
      if (token) {
        const { exp } = token;
        if (exp - now <= TOKEN_UPDATE_TIME) {
          const { meta } = await dispatch(updateDelegationTokenAsync());
          if (meta.requestStatus === "rejected") {
            dispatch(cleanupDelegateAccount());
            navigate("/partners");
          }
        }
      }
    }
  }, [dispatch, delegattionToken, navigate]);

  useInterval(updateToken, TOKEN_UPDATE_INTERVAL_MS);

  // eslint-disable-next-line react/jsx-no-useless-fragment
  return <></>;
};
