import {
  reconcileStaffSessionFromToken,
  useAuthStore,
  type StaffUser,
  type StaffUserType,
} from '../stores/auth';

let hydratePromise: Promise<boolean> | null = null;
let lastHydrateAt = 0;

/** 跨路由复用 /me 结果，减少菜单切换时的重复鉴权请求 */
const HYDRATE_TTL_MS = 60_000;

function isStaffUserType(value: unknown): value is StaffUserType {
  return value === 'ADMIN' || value === 'AGENT';
}

export function resetStaffSessionHydration() {
  hydratePromise = null;
  lastHydrateAt = 0;
}

/** 同步判断 session 是否已经新鲜，无需网络请求。主要给 router beforeEach 使用。 */
export function isSessionFresh(): boolean {
  const auth = useAuthStore();
  if (!auth.token.value) return false;
  return (
    lastHydrateAt > 0 &&
    Date.now() - lastHydrateAt < HYDRATE_TTL_MS &&
    hasCompleteStaffUser(auth.user.value)
  );
}

function hasCompleteStaffUser(u: StaffUser | null | undefined): u is StaffUser {
  return !!(u?.id && u.username && u.userType);
}

/** Sync manage_user from JWT + /manage/auth/me (fixes stale localStorage userType). */
export async function hydrateStaffSession(): Promise<boolean> {
  const auth = useAuthStore();
  if (!auth.token.value) return false;

  const freshEnough =
    lastHydrateAt > 0 &&
    Date.now() - lastHydrateAt < HYDRATE_TTL_MS &&
    hasCompleteStaffUser(auth.user.value);
  if (freshEnough) return true;

  if (hydratePromise) return hydratePromise;

  hydratePromise = (async () => {
    reconcileStaffSessionFromToken();

    if (!hasCompleteStaffUser(auth.user.value)) {
      auth.clearStaffSession();
      return false;
    }

    try {
      const { default: api } = await import('../api');
      const { data } = await api.get('/manage/auth/me');
      const raw = data.data as Partial<StaffUser>;
      if (!raw?.id || !raw.username || !isStaffUserType(raw.userType)) {
        return true;
      }
      auth.setSession(auth.token.value, {
        id: raw.id,
        username: raw.username,
        userType: raw.userType,
        locale: raw.locale,
        role: raw.role,
        permissions: Array.isArray(raw.permissions) ? raw.permissions : auth.user.value?.permissions,
        agentLevel: typeof raw.agentLevel === 'number' ? raw.agentLevel : null,
        maxAgentLevel: typeof raw.maxAgentLevel === 'number' ? raw.maxAgentLevel : null,
        canManageSubAgents: raw.canManageSubAgents === true,
        inviteCode: raw.inviteCode ?? null,
        visibleMenus: raw.visibleMenus ?? null,
      });
      lastHydrateAt = Date.now();
      return true;
    } catch (e: unknown) {
      const status = (e as { response?: { status?: number } })?.response?.status;
      if (status === 401) {
        auth.clearStaffSession();
        return false;
      }
      return hasCompleteStaffUser(auth.user.value);
    } finally {
      hydratePromise = null;
    }
  })();

  return hydratePromise;
}

/** Run before any authenticated route — JWT reconcile + optional /me refresh. */
export async function ensureStaffSession(): Promise<boolean> {
  reconcileStaffSessionFromToken();
  const auth = useAuthStore();
  if (!auth.token.value) return false;
  if (!hasCompleteStaffUser(auth.user.value)) {
    reconcileStaffSessionFromToken();
  }
  if (!hasCompleteStaffUser(auth.user.value)) {
    return false;
  }
  return hydrateStaffSession();
}
