import { updateBAEventParameters } from "@elliemae/pui-analytics-so";
import { browserHistory as history } from "../history.js";
import {
  getToken,
  revokeToken,
  introspectToken
} from "../../api/auth/index.js";
import { getUser } from "../../api/users/index.js";
import { loginEvent, logoutEvent } from "../../analytics/user-session-event.js";
import { lrIdentify, lrTrack } from "../logrocket.js";
import { getAuthorizationHeader, setAuthorizationHeader } from "./helper.js";
import { getAppConfigValue } from "../app-config/config.js";
import { logRecords } from "../log-records.js";
import { setLoginParams } from "./loginParams.js";
import { getLogger } from "../logger.js";
const IDP_ENDPOINT_CONFIG_KEY = "serviceEndpoints.idp";
const isUserAuthorized = () => !!getAuthorizationHeader();
const getIDPInfoFromUrl = () => {
  const currentUrl = new URL(window.location.href);
  const code = currentUrl.searchParams.get("code") || "";
  const idpErrorCode = currentUrl.searchParams.get("error_code") || "";
  currentUrl.search = "";
  return { code, idpErrorCode, redirectUri: currentUrl.href };
};
const navigateToLoginPage = ({
  clientId,
  redirectUri,
  idpErrorCode,
  scope,
  // eslint-disable-next-line camelcase
  responseType
}) => {
  const idpHost = getAppConfigValue(IDP_ENDPOINT_CONFIG_KEY, "");
  const idpUrl = new URL("/authorize", idpHost);
  const idpOptions = {
    client_id: clientId,
    redirect_uri: redirectUri,
    response_type: responseType,
    scope
  };
  const searchParams = new URLSearchParams(
    idpErrorCode ? Object.assign(idpOptions, { error_code: idpErrorCode }) : idpOptions
  );
  idpUrl.search = searchParams.toString();
  window.location.replace(idpUrl.href);
};
const endSession = async ({
  clientId,
  redirectUri,
  responseType,
  scope,
  code = "",
  skipRevoke = false
}) => {
  try {
    const authorization = getAuthorizationHeader();
    sessionStorage.clear();
    const token = authorization ? authorization.split(" ")[1] : "";
    if (!skipRevoke)
      await revokeToken({
        clientId,
        token
      });
    logoutEvent();
    lrTrack("logout");
    updateBAEventParameters({ instanceId: "", userId: "" });
    const idpHost = getAppConfigValue(IDP_ENDPOINT_CONFIG_KEY, "");
    const logoutUrl = new URL("/authorize", idpHost);
    const params = {
      client_id: clientId,
      redirect_uri: redirectUri || "",
      ...code && { error_code: code },
      response_type: responseType || "",
      scope
    };
    const searchParams = new URLSearchParams(params);
    logoutUrl.search = searchParams.toString();
    window.location.replace(logoutUrl.href);
  } catch (err) {
    getLogger()?.error({
      ...logRecords.LOGOUT_FAILED,
      exception: err
    });
  }
};
const authorize = async ({
  code,
  redirectUri,
  clientId,
  scope,
  responseType,
  isConsumerUser
}) => {
  try {
    const { tokenType, accessToken } = await getToken({
      code,
      clientId,
      scope,
      redirectUri
    });
    setLoginParams({ clientId, scope, responseType, redirectUri });
    const authorizationToken = `${tokenType} ${accessToken}`;
    setAuthorizationHeader(authorizationToken);
    const introspectResponse = await introspectToken({
      clientId,
      accessToken
    });
    sessionStorage.setItem("user", JSON.stringify(introspectResponse));
    const {
      encompass_instance_id: instanceId,
      user_name: userName,
      bearer_token: bearerToken,
      user_key: userKey
    } = introspectResponse;
    const cred = {
      bearerToken,
      realm: instanceId,
      userName,
      sessionId: bearerToken?.replace(`${instanceId} `, "")
    };
    sessionStorage.setItem("cred", JSON.stringify(cred));
    sessionStorage.setItem("instanceId", instanceId);
    sessionStorage.setItem("userId", userName);
    loginEvent({ instanceId, userId: userName });
    updateBAEventParameters({ instanceId, userId: userName });
    const eventData = {
      name: userName,
      instanceId
    };
    lrIdentify(userKey, eventData);
    lrTrack("login", eventData);
    const data = await getUser({ userName, isConsumerUser });
    sessionStorage.setItem("userSettings", JSON.stringify(data));
    const pathName = new URL(redirectUri).pathname;
    history.replace(pathName);
  } catch (err) {
    const errCode = err?.response?.data?.code;
    await endSession({
      clientId,
      redirectUri,
      code: errCode,
      scope,
      responseType
    });
    getLogger()?.error({
      ...logRecords.LOGIN_FAILED,
      exception: err
    });
  }
};
const login = async ({
  clientId,
  scope,
  responseType,
  isConsumerUser
}) => {
  const { code, idpErrorCode, redirectUri } = getIDPInfoFromUrl();
  const loginInfo = {
    clientId,
    scope,
    responseType,
    redirectUri,
    code,
    idpErrorCode,
    isConsumerUser
  };
  if (code) {
    await authorize(loginInfo);
    return { authorized: true };
  }
  navigateToLoginPage(loginInfo);
  return { authorized: false };
};
export {
  authorize,
  endSession,
  getIDPInfoFromUrl,
  isUserAuthorized,
  login,
  navigateToLoginPage
};
