/**
 *@description: 请求接口配置文件
 *@return {*}
 *@param 
*/
import urlConfig from "./config";
import toast from "@/utils/toast";
import { getStorage } from "@/utils/storage";
import { store } from "@/store";
import { addTask, jx_trembling } from "@/utils/tools";
import configCms from "@/utils/configCms";
import useGlobalFunc from "@/composables/useGlobalFunc";


// 定义请求类型
type methodsType = "GET" | "OPTIONS" | "HEAD" | "POST" | "PUT" | "DELETE" | "TRACE" | "CONNECT" | undefined
// 定义方法中的类型
type FnApiType = {
    (url: string, methods: methodsType, data?: AnyObject | string, timeout?: number, baseURL?: string, contentType?: string): Promise<AnyObject>
}
// 定义方法类型
interface Api {
    api: FnApiType
}
// 请求类型请求头
let cType = 'application/x-www-form-urlencoded'
// 最大超时时间默认15秒
let timeouts: any = 0
// 清空定时器，在800毫秒内数据请求回来了就清空定时器
let timer: any
// 最大请求加载图层时间
let timer1: any
// 保存请求中断
let requestTask: any = null


/*************************************************
 * 封装请求方法
 * @param {string} [url] 请求地址
 * @param {methodsType} [method] 请求方法默认GET
 * @param {object} [data] 请求参数默认""
 * @param {number} [timeout] 请求超时时间
 * @param {string} [baseURL] 请求根路径默认https://wx.jxc4.com
 * @param {string} [contentType] 请求头类型默认'application/x-www-form-urlencoded'
 * @return {promist} [resolve, reject] promist成功与失败
*/
const request: Api = {
    api: (url, method = 'GET', data = "", timeout = 1000 * 20, baseURL = urlConfig, contentType = cType) => {
        if (requestGuard(url)) {
            return new Promise((resolve, reject) => { })
        }
        let newUrl = url
        if(getStorage('terrace') !== 'jxcs') newUrl = `/${getStorage('terrace')}` + url
        if(getStorage('terrace') == 'jxgy' && url == '/v2/version/GetVersionController') newUrl = url
        timeouts = timeout
        store.commit('storeInfo/jxLoadingFn', false)    // 关闭自定义加载图（vuex)
        clearTimeout(timer)
        timer = setTimeout(() => {
            // 显示自定义加载图(vuex)
            store.commit('storeInfo/jxLoadingFn', true)
            // 最大时间加载图
            tremblingJxLoadingFn()
        }, 500)
        return new Promise((resolve, reject) => {
            requestTask = uni.request({
                url: baseURL + newUrl,
                method: method,
                data: data,
                timeout: timeout,
                header: {
                    'content-type': contentType,
                    'token': getStorage('token') ? getStorage('token') : 'jxcs'
                },
                success: (res) => {
                    store.commit('storeInfo/jxLoadingFn', false)    // 关闭自定义加载图（vuex)
                    if (res.statusCode >= 200 && res.statusCode < 300) {
                        // 通过token 验证 通过store 验证
                        if ((res.data as AnyObject).code == '-2') {
                            uni.jxAlert({
                                title: '提示',
                                content: '登录信息已过期',
                                confirmText: '重新登录',
                                success: () => {
                                    const { logOutFn } = useGlobalFunc()
                                    logOutFn()
                                    uni.reLaunch({ url: '/subPages/login/wxLogin/wxLogin' })
                                }
                            })
                            return false
                        } else {
                            // 验证通过
                            try {
                                const jsonData = JSON.parse((res.data as AnyObject).data)
                                resolve({
                                    code: (res.data as AnyObject).code,
                                    data: jsonData,
                                    desc: (res.data as AnyObject).desc
                                })
                            } catch (error) {
                                resolve(res.data as AnyObject)
                            }
                        }
                    } else if (res.statusCode >= 400 && res.statusCode < 500) {
                        toast('客户端出错', 2)
                        reject('客户端出错')
                    } else if (res.statusCode >= 500) {
                        toast('服务端出错', 2)
                        reject('服务端出错')
                    } else {
                        toast('网络请求出错', 2)
                    }
                },
                fail: (error) => {
                    if (error.errMsg == 'request:fail abort') {
                        // 中断请求
                        return false
                    }
                    toast('网络请求超时', 2)
                    console.log('ZSW-网络请求超时', error);
                    reject(`网络请求超时 -- request.ts, ${error}`)
                },
                complete: () => {
                    uni.stopPullDownRefresh()
                    store.commit('storeInfo/jxLoadingFn', false)    // 关闭自定义加载图（vuex)
                    uni.hideLoading()
                    clearTimeout(timer)     // 清空定时器
                }
            })

            // 添加请求记录到缓存
            if (url == '/v2/cms/GetNewOrderMsg') return
            addTask(requestTask)
        })
    }
}

/*************************************************
 * 防抖超时加载图层
*/
const tremblingJxLoadingFn = jx_trembling(() => {
    clearTimeout(timer1)
    timer1 = setTimeout(() => {
        store.commit('storeInfo/jxLoadingFn', false)    // 关闭自定义加载图（vuex)
        console.log('ZSW-超时关闭加载图层');
        clearTimeout(timer1)
    }, timeouts)
}, 500)


/*************************************************
 * 登录守卫
*/
function requestGuard(url: string) {
    // 获取网络状态
    uni.getNetworkType({
        success: (res) => {
            if (res.networkType == 'none') {
                store.commit('serveInfo/setIsNetWorkS', false)
            } else {
                store.commit('serveInfo/setIsNetWorkS', true)
            }
        }
    })

    // 验证token
    if (!getStorage('token') && !configCms.whiteListUrl.includes(url)) {
        store.commit('serveInfo/setIsFirestLogin', true)
        return true
    }

    // 验证storeID
    if (!getStorage('storeID') && !configCms.whiteListUrl.includes(url)) {
        rulerStoreID()
        return true
    }

    // 验证网络状态
    if (!store.state.serveInfo.isNetWork) {
        return true
    }

    store.commit('serveInfo/setIsFirestLogin', false)
    return false
}
// 门店防抖节流
const rulerStoreID = jx_trembling(() => {
    uni.navigateTo({ url: "/subPages/switchStore/switchStore" })
}, 1000)


export default request