import throttle from "@/uni_modules/uv-ui-tools/libs/function/throttle";
import mxConst from "@/common/mxConst";
import {fnPlaceholder} from "@/utils/uni-helper";
import {useUserStore} from "@/hooks/useUserStore";

function isBlobRequest(response) {
    return response?.config?.responseType?.toLowerCase() === 'arraybuffer'
}

/**
 * 响应拦截
 * @param {Object} http
 */
export const responseInterceptors = (vm) => {
    // blob 预处理，文件流强制转换输出类型
    uni.$uv.http.interceptors.response.use((response) => {
        if (isBlobRequest(response)) {
            response.config.custom = response.config.custom || {}
            response.config.custom.raw = true
        }
        return response
    })

    // 一般的请求处理结果
    uni.$uv.http.interceptors.response.use(async (response) => { /* 对响应成功做点什么 可使用async await 做异步操作*/
        const data = response.data
        // 自定义参数
        const custom = response.config?.custom
        const code = data.code || response.statusCode
        if (code !== 200) { // 服务端返回的状态码不等于200，则reject()
            const {clearToken} = useUserStore()
            const msg = data.msg || data.message || mxConst.serverErrors[data.code] || '服务器错误，请稍后重试'
            switch (code) {
                case 401:
                    // 无提示跳转
                    clearToken()
                    throttle(() => uni.$uv.route(mxConst.routes.login))
                    break
                case 402:
                case 405:
                    // 有提示跳转
                    throttle(() => {
                        Promise.all([
                            new Promise((resolve) => {
                                uni.showModal({
                                    content: msg, // 登陆提示或者是 VIP 提示
                                    showCancel: false,
                                    success: _ => {
                                        if (data.code == 402) {
                                            clearToken()
                                            uni.$uv.route(mxConst.routes.login)
                                        }
                                        else if (data.code == 405) {
                                            uni.$uv.route(mxConst.routes.activate)
                                        }
                                        else {
                                            throw new Error('Unhandled code for modal action: ' + data.code)
                                        }
                                        resolve()
                                    }
                                })
                            })
                        ])
                    })
                    break
                default:
                    // 如果没有显式定义custom的toast参数为false的话，默认对报错进行toast弹出提示
                    if (custom?.toast !== false) {
                        uni.$uv.toast(msg)
                    }
                    break
            }

            // 如果需要catch返回，则进行reject
            if (custom?.catch) {
                // 后续能显式收到错误
                return Promise.reject(data)
            } else {
                // 打断继续执行，但不会显式收到错误
                return new Promise(fnPlaceholder)
            }
        }

        // 成功时，定了几种不同的返回类型
        if (custom?.raw === true) return response
        if (custom?.root === true) return data // 默认配置
        return data.data || {}
    }, (response) => { /*  对响应错误做点什么 （statusCode !== 200）*/
        return Promise.reject(response)
    })

    // blob 文件流返回数据处理
    uni.$uv.http.interceptors.response.use((response) => {
        if (isBlobRequest(response)) {
            if (!(response.data instanceof Blob) && (response.data instanceof ArrayBuffer)) {
                response.data = new Blob([response.data])
            }
        }
        return response
    })
}
