/**
 * 添加拦截器:
 *   拦截 request 请求
 *   拦截 uploadFile 文件上传
 *
 * TODO:
 *   1. 非 http 开头需拼接地址
 *   2. 请求超时
 *   3. 添加小程序端请求头标识
 *   4. 添加 token 请求头标识
 */

import useUserStore from '@/store/user'

const baseURL = 'https://hna-platform.anyremote.cn'

class ServiceLoading {
    constructor() {
        this.count = 0
    }
    open(loading) {
        if (this.count < 0) {
            this.count = 0
        }
        if (loading || loading === '') {
            let loadingText = '加载中'
            if (typeof loading === 'string' && loading !== '') {
                loadingText = loading
            }
            this.count++
            uni.showLoading({
                title: loadingText,
                mask: true
            });
        }
    }
    close() {
        this.count--
        if (this.count <= 0) {
            uni.hideLoading();
        }
    }
}
const serviceLoading = new ServiceLoading()

// 添加拦截器
const httpInterceptor = {
    // 拦截前触发
    invoke(options) {
        //responseType
        if (options.config?.arraybuffer) {
            options.responseType = 'arraybuffer'
        }
        //loading
        const loading = options.config?.loading
        serviceLoading.open(loading)
        //重组提交数据
        if (options.data) {
            options.data = {
                ...options.data,
                apiPwd: 'Ifar$2_0160_525_Mocp',
                requestFrom: '3',
                realUserId: '21'
            }
        }
        // 非 http 开头需拼接地址
        if (!options.url.startsWith('http')) {
            options.url = baseURL + options.url
        }
        // 请求超时, 默认 60s
        options.timeout = 10000
        // 添加小程序端请求头标识
        options.header = {
            'Content-Type': 'application/x-www-form-urlencoded',
            ...options.header,
        }
        // 添加 token 请求头标识
        const userStore = useUserStore()
        if (userStore.token) {
            options.header.Authorization = `Bearer ${userStore.token}`
        }
    },
}
uni.addInterceptor('request', httpInterceptor)
uni.addInterceptor('uploadFile', httpInterceptor)

/**
 * 请求函数
 * @returns Promise
 *  1. 返回 Promise 对象
 *  2. 获取数据成功
 *    2.1 提取核心数据 res.data
 *    2.2 添加类型，支持泛型
 *  3. 获取数据失败
 *    3.1 401错误  -> 清理用户信息，跳转到登录页
 *    3.2 其他错误 -> 根据后端错误信息轻提示
 *    3.3 网络错误 -> 提示用户换网络
 */
// 2.2 添加类型
export const http = (options) => {
    // 1. 返回 Promise 对象
    return new Promise((resolve, reject) => {
        uni.request({
            ...options,
            // 响应成功
            success(res) {
                serviceLoading.close()
                // 状态码 2xx， axios 就是这样设计的
                if (res.statusCode >= 200 && res.statusCode < 300) {
                    // 2.1 提取核心数据 res.data
                    resolve(res.data)
                } else if (res.statusCode === 401) {
                    // 401错误  -> 清理用户信息，跳转到登录页
                    const userStore = useUserStore()
                    userStore.handleLogOut()
                    reject(res)
                } else {
                    // 其他错误 -> 根据后端错误信息轻提示
                    uni.$message.showToast(res.data.msg || '请求错误')
                    reject(res)
                }
            },
            // 响应失败
            fail(err) {
                serviceLoading.close()
                uni.$message.showToast('网络错误，换个网络试试')
                reject(err)
            },
        })
    })
}