console.log("FC: Init script");

document.addEventListener("readystatechange", () => {
  if (document.readyState === "complete") {
    SetupFcHooks();
  }
});

const FRESHCHAT_KEY = {
  HAS_ACTIVE_SESSION: "FRESHCHAT_HAS_ACTIVE_SESSION",
  CLEAR_SESSION_AT: "FRESHCHAT_CLEAR_SESSION_AT",
  SESSION_ONLINE_ID: "FRESHCHAT_SESSION_ONLINE_ID",
};

function SetupFcHooks() {
  window.fcSettings = {
    onInit: function () {
      InitWidget();
    },
  };

  async function Sleep(seconds) {
    await new Promise((r) => setTimeout(r, seconds * 1000));
  }

  async function InitWidget() {
    console.log("FC: Init widget");

    let isWidgetInitialized = false;
    let initWidgetAttempt = 0;
    while (isWidgetInitialized === false && initWidgetAttempt < 10) {
      initWidgetAttempt++;

      try {
        window.fwcrm.on("widget:loaded", async function () {
          await ClearInactiveSession();

          await UpdateSession();

          // Hook when message from bot is received.
          window.fcWidget.on("message:received", async function (data) {
            console.log("Message received", data);

            window.localStorage.setItem(
              FRESHCHAT_KEY.CLEAR_SESSION_AT,
              new Date(Date.now() + 10 * 60 * 1000)
            );

            Sleep(600).then(() => {
              ClearInactiveSession();
            });
          });

          // Hook when user sends message.
          window.fcWidget.on("message:sent", function (data) {
            console.log("Message sent", data);

            window.localStorage.removeItem(FRESHCHAT_KEY.CLEAR_SESSION_AT);
            window.localStorage.setItem(FRESHCHAT_KEY.HAS_ACTIVE_SESSION, true);
          });
        });

        isWidgetInitialized = true;
      } catch (err) {
        console.error("FC: Init widget error #" + initWidgetAttempt, err);
        await Sleep(1);
      }
    }
  }

  async function UpdateSession() {
    console.log("FC: Update session");

    const hasActiveSession = window.localStorage.getItem(
      FRESHCHAT_KEY.HAS_ACTIVE_SESSION
    );
    const userOnlineId = window.localStorage.getItem(
      FRESHCHAT_KEY.SESSION_ONLINE_ID
    );
    const onlineId = document.body.dataset.onlineId;
    const partnerId = onlineId || null;

    if (!hasActiveSession || userOnlineId !== partnerId) {
      const userData = {
        firstName: "GUEST_USER",
        lastName: websiteName,
        meta: { cf_partner_id: partnerId, cf_platform_source: "BROWSER" },
      };

      let isUserUpdated = false;
      let updateUserAttempt = 0;
      while (isUserUpdated === false && updateUserAttempt < 10) {
        updateUserAttempt++;

        try {
          await window.fcWidget.user.update(userData).then(
            async () => {
              console.log("FC: User updated");
            },
            async () => {
              await window.fcWidget.user.create(userData);

              console.log("FC: User created");
            }
          );

          isUserUpdated = true;
          window.localStorage.setItem(FRESHCHAT_KEY.HAS_ACTIVE_SESSION, true);
          if (partnerId) {
            window.localStorage.setItem(
              FRESHCHAT_KEY.SESSION_ONLINE_ID,
              partnerId
            );
          }
        } catch (err) {
          console.error("FC: Update user error #" + updateUserAttempt, err);
          await Sleep(1);
        }
      }
    }
  }

  function IsSessionInactive() {
    const hasOngoingSession = !!window.localStorage.getItem(
      FRESHCHAT_KEY.HAS_ACTIVE_SESSION
    );

    const expiryTime = window.localStorage.getItem(
      FRESHCHAT_KEY.CLEAR_SESSION_AT
    );
    const isPastExpiryTime = !!(
      expiryTime && new Date() >= new Date(expiryTime)
    );

    const userOnlineId = window.localStorage.getItem(
      FRESHCHAT_KEY.SESSION_ONLINE_ID
    );
    const onlineId = document.body.dataset.onlineId;
    const partnerId = onlineId || null;
    const hasLoggedOut = partnerId === null && userOnlineId !== partnerId;

    return hasOngoingSession && (isPastExpiryTime || hasLoggedOut);
  }

  async function ClearInactiveSession() {
    if (IsSessionInactive()) {
      await ClearSession();
    }
  }

  async function ClearSession(shouldResetSession = true) {
    console.log("FC: Clear session");

    let isUserCleared = false;
    let userClearAttempt = 0;
    while (isUserCleared === false && userClearAttempt < 10) {
      userClearAttempt++;
      try {
        await window.fcWidget.user.clear().then(async () => {
          isUserCleared = true;

          await window.fcWidget.close();
          window.localStorage.removeItem(FRESHCHAT_KEY.HAS_ACTIVE_SESSION);
          window.localStorage.removeItem(FRESHCHAT_KEY.SESSION_ONLINE_ID);
          window.localStorage.removeItem(FRESHCHAT_KEY.CLEAR_SESSION_AT);
          if (shouldResetSession === true) {
            await UpdateSession();
          }
          await window.fcWidget.open();

          console.log("FC: Cleared user data!");
        });
      } catch (err) {
        console.error("FC: Clear user error #" + userClearAttempt, err);
        await Sleep(1);
      }
    }
  }
}
