import env from '../config/env.js'

// Loading 管理器
const loadingManager = {
  loadingCount: 0,
  loadingTimer: null,

  // 显示 loading
  show(options = {}) {
    const config = {
      title: '加载中...',
      mask: true,
      delay: 300,
      ...options
    }

    // 如果已经有 loading 在显示，只增加计数
    if (this.loadingCount > 0) {
      this.loadingCount++
      return
    }

    // 延迟显示，避免快速请求造成闪烁
    this.loadingTimer = setTimeout(() => {
      if (this.loadingCount > 0) {
        uni.showLoading({
          title: config.title,
          mask: config.mask
        })
      }
    }, config.delay)

    this.loadingCount++
  },

  // 隐藏 loading
  hide() {
    this.loadingCount = Math.max(0, this.loadingCount - 1)

    if (this.loadingCount === 0) {
      // 清除延迟显示的定时器
      if (this.loadingTimer) {
        clearTimeout(this.loadingTimer)
        this.loadingTimer = null
      }

      // 隐藏 loading
      uni.hideLoading()
    }
  },

  // 强制隐藏所有 loading
  forceHide() {
    this.loadingCount = 0
    if (this.loadingTimer) {
      clearTimeout(this.loadingTimer)
      this.loadingTimer = null
    }
    uni.hideLoading()
  }
}

const request = {
  async get(url, params = {}, options = {}) {
    return this.request(url, 'GET', params, options)
  },

  async post(url, data = {}, options = {}) {
    return this.request(url, 'POST', data, options)
  },

  async put(url, data = {}, options = {}) {
    return this.request(url, 'PUT', data, options)
  },

  async delete(url, data = {}, options = {}) {
    return this.request(url, 'DELETE', data, options)
  },
  
  async request(url, method, data, options = {}) {
    // 解析 loading 配置
    let loadingConfig
    if (options.loading === false) {
      // 如果明确设置为 false，则不显示 loading
      loadingConfig = false
    } else {
      // 否则使用默认配置并合并用户配置
      loadingConfig = {
        show: true,
        title: '加载中...',
        mask: true,
        delay: 300,
        timeout: 10000,
        ...(typeof options.loading === 'object' ? options.loading : {})
      }
    }

    // 解析请求配置
    const requestConfig = {
      timeout: 15000, // 默认网络超时 15 秒
      ...options.request
    }

    // 如果 loading 配置为 false，则不显示 loading
    const shouldShowLoading = loadingConfig !== false && loadingConfig.show !== false

    // 显示 loading
    if (shouldShowLoading) {
      loadingManager.show(loadingConfig)
    }

    // 获取设备信息
    const deviceInfo = uni.getStorageSync("deviceInfo") || {};
    const sbbs = deviceInfo.deviceId || '';
    const sbmc = deviceInfo.model || '';

    // 处理URL，添加设备参数
    const separator = url.includes('?') ? '&' : '?';
    const finalUrl = `${url}${separator}sbbs=${sbbs}&sbmc=${sbmc}`;

    // 超时处理
    let timeoutTimer = null
    if (shouldShowLoading && loadingConfig.timeout) {
      timeoutTimer = setTimeout(() => {
        loadingManager.hide()
        uni.showToast({
          title: '请求超时',
          icon: 'none'
        })
      }, loadingConfig.timeout)
    }

    // 数据格式转换
    let requestData = data;
    if (options.formData && data && typeof data === 'object') {
      // 转换为表单格式
      requestData = Object.keys(data).map(key => {
        const value = data[key];
        if (Array.isArray(value)) {
          // 数组数据转换为多个同名参数
          return value.map(item => `${encodeURIComponent(key)}=${encodeURIComponent(item)}`).join('&');
        } else {
          return `${encodeURIComponent(key)}=${encodeURIComponent(value)}`;
        }
      }).join('&');
    }

    return new Promise((resolve, reject) => {
      uni.request({
        url: `${env.baseUrl}${finalUrl}`,
        method,
        data: requestData,
        timeout: requestConfig.timeout, // 设置网络超时
        header: (() => {
          const headers = {};

          // 根据选项决定Content-Type
          if (options.formData) {
            // 使用表单格式，让浏览器自动设置Content-Type
            headers['content-type'] = 'application/x-www-form-urlencoded';
          } else {
            // 默认使用JSON格式
            headers['content-type'] = 'application/json';
          }

          const jsessionId = uni.getStorageSync('JSESSIONID');
          if (jsessionId) {
            headers['Cookie'] = `JSESSIONID=${jsessionId}`;
          }

          return headers;
        })(),
        success: (res) => {
          // 清除超时定时器
          if (timeoutTimer) {
            clearTimeout(timeoutTimer)
          }

          // 获取响应头
          const headers = res.header;
          // console.log('响应头:', headers);

          // 处理Set-Cookie，获取JSESSIONID
          const setCookie = headers['set-cookie'] || headers['Set-Cookie'];
          if (setCookie) {
            const match = setCookie.match(/JSESSIONID=([^;]+)/);
            if (match && match[1]) {
              // console.log('获取到新的JSESSIONID:', match[1]);
              uni.setStorageSync('JSESSIONID', match[1]);
            }
          }

          if (res.statusCode === 200) {
            // 将响应头信息附加到返回数据中
            const responseData = {
              data: res.data,
            };
            resolve(responseData);
          } else {
            reject(res);
          }
        },
        fail: (err) => {
          // 清除超时定时器
          if (timeoutTimer) {
            clearTimeout(timeoutTimer)
          }

          uni.showToast({
            title: '网络请求失败',
            icon: 'none'
          })
          reject(err)
        },
        complete: () => {
          // 隐藏 loading
          if (shouldShowLoading) {
            loadingManager.hide()
          }
          // console.log('请求完成');
        }
      })
    })
  }
}

// 添加一些便捷方法
request.loadingManager = loadingManager

// 静默请求（不显示 loading）
request.silent = {
  get: (url, params = {}) => request.get(url, params, { loading: false }),
  post: (url, data = {}) => request.post(url, data, { loading: false }),
  put: (url, data = {}) => request.put(url, data, { loading: false }),
  delete: (url, data = {}) => request.delete(url, data, { loading: false })
}

// 带自定义 loading 文字的请求
request.withLoading = (title) => ({
  get: (url, params = {}) => request.get(url, params, { loading: { title } }),
  post: (url, data = {}) => request.post(url, data, { loading: { title } }),
  put: (url, data = {}) => request.put(url, data, { loading: { title } }),
  delete: (url, data = {}) => request.delete(url, data, { loading: { title } })
})

export default request