/**
 * 网络请求工具类
 * 封装uni-app的request方法
 */

import errorHandler from './errorHandler.js';

// 基础URL，可以根据环境变量等动态设置
const BASE_URL = 'http://192.168.66.187:8083';

// 请求超时时间
const TIMEOUT = 60000;

// 请求拦截器
const requestInterceptor = (config) => {
  // 获取token
  const token = uni.getStorageSync('token');
  
  // 获取 CSRF token
  const csrfToken = uni.getStorageSync('csrfToken');
  
  // 设置请求头
  if (!config.header) {
    config.header = {};
  }
  
  // 添加token到请求头
  if (token) {
    config.header['Authorization'] = `Bearer ${token}`;
  }
  
  // 添加 CSRF token 到请求头
  if (csrfToken) {
    config.header['X-CSRF-Token'] = csrfToken;
  }
  
  // 添加内容类型
  if (!config.header['Content-Type']) {
    config.header['Content-Type'] = 'application/json';
  }
  
  // 添加基础URL
  if (!config.url.startsWith('http')) {
    config.url = BASE_URL + config.url;
  }
  
  // 如果是 POST 请求，也可以添加到请求体
  if (config.method === 'POST' && config.data) {
    config.data._csrf = csrfToken;
  }
  
  return config;
};

// 错误提示
const showError = (message, duration = 2000) => {
  // 避免重复显示相同的错误提示
  if (showError.lastMessage === message && Date.now() - showError.lastTime < 3000) {
    return;
  }
  
  uni.showToast({
    title: message,
    icon: 'none',
    duration: duration
  });
  
  // 记录最后显示的错误信息和时间
  showError.lastMessage = message;
  showError.lastTime = Date.now();
};

// 初始化错误提示状态
showError.lastMessage = '';
showError.lastTime = 0;

// 错误码映射表
const ERROR_CODE_MAP = {
  400: '请求参数错误',
  401: '登录已过期，请重新登录',
  403: '没有权限执行此操作',
  404: '请求的资源不存在',
  500: '服务器错误，请稍后重试',
  502: '网关错误',
  503: '服务不可用，请稍后重试',
  504: '网关超时'
};

// 响应拦截器
const responseInterceptor = (response) => {
  // 这里可以对响应数据做统一处理
  if (response.statusCode === 200) {
    // 服务器正常响应
    const { data } = response;
    
    // 检查是否有特定错误码
    if (data.status === 999 || data.code === 999) {
      // 微信 code 无效错误
      const error = new Error(data.message || '微信登录失败: code无效');
      error.status = 999;
      return Promise.reject(error);
    }
    // 处理成功响应 - 适配不同的返回格式
    if (data.status === 2000 || data.code === 0 || data.code === 2000) {
      // 如果返回的是完整数据对象，直接返回
      if (data.data) {
        return data.data;
      }
      // 如果没有data字段，但有其他用户信息字段，返回整个对象
      if (data.openid || data.userId || data.user_id) {
        return data;
      }
      // 默认返回
      return data;
    } else {
      // 业务错误
      const error = errorHandler.handleBusinessError(data);
      return Promise.reject(error);
    }
  } else {
    // HTTP错误
    const error = errorHandler.handleHttpError(response.statusCode, response);
    return Promise.reject(error);
  }
};

// 请求方法
const request = (options = {}) => {
  return new Promise((resolve, reject) => {
    // 应用请求拦截器
    options = requestInterceptor(options);
    
    // 设置超时时间
    if (!options.timeout) {
      options.timeout = TIMEOUT;
    }
    
    // 发起请求
    uni.request({
      ...options,
      success: (res) => {
        try {
          // 应用响应拦截器
          const data = responseInterceptor(res);
          resolve(data);
        } catch (error) {
          errorHandler.logError(error, 'request.responseInterceptor');
          reject(error);
        }
      },
      fail: (err) => {
        const error = errorHandler.handleRequestFail(err);
        errorHandler.logError(error, 'request.fail');
        reject(error);
      }
    });
  });
};

// 封装常用请求方法
const http = {
  get(url, data = {}, options = {}) {
    return request({
      url,
      data,
      method: 'GET',
      ...options
    });
  },
  
  post(url, data = {}, options = {}) {
    return request({
      url,
      data,
      method: 'POST',
      ...options
    });
  },
  
  put(url, data = {}, options = {}) {
    return request({
      url,
      data,
      method: 'PUT',
      ...options
    });
  },
  
  delete(url, data = {}, options = {}) {
    return request({
      url,
      data,
      method: 'DELETE',
      ...options
    });
  },
  
  // 上传文件
  upload(url, filePath, name = 'file', formData = {}, options = {}) {
    return new Promise((resolve, reject) => {
      // 获取token
      const token = uni.getStorageSync('token');
      
      // 设置请求头
      const header = options.header || {};
      if (token) {
        header['Authorization'] = `Bearer ${token}`;
      }
      
      // 添加基础URL
      if (!url.startsWith('http')) {
        url = BASE_URL + url;
      }
      
      uni.uploadFile({
        url,
        filePath,
        name,
        formData,
        header,
        success: (res) => {
          try {
            // 上传接口可能返回的是字符串
            if (typeof res.data === 'string') {
              res.data = JSON.parse(res.data);
            }
            
            // 应用响应拦截器
            const data = responseInterceptor({
              statusCode: res.statusCode,
              data: res.data
            });
            resolve(data);
          } catch (error) {
            reject(error);
          }
        },
        fail: (err) => {
          showError('文件上传失败');
          reject(err);
        }
      });
    });
  }
};

export default http; 