// 统一请求封装
class Request {
  constructor() {
    this.baseURL = ''
    this.timeout = 10000
    this.header = {
      'Content-Type': 'application/json'
    }
  }

  // 设置基础URL
  setBaseURL(url) {
    this.baseURL = url
  }

  // 设置请求头
  setHeader(header) {
    this.header = { ...this.header, ...header }
  }

  // 请求拦截器
  requestInterceptor(config) {
    // 添加token
    const token = uni.getStorageSync('token')
    if (token) {
      config.header = config.header || {}
      config.header.Authorization = 'Bearer ' + token
    }

    // 添加基础URL
    if (config.url && !config.url.startsWith('http')) {
      config.url = this.baseURL + config.url
    }

    // 显示加载提示
    if (config.loading !== false) {
      uni.showLoading({
        title: config.loadingText || '加载中...',
        mask: true
      })
    }

    return config
  }

  // 响应拦截器
  responseInterceptor(response, config) {
    // 隐藏加载提示
    if (config.loading !== false) {
      uni.hideLoading()
    }

    const { data, statusCode } = response

    // HTTP状态码检查
    if (statusCode !== 200) {
      this.handleError({
        code: statusCode,
        message: '网络请求失败'
      }, config)
      return Promise.reject(response)
    }

    // 业务状态码检查
    if (data.code !== undefined && data.code !== 200) {
      this.handleError(data, config)
      return Promise.reject(data)
    }

    return data
  }

  // 错误处理
  handleError(error, config) {
    const { code, message } = error

    // 根据错误码处理
    switch (code) {
      case 401:
        // token过期，清除本地存储并跳转登录
        uni.removeStorageSync('token')
        uni.removeStorageSync('userInfo')
        uni.showToast({
          title: '登录已过期，请重新登录',
          icon: 'none'
        })
        setTimeout(() => {
          uni.navigateTo({
            url: '/pages/auth/login'
          })
        }, 1500)
        break
      case 403:
        uni.showToast({
          title: '权限不足',
          icon: 'none'
        })
        break
      case 404:
        uni.showToast({
          title: '请求的资源不存在',
          icon: 'none'
        })
        break
      case 500:
        uni.showToast({
          title: '服务器内部错误',
          icon: 'none'
        })
        break
      default:
        if (config.showError !== false) {
          uni.showToast({
            title: message || '请求失败',
            icon: 'none'
          })
        }
    }
  }

  // 通用请求方法
  request(config) {
    return new Promise((resolve, reject) => {
      // 请求拦截
      config = this.requestInterceptor(config)

      uni.request({
        ...config,
        success: (response) => {
          try {
            const result = this.responseInterceptor(response, config)
            resolve(result)
          } catch (error) {
            reject(error)
          }
        },
        fail: (error) => {
          // 隐藏加载提示
          if (config.loading !== false) {
            uni.hideLoading()
          }

          this.handleError({
            code: 0,
            message: '网络连接失败'
          }, config)
          reject(error)
        }
      })
    })
  }

  // GET请求
  get(url, data = {}, config = {}) {
    return this.request({
      url,
      method: 'GET',
      data,
      ...config
    })
  }

  // POST请求
  post(url, data = {}, config = {}) {
    return this.request({
      url,
      method: 'POST',
      data,
      ...config
    })
  }

  // PUT请求
  put(url, data = {}, config = {}) {
    return this.request({
      url,
      method: 'PUT',
      data,
      ...config
    })
  }

  // DELETE请求
  delete(url, data = {}, config = {}) {
    return this.request({
      url,
      method: 'DELETE',
      data,
      ...config
    })
  }

  // 上传文件
  upload(url, filePath, formData = {}, config = {}) {
    return new Promise((resolve, reject) => {
      // 添加token
      const token = uni.getStorageSync('token')
      const header = { ...this.header }
      if (token) {
        header.Authorization = 'Bearer ' + token
      }

      // 添加基础URL
      if (!url.startsWith('http')) {
        url = this.baseURL + url
      }

      // 显示上传进度
      if (config.showProgress !== false) {
        uni.showLoading({
          title: '上传中...',
          mask: true
        })
      }

      uni.uploadFile({
        url,
        filePath,
        name: config.name || 'file',
        formData,
        header,
        success: (response) => {
          if (config.showProgress !== false) {
            uni.hideLoading()
          }

          try {
            const data = JSON.parse(response.data)
            if (data.code === 200) {
              resolve(data)
            } else {
              this.handleError(data, config)
              reject(data)
            }
          } catch (error) {
            this.handleError({
              code: 0,
              message: '上传失败'
            }, config)
            reject(error)
          }
        },
        fail: (error) => {
          if (config.showProgress !== false) {
            uni.hideLoading()
          }

          this.handleError({
            code: 0,
            message: '上传失败'
          }, config)
          reject(error)
        }
      })
    })
  }

  // 下载文件
  download(url, config = {}) {
    return new Promise((resolve, reject) => {
      // 添加基础URL
      if (!url.startsWith('http')) {
        url = this.baseURL + url
      }

      // 显示下载进度
      if (config.showProgress !== false) {
        uni.showLoading({
          title: '下载中...',
          mask: true
        })
      }

      uni.downloadFile({
        url,
        success: (response) => {
          if (config.showProgress !== false) {
            uni.hideLoading()
          }

          if (response.statusCode === 200) {
            resolve(response)
          } else {
            this.handleError({
              code: response.statusCode,
              message: '下载失败'
            }, config)
            reject(response)
          }
        },
        fail: (error) => {
          if (config.showProgress !== false) {
            uni.hideLoading()
          }

          this.handleError({
            code: 0,
            message: '下载失败'
          }, config)
          reject(error)
        }
      })
    })
  }
}

// 创建实例
const request = new Request()

export default request