import { createApp } from "vue";
import ElementPlus from "element-plus";
import { ElMessage } from "element-plus";
import "element-plus/dist/index.css";
import "element-plus/theme-chalk/dark/css-vars.css";
import "./styles/variables.css";
import "./styles/theme.css";
import "./styles/utilities.css";
import App from "./App.vue";
import router from "./router";
import { pinia } from "./stores";
import { useAppearanceStore } from "./stores/appearance";
import { useAuthStore } from "./stores/auth";
import { logoutAuth } from "./api/modules";
import { resolveLoginPath } from "./utils/authNavigation";

const IDLE_TIMEOUT_MINUTES = Number(import.meta.env.VITE_IDLE_TIMEOUT_MINUTES || 60);
const IDLE_TIMEOUT_MS = (Number.isFinite(IDLE_TIMEOUT_MINUTES) && IDLE_TIMEOUT_MINUTES > 0 ? IDLE_TIMEOUT_MINUTES : 60) * 60 * 1000;
const IDLE_ACTIVITY_EVENTS = ["mousedown", "keydown", "scroll", "touchstart"] as const;
const PUBLIC_ENTRY_PATH_PATTERNS = [/^\/login$/, /^\/[^/]+\/login$/, /^\/[^/]+\/setup-password$/];

let idleTimer: number | null = null;
let lastActivityAt = Date.now();
let idleLogoutPending = false;
let previousAuthLoggedIn = false;

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

const scheduleIdleTimeout = () => {
  stopIdleTimer();
  const authStore = useAuthStore(pinia);
  if (!authStore.token) {
    previousAuthLoggedIn = false;
    return;
  }
  const elapsed = Date.now() - lastActivityAt;
  const delay = Math.max(0, IDLE_TIMEOUT_MS - elapsed);
  idleTimer = window.setTimeout(() => {
    void handleIdleTimeout();
  }, delay);
};

const markUserActivity = () => {
  const authStore = useAuthStore(pinia);
  if (!authStore.token) {
    stopIdleTimer();
    previousAuthLoggedIn = false;
    return;
  }
  lastActivityAt = Date.now();
  scheduleIdleTimeout();
};

async function handleIdleTimeout() {
  const authStore = useAuthStore(pinia);
  if (!authStore.token || idleLogoutPending) {
    return;
  }
  idleLogoutPending = true;
  const nextLoginPath = resolveLoginPath(authStore.scope, authStore.tenantCode);
  try {
    await logoutAuth();
  } catch (_error) {
    // ignore logout failure during idle cleanup
  }
  authStore.clearAuthStorage();
  window.location.href = nextLoginPath;
}

const handleAuthStateChanged = () => {
  const authStore = useAuthStore(pinia);
  const loggedIn = Boolean(authStore.token);
  if (!loggedIn) {
    stopIdleTimer();
    previousAuthLoggedIn = false;
    idleLogoutPending = false;
    return;
  }
  if (!previousAuthLoggedIn) {
    lastActivityAt = Date.now();
  }
  previousAuthLoggedIn = true;
  scheduleIdleTimeout();
};

const app = createApp(App);
app.use(pinia);
const appearanceStore = useAppearanceStore(pinia);
appearanceStore.initAppearance();

const isPublicEntryPath = (path: string) => PUBLIC_ENTRY_PATH_PATTERNS.some((pattern) => pattern.test(path));

// 全局错误边界：捕获未处理的组件异常，防止白屏
app.config.errorHandler = (err, _instance, info) => {
  console.error("[全局错误边界]", info, err);
  ElMessage.error("页面发生异常，请尝试刷新页面");
};

app.use(router).use(ElementPlus).mount("#app");

router.isReady().then(() => {
  if (isPublicEntryPath(router.currentRoute.value.path)) {
    appearanceStore.markBootstrapped();
  }
  appearanceStore.syncFromServer();
  for (const eventName of IDLE_ACTIVITY_EVENTS) {
    window.addEventListener(eventName, markUserActivity, { passive: true });
  }
  window.addEventListener("auth:token-updated", handleAuthStateChanged as EventListener);
  document.addEventListener("visibilitychange", () => {
    if (document.visibilityState === "visible") {
      markUserActivity();
    }
  });
  router.afterEach(() => {
    markUserActivity();
  });
  handleAuthStateChanged();
});
