import HttpRequest from './http'
import { merge } from 'lodash-es'
import { HttpRequestOptions, RequestHooks } from './type'
import { getToken } from '../auth'
import { RequestCodeEnum, RequestMethodsEnum } from '@/enums/requestEnums'
import { useUserStore } from '@/stores/user'
import appConfig from '@/config'
import { getClient } from '../client'
import cache from '@/utils/cache'
import { BACK_URL } from '@/enums/constantEnums'

let isLoginModalShowing = false

function showLoginModal() {
    if (isLoginModalShowing) return
    isLoginModalShowing = true
    // 先关闭可能存在的 toast/loading，否则 showModal 不会弹出
    uni.hideToast()
    uni.hideLoading()
    setTimeout(() => {
        uni.showModal({
            title: '提示',
            content: '该功能需要登录，是否前往登录？',
            confirmText: '去登录',
            cancelText: '取消',
            success: (res) => {
                if (res.confirm) {
                    const pages = getCurrentPages()
                    const current = pages[pages.length - 1]
                    if (current) {
                        const route = '/' + current.route
                        const options = (current as any).options || {}
                        const query = Object.keys(options)
                            .map((k) => `${k}=${options[k]}`)
                            .join('&')
                        cache.set(BACK_URL, query ? `${route}?${query}` : route)
                    }
                    uni.navigateTo({ url: '/pages/login/login' })
                }
            },
            complete: () => {
                isLoginModalShowing = false
            }
        })
    }, 100)
}

const requestHooks: RequestHooks = {
    requestInterceptorsHook(options, config) {
        const { urlPrefix, baseUrl, withToken, isAuth } = config
        options.header = options.header ?? {}
        if (urlPrefix) {
            options.url = `${urlPrefix}${options.url}`
        }
        if (baseUrl) {
            options.url = `${baseUrl}${options.url}`
        }
        const token = getToken()
        // 有token就带上，无token则不传
        if (token && !options.header.token) {
            options.header.token = token
        }
        options.header.version = appConfig.version
        // options.header.terminal = getClient();
        return options
    },
    async responseInterceptorsHook(response, config) {
        const { isTransformResponse, isReturnDefaultResponse, isAuth } = config

        //返回默认响应，当需要获取响应头及其他数据时可使用
        if (isReturnDefaultResponse) {
            return response
        }
        // 是否需要对数据进行处理
        if (!isTransformResponse) {
            return response.data
        }
        const userStore = useUserStore()
        const { code, data, msg, show } = response.data as any
        switch (code) {
            case RequestCodeEnum.SUCCESS:
                msg && show && uni.$u.toast(msg)
                return data
            case RequestCodeEnum.FAILED:
                if (msg && (/token/i.test(msg) || /登录/i.test(msg))) {
                    if (userStore.isLogin || isAuth) {
                        userStore.logout()
                        showLoginModal()
                    }
                } else if (msg) {
                    uni.$u.toast(msg)
                }
                return Promise.reject(msg)

            case RequestCodeEnum.TOKEN_INVALID:
                if (userStore.isLogin || isAuth) {
                    userStore.logout()
                    showLoginModal()
                }
                return Promise.reject(msg)

            default:
                return data
        }
    },
    async responseInterceptorsCatchHook(options, error) {
        if (options.method?.toUpperCase() == RequestMethodsEnum.POST) {
            uni.$u.toast('请求失败，请重试')
        }
        return Promise.reject(error)
    }
}

const defaultOptions: HttpRequestOptions = {
    requestOptions: {
        timeout: appConfig.timeout
    },
    baseUrl: appConfig.baseUrl,
    //是否返回默认的响应
    isReturnDefaultResponse: false,
    // 需要对返回数据进行处理
    isTransformResponse: true,
    // 接口拼接地址
    urlPrefix: 'api',
    // 忽略重复请求
    ignoreCancel: false,
    // 是否携带token
    withToken: true,
    isAuth: false,
    retryCount: 2,
    retryTimeout: 1000,
    requestHooks: requestHooks
}

function createRequest(opt?: HttpRequestOptions) {
    return new HttpRequest(
        // 深度合并
        merge(defaultOptions, opt || {})
    )
}
const request = createRequest()
export default request
