/**
 * @file axios-middleware.js
 * @description 该模块为 Axios 提供设置全局请求和响应拦截器的工具。
 * 主要功能包括：
 * - 缓存机制：减少重复请求，提高性能；
 * - 错误处理：包括业务逻辑错误和网络错误的统一处理；
 * - 基于令牌的身份验证：在请求中自动附加身份验证信息。
 * @author inupedia
 */

import axios from 'axios';
import { useAuthStore } from '@/stores/authStore';

let vueRouter;

let globalReqInterceptor = null;
let globalRespInterceptor = null;

const TTL_CACHE_PERIOD = 500; // 默认0.5秒

const requestCache = new Map();

const generateCacheKey = (config) => {
  const base = config.url;
  if (config.method === 'post') {
    return `${base}-${JSON.stringify(config.data)}`;
  } else if (config.method === 'get' && config.params) {
    return `${base}-${JSON.stringify(config.params)}`;
  }
  return base;
};

const setCache = (key, data, ttl = TTL_CACHE_PERIOD) => {
  const existingCache = requestCache.get(key);

  if (existingCache && existingCache.expiry > Date.now()) {
    return;
  }

  const expiry = Date.now() + ttl;
  requestCache.set(key, { data, expiry });
};

const getCache = (key) => {
  const cached = requestCache.get(key);
  if (cached && cached.expiry > Date.now()) {
    return cached.data;
  }
  requestCache.delete(key);
  return null;
};

const extractApiPath = (url) => {
  const match = url.match(/\/v2\/(.*)/);
  return match ? match[1] : 'Unknown API';
};

const handleBusinessError = (response) => {
  if (response.data.code === 0) {
    const apiPath = extractApiPath(response.config.url);
    if (process.env.NODE_ENV === 'development') {
      alert(`接口错误: ${apiPath}`);
    }
  }
};

const handleError = (error) => {
  if (window == undefined) {
    //console.error('代码在非浏览器环境中运行，无法访问 window 对象');
    alert('浏览器版本过低，请升级浏览器后访问');
    return Promise.reject(new Error('浏览器版本过低，请升级浏览器后访问'));
  }
  if (!error?.response || error.isOffline || error.code == 'ERR_NETWORK') {
    //alert('网络错误');
    return Promise.reject(new Error('网络错误'));
  }
  const authStore = useAuthStore();
  if (error.response?.status == 401 && !window.hasShownUnauthorizedAlert) {
    alert('您的登录信息已过期，请重新登录');
    authStore.clearToken();
    window.hasShownUnauthorizedAlert = true; // 设置标志为true，表示已经弹出过提示
    vueRouter.push('/login');
  } else if (error.response?.status == 403) {
    alert('您没有权限访问该资源');
  } else if (error.response?.status == 500) {
    //alert('服务器内部错误');
  } else if (error.response?.status == 400) {
    const errorMessage = error.response.data?.message || '参数错误';
    alert(errorMessage);
  }
  return Promise.reject(error);
};

const checkOnlineStatus = () => {
  return navigator.onLine;
};

const setXTokenInterceptor = (token) => {
  // 移除已存在的拦截器
  if (globalReqInterceptor !== null) {
    axios.interceptors.request.eject(globalReqInterceptor);
  }
  if (globalRespInterceptor !== null) {
    axios.interceptors.response.eject(globalRespInterceptor);
  }

  // 设置新的请求拦截器
  globalReqInterceptor = axios.interceptors.request.use(
    (config) => {
      if (!checkOnlineStatus()) {
        return Promise.reject(new Error('网络连接不可用，请检查您的网络设置'));
      }

      if (!token) {
        return config;
      }

      config.headers['X-APP-ID'] = 'selectsys';
      config.headers['X-TOKEN'] = token;

      const cacheKey = generateCacheKey(config);
      const cachedData = getCache(cacheKey);

      if (cachedData && config.method.toLowerCase() === 'get') {
        config.adapter = () =>
          Promise.resolve({
            data: cachedData.data,
            status: cachedData.status,
            statusText: cachedData.statusText,
            headers: cachedData.headers,
            config,
            request: cachedData.request,
          });
      }

      return config;
    },
    (error) => handleError(error)
  );

  // 设置新的响应拦截器
  globalRespInterceptor = axios.interceptors.response.use(
    (response) => {
      //handleBusinessError(response);

      // 只缓存GET请求的响应数据
      if (response.config.method.toLowerCase() === 'get') {
        const cacheKey = generateCacheKey(response.config);
        setCache(cacheKey, {
          data: response.data,
          status: response.status,
          statusText: response.statusText,
          headers: response.headers,
          config: response.config,
          request: response.request,
        });
      }

      return response;
    },
    (error) => handleError(error)
  );
};

export const setInterceptorVueRouter = (router) => {
  if (router) {
    console.log('拦截器router设置成功');
    vueRouter = router;
  } else {
    console.warn('拦截器router设置失败，自动跳转功能不可用');
  }
};

export const initAxiosInterceptors = (token) => {
  if (token) {
    console.log('拦截器token设置成功');
    setXTokenInterceptor(token);
  }
  window.hasShownUnauthorizedAlert = false;
};
