<script setup lang="ts">
import { onBeforeUnmount, onMounted, watch } from "vue";
import { useRoute } from "vue-router";
import { motion } from "motion-v";
import { deleteUserCache } from "@hooks/useCache";
import { manualLogoutKey, reloginCancelKey } from "@/config/axios/service";
import { removeToken, getAccessToken } from "@/utils/auth";
import { useUserStore } from "@/stores/useUserStore";

const route = useRoute();
const userStore = useUserStore();

const IDLE_TIMEOUT = 30 * 60 * 1000;
const activityEvents = [
  "click",
  "mousemove",
  "keydown",
  "scroll",
  "touchstart",
];

let idleTimer: number | null = null;

const isLoginPage = () => route.path === "/login";

const clearIdleTimer = () => {
  if (idleTimer) {
    window.clearTimeout(idleTimer);
    idleTimer = null;
  }
};

const logoutByIdle = () => {
  clearIdleTimer();

  if (!getAccessToken() || isLoginPage()) {
    return;
  }

  deleteUserCache();
  userStore.resetState();
  sessionStorage.setItem(manualLogoutKey, "true");
  sessionStorage.removeItem(reloginCancelKey);
  removeToken();
  const ua = window.navigator.userAgent.toLowerCase();
  const logoutRedirect =
    ua.includes("dingtalk") || ua.includes("dingtalkwork") ? "/" : "/login";
  window.location.href = logoutRedirect;
};

const resetIdleTimer = () => {
  clearIdleTimer();

  if (!getAccessToken() || isLoginPage()) {
    return;
  }

  idleTimer = window.setTimeout(() => {
    logoutByIdle();
  }, IDLE_TIMEOUT);
};

const handleUserActivity = () => {
  resetIdleTimer();
};

onMounted(() => {
  activityEvents.forEach((eventName) => {
    window.addEventListener(eventName, handleUserActivity, true);
  });

  watch(
    () => route.path,
    () => {
      resetIdleTimer();
    },
    { immediate: true },
  );
});

onBeforeUnmount(() => {
  clearIdleTimer();
  activityEvents.forEach((eventName) => {
    window.removeEventListener(eventName, handleUserActivity, true);
  });
});
</script>

<template>
  <motion.div
    class="overflow-x-hidden font-sans app-shell"
    :key="$route.fullPath"
    :initial="{ opacity: 0 }"
    :animate="{ opacity: 1, transition: { duration: 0.5, ease: 'easeOut' } }"
  >
    <router-view></router-view>
  </motion.div>
</template>

<style scoped></style>
