import axios from 'axios'
import errorCode from './errorCode'
import { Notification, MessageBox, Message } from 'element-ui'
import loadingManager from './loadingManager';
import  errorNotificationManager from './errorNotificationManager';

  
const pendingRequestMap = new Map(); //处理Request aborted 错误

function getRequestKey(config) { //处理Request aborted 错误  生成唯一 key 的函数
  const { url, method, params, data } = config;
  return [url, method, JSON.stringify(params), JSON.stringify(data)].join('&');
}
// 创建axios实例
const service = axios.create({
  // axios中请求配置有baseURL选项，表示请求URL公共部分
  baseURL: process.env.VUE_APP_BASE_API,
  // 超时
  timeout: 10000,
})

// 网络错误相关配置
const NETWORK_ERROR_THROTTLE_TIME = 5000; // 错误提示节流时间
const RETRY_DELAY = 2000;                 // 重试间隔时间
const MAX_RETRY_TIMES = 3;                // 最大重试次数
const RETRY_WINDOW = 60000;               // 60秒重试窗口
let lastNetworkErrorTime = 0; // 上次网络错误提示时间
let pendingRequests = new Map();


// 网络状态监听器
// 网络状态最后提示时间
let lastNetworkStatusTime = {
  online: 0,
  offline: 0
};

// 创建一个全局标志，确保每次网络恢复只显示一次提示
let networkRecoveryInProgress = false;

// 网络状态监听器
window.addEventListener('online', () => {
  const now = Date.now();
  
  // 避免短时间内多次触发
  if (networkRecoveryInProgress) {
    console.log('[网络] 网络恢复处理已在进行中，忽略重复事件');
    return;
  }
  
  networkRecoveryInProgress = true;
  
  // 严格检查是否应该显示提示
  if (now - lastNetworkStatusTime.online > 30000) { // 30秒内不重复提示
    lastNetworkStatusTime.online = now;
    
    try {
      if (window.vm && window.vm.$message) {
        // 确保消息只显示一次
        window.vm.$message({
          message: window.vm.$i18n.t('home.networkReconnected') || '网络已重新连接，正在恢复数据...',
          type: 'success',
          duration: 5000,
          showClose: true,
        });
        console.log('[网络] 显示网络恢复提示, 时间:', new Date().toLocaleTimeString());
      }
    } catch (e) {
      console.error('[网络] 显示网络恢复提示失败:', e);
    }
  } else {
    console.log('[网络] 抑制重复的网络恢复提示, 间隔过短:', now - lastNetworkStatusTime.online + 'ms');
  }

  // 网络恢复时，重试所有待处理的请求
  const pendingPromises = [];
  
  pendingRequests.forEach(async (request, key) => {
    if (now - request.timestamp <= RETRY_WINDOW) {
      try {
        // 获取新的响应数据
        const response = await service(request.config);
        pendingPromises.push(response);
        
        // 执行请求特定的回调
        if (request.callback && typeof request.callback === 'function') {
          request.callback(response);
        }
        
        // 处理特定类型的请求
        if (window.vm) {
          // 处理图表数据请求
          if (request.config.url.includes('getPoolPower') && response && response.data) {
            // 触发图表更新事件
            window.dispatchEvent(new CustomEvent('chart-data-updated', { 
              detail: { type: 'poolPower', data: response.data } 
            }));
          }
          else if (request.config.url.includes('getNetPower') && response && response.data) {
            window.dispatchEvent(new CustomEvent('chart-data-updated', { 
              detail: { type: 'netPower', data: response.data } 
            }));
          }
          else if (request.config.url.includes('getBlockInfo') && response && response.rows) {
            window.dispatchEvent(new CustomEvent('chart-data-updated', { 
              detail: { type: 'blockInfo', data: response.rows } 
            }));
          }
        }
        
        pendingRequests.delete(key);
      } catch (error) {
        console.error('重试请求失败:', error);
        pendingRequests.delete(key);
      }
    } else {
      pendingRequests.delete(key);
    }
  });
  
  // 等待所有请求完成
  Promise.allSettled(pendingPromises).then(() => {
    // 重置所有 loading 状态
    if (loadingManager) {
      loadingManager.resetAllLoadingStates();
    }
    
    // 手动重置一些关键的 loading 状态
    if (window.vm) {
      // 常见的加载状态
      const commonLoadingProps = [
        'minerChartLoading', 'reportBlockLoading', 'apiPageLoading', 
        'MiningLoading', 'miniLoading', 'bthLoading', 'editLoading'
      ];
      
      commonLoadingProps.forEach(prop => {
        if (typeof window.vm[prop] !== 'undefined') {
          window.vm[prop] = false;
        }
      });

      // 重置所有以Loading结尾的状态
      Object.keys(window.vm).forEach(key => {
        if (key.endsWith('Loading')) {
          window.vm[key] = false;
        }
      });


    }
    
    // 触发网络重试完成事件
    window.dispatchEvent(new CustomEvent('network-retry-complete'));
    
    // 重置网络恢复标志
    setTimeout(() => {
      networkRecoveryInProgress = false;
    }, 5000); // 5秒后允许再次处理网络恢复
  });
});

 // 使用错误提示管理器控制网络断开提示
window.addEventListener('offline', () => {
  if (window.vm && window.vm.$message && errorNotificationManager.canShowError('networkOffline')) {
    window.vm.$message({
      message: window.vm.$i18n.t('home.networkOffline') || '网络连接已断开，系统将在恢复连接后自动重试',
      type: 'error',
      duration: 5000,
      showClose: true,
    });
  }
});

service.defaults.retry = 2;// 重试次数
service.defaults.retryDelay = 2000;
service.defaults.shouldRetry = (error) => {
  // 只有网络错误或超时错误才进行重试
  return error.message === "Network Error" || error.message.includes("timeout");
};

localStorage.setItem('superReportError', "")
let superReportError = localStorage.getItem('superReportError')
window.addEventListener("setItem", () => {
  superReportError = localStorage.getItem('superReportError')
});

// request拦截器
service.interceptors.request.use(config => {
  superReportError = ""
  // retryCount =0
  localStorage.setItem('superReportError', "")
  // 是否需要设置 token
  let token
  try {
    token = JSON.parse(localStorage.getItem('token'))
  } catch (e) {
    console.log(e);
  }
  if (token) {
    config.headers['Authorization'] = token
  }

console.log(token,"if就覅飞机飞机");

  if (config.method == 'get' && config.data) {
    config.params = config.data
  }
  // get请求映射params参数
  if (config.method === 'get' && config.params) {
    let url = config.url + '?';
    for (const propName of Object.keys(config.params)) {
      const value = config.params[propName];
      var part = encodeURIComponent(propName) + "=";
      if (value !== null && typeof (value) !== "undefined") {
        if (typeof value === 'object') {
          for (const key of Object.keys(value)) {
            if (value[key] !== null && typeof (value[key]) !== 'undefined') {
              let params = propName + '[' + key + ']';
              let subPart = encodeURIComponent(params) + '=';
              url += subPart + encodeURIComponent(value[key]) + '&';
            }
          }
        } else {
          url += part + encodeURIComponent(value) + "&";
        }
      }
    }
    url = url.slice(0, -1);
    config.params = {};
    config.url = url;
  }

  // 生成请求唯一key  处理Request aborted 错误
  const requestKey = getRequestKey(config);

  // 如果有相同请求，先取消  处理Request aborted 错误
  if (pendingRequestMap.has(requestKey)) {
    const cancel = pendingRequestMap.get(requestKey);
    cancel(); // 取消上一次请求
    pendingRequestMap.delete(requestKey);
  }

  // 创建新的CancelToken 处理Request aborted 错误
  config.cancelToken = new axios.CancelToken(cancel => {
    pendingRequestMap.set(requestKey, cancel);
  });

  return config
}, error => {
  Promise.reject(error)
})

// 响应拦截器
service.interceptors.response.use(res => {

    // 请求完成后移除
    const requestKey = getRequestKey(res.config);
    pendingRequestMap.delete(requestKey);
  
  // 特殊处理：如果是 blob 类型响应（文件下载），直接返回原始响应对象
  // 因为 blob 数据不是 JSON，不能解析 res.data.code
  if (res.config.responseType === 'blob' || res.data instanceof Blob) {
    // 检查响应状态码
    if (res.status >= 200 && res.status < 300) {
      return res // 返回完整响应对象，包含 headers 等信息
    } else {
      // blob 响应但状态码异常，尝试读取错误信息
      return Promise.reject(new Error(`下载失败，状态码: ${res.status}`))
    }
  }
  
  // 未设置状态码则默认成功状态
  const code = res.data.code || 200;
  // 获取错误信息
  const msg = errorCode[code] || res.data.msg || errorCode['default']
  if (code === 421) {
    localStorage.setItem('cs_disconnect_all', Date.now().toString()); //告知客服页面断开连接
    localStorage.removeItem('token')
    // 系统状态已过期，请重新点击SUPPORT按钮进入  
    superReportError = localStorage.getItem('superReportError')
    if (!superReportError) {
      superReportError = 421
      localStorage.setItem('superReportError', superReportError)
      MessageBox.confirm(window.vm.$i18n.t(`user.loginExpired`), window.vm.$i18n.t(`user.overduePrompt`), {
        distinguishCancelAndClose: true,
        confirmButtonText: window.vm.$i18n.t(`user.login`),
        cancelButtonText: window.vm.$i18n.t(`user.Home`),
        // showCancelButton: false, // 隐藏取消按钮
        closeOnClickModal: false, // 点击空白处不关闭对话框
        showClose: false, // 隐藏关闭按钮
        type: 'warning'
      }
      ).then(() => {
        window.vm.$router.push(`/${window.vm.$i18n.locale}/login`)
        localStorage.removeItem('token')
      }).catch(() => {
        window.vm.$router.push(`/${window.vm.$i18n.locale}/`)
        localStorage.removeItem('token')
      });

    }


    return Promise.reject('登录状态已过期')
  } else if (code >= 500 && !superReportError) {
    superReportError = 500
    localStorage.setItem('superReportError', superReportError)
    Message({
      dangerouslyUseHTMLString: true,
      message: msg,
      type: 'error',
      showClose: true
    })
    // throw msg; // 抛出错误，中断请求链并触发后续的错误处理逻辑
    // return Promise.reject(new Error(msg))
  } else if (code !== 200) {



    Notification.error({
      title: msg
    })
    return Promise.reject('error')

  } else {

    return res.data
  }




},
  error => {

     // 主动取消的请求，直接忽略，不提示
    if (
      error.code === 'ERR_CANCELED' ||
      (error.message && error.message.includes('canceled')) ||
      error.message?.includes('Request aborted')
    ) {
      // 静默处理，不提示，不冒泡
      return new Promise(() => {}); // 返回pending Promise，阻止控制台报错
    }



    
  // 请求异常也要移除  处理Request aborted 错误
  if (error.config) {
    const requestKey = getRequestKey(error.config);
    pendingRequestMap.delete(requestKey);
  }


    let { message } = error;
    if (message == "Network Error" || message.includes("timeout")) {
      if (!navigator.onLine) {
        // 断网状态，添加到重试队列
        const requestKey = JSON.stringify({
          url: error.config.url,
          method: error.config.method,
          params: error.config.params,
          data: error.config.data
        });
  
        // 根据URL确定请求类型并记录回调
        let callback = null;
        if (error.config.url.includes('getPoolPower')) {
          callback = (data) => {
            if (window.vm) {
              // 清除loading状态
              window.vm.minerChartLoading = false;
            }
          };
        } else if (error.config.url.includes('getBlockInfo')) {
          callback = (data) => {
            if (window.vm) {
              window.vm.reportBlockLoading = false;
            }
          };
        }
  
        if (!pendingRequests.has(requestKey)) {
          pendingRequests.set(requestKey, {
            config: error.config,
            timestamp: Date.now(),
            retryCount: 0,
            callback: callback
          });
  
          console.log('请求已加入断网重连队列:', error.config.url);
        }
      } else {
        // 网络已连接，但请求失败，尝试重试
        // 确保 config 中有 __retryCount 字段
        error.config.__retryCount = error.config.__retryCount || 0;
        
        // 判断是否可以重试
        if (error.config.__retryCount < service.defaults.retry && service.defaults.shouldRetry(error)) {
          // 增加重试计数
          error.config.__retryCount += 1;
          
          console.log(`[请求重试] ${error.config.url} - 第 ${error.config.__retryCount} 次重试`);
          
          // 创建新的Promise等待一段时间后重试
          return new Promise(resolve => {
            setTimeout(() => {
              resolve(service(error.config));
            }, service.defaults.retryDelay);
          });
        }
        
        // 达到最大重试次数，不再重试
        console.log(`[请求失败] ${error.config.url} - 已达到最大重试次数`);
      }
    }

    if (!superReportError) {
      superReportError = "error"
      localStorage.setItem('superReportError', superReportError)
      //使用错误提示管理器errorNotificationManager
      if (errorNotificationManager.canShowError(message)) {
        if (message == "Network Error") {
          Message({
            message: window.vm.$i18n.t(`home.NetworkError`),
            type: 'error',
            duration: 4 * 1000,
            showClose: true
          });
        }
        else if (message.includes("timeout")) {
          Message({
            message: window.vm.$i18n.t(`home.requestTimeout`),
            type: 'error',
            duration: 5 * 1000,
            showClose: true
          });
        }
        else if (message.includes("Request failed with status code")) {
          Message({
            message: "系统接口" + message.substr(message.length - 3) + "异常",
            type: 'error',
            duration: 5 * 1000,
            showClose: true
          });
        } else {
          Message({
            message: message,
            type: 'error',
            duration: 5 * 1000,
            showClose: true
          });
        }
      } else {
        // 避免完全不提示，可以在控制台记录被抑制的错误
        console.log('[错误提示] 已抑制重复错误:', message);
      }
    }




    return Promise.reject(error)

  }
)



export default service