<script setup lang="ts">
import { onLaunch, onShow, onHide } from "@dcloudio/uni-app";
import { API_CONFIG } from './utils/config';
import { handleUnauthorized, clearAuth } from './utils/auth';
import { logger } from './utils/logger';

/**
 * 应用启动
 * 登录状态检查采用非阻塞模式，避免网络延迟拖慢启动速度
 */
onLaunch((options: any) => {
  logger.log("App Launch, options:", JSON.stringify(options));
  checkLoginStatus(options);
});

/**
 * 应用显示
 */
onShow(() => {
  logger.log("App Show");
});

/**
 * 应用隐藏
 */
onHide(() => {
  logger.log("App Hide");

  // 当应用隐藏时，清理购物页面的轮询状态
  const pollingActive = uni.getStorageSync('shoppingPollingActive');
  if (pollingActive === 'true') {
    logger.log('应用隐藏，清理购物页面轮询状态');
    uni.removeStorageSync('shoppingPollingActive');
  }
});

/**
 * 免登录白名单页面
 * 这些页面允许未登录用户直接访问
 */
const LOGIN_WHITE_LIST = [
  'pages/login/login',
  'pages/products/products',
];

/**
 * 验证token是否有效
 * @returns 'valid' | 'invalid' | 'unknown'
 *   - valid: token确认有效
 *   - invalid: 后端明确返回401，token已失效
 *   - unknown: 网络异常/超时，无法确认（由后续API的401拦截兜底）
 */
const verifyToken = (): Promise<'valid' | 'invalid' | 'unknown'> => {
  return new Promise((resolve) => {
    const token = uni.getStorageSync('accessToken');
    if (!token) {
      resolve('invalid');
      return;
    }

    let settled = false;
    const done = (result: 'valid' | 'invalid' | 'unknown') => {
      if (!settled) {
        settled = true;
        resolve(result);
      }
    };

    const url = `${API_CONFIG.baseUrl}/login/user-info`;
    uni.request({
      url,
      method: 'POST',
      header: {
        'Content-Type': 'application/json',
        'accessToken': token
      },
      timeout: 5000,
      success: (res: any) => {
        if (res.statusCode === 200) {
          const data = res.data;
          if (data && (data.code === 200 || data.code === 0)) {
            done('valid');
          } else if (data && data.code === 401) {
            logger.log('[App] token无效:', data.message);
            done('invalid');
          } else {
            logger.warn('[App] 验证token返回异常状态:', data?.code, data?.message);
            done('unknown');
          }
        } else if (res.statusCode === 401) {
          logger.log('[App] HTTP 401, token无效');
          done('invalid');
        } else {
          logger.warn('[App] 验证token HTTP状态异常:', res.statusCode);
          done('unknown');
        }
      },
      fail: (err: any) => {
        logger.warn('[App] 验证token请求失败:', err.errMsg);
        done('unknown');
      }
    });

    setTimeout(() => {
      logger.warn('[App] 验证token超时');
      done('unknown');
    }, 3000);
  });
};

/**
 * 检查登录状态
 * 如果未登录或token无效且当前不在白名单页面，则跳转到登录页
 */
const checkLoginStatus = async (launchOptions?: any) => {
  const token = uni.getStorageSync('accessToken');

  // 优先从启动参数获取目标页面路径（onLaunch时getCurrentPages为空）
  let currentPath = launchOptions?.path || '';
  if (!currentPath) {
    const pages = getCurrentPages();
    const currentPage = pages[pages.length - 1];
    currentPath = currentPage ? currentPage.route : '';
  }

  logger.log('[App] 检查登录状态 - token:', token ? '已存在' : '不存在', ', 目标页面:', currentPath);

  const isWhiteListed = LOGIN_WHITE_LIST.some(path => currentPath.indexOf(path) !== -1);

  // 没有token
  if (!token) {
    if (!isWhiteListed) {
      logger.log('[App] 未登录，跳转到登录页');
      uni.reLaunch({ url: '/pages/login/login' });
    }
    return;
  }

  // 有token，向后端验证是否有效
  logger.log('[App] token存在，验证token有效性...');
  const verifyResult = await verifyToken();

  if (verifyResult === 'valid') {
    logger.log('[App] token有效');
  } else if (verifyResult === 'invalid') {
    // 后端明确返回401：token已失效，必须跳转登录
    if (!isWhiteListed) {
      logger.log('[App] token已失效，触发全局未授权处理');
      handleUnauthorized();
    } else {
      logger.log('[App] token已失效，清除登录数据（当前在白名单页面）');
      clearAuth();
    }
  } else {
    // unknown：网络异常或超时，不踢用户，交给后续API的401拦截处理
    logger.log('[App] token验证无法确认，保留token继续运行（由API请求401兜底）');
  }
};
</script>
<style>
/* 全局动画样式 */
@keyframes fadeIn { from { opacity: 0; } to { opacity: 1; } }
@keyframes slideUp { from { opacity: 0; transform: translateY(40rpx); } to { opacity: 1; transform: translateY(0); } }
@keyframes slideDown { from { opacity: 0; transform: translateY(-40rpx); } to { opacity: 1; transform: translateY(0); } }
@keyframes scaleIn { from { opacity: 0; transform: scale(0.9); } to { opacity: 1; transform: scale(1); } }
@keyframes pulse { 0%, 100% { transform: scale(1); opacity: 0.3; } 50% { transform: scale(1.05); opacity: 0.5; } }
@keyframes bounce { 0% { transform: scale(0); opacity: 0; } 50% { transform: scale(1.1); } 100% { transform: scale(1); opacity: 1; } }
@keyframes skeleton { 0%, 100% { background-color: #F5F5F5; } 50% { background-color: #EEEEEE; } }
</style>
