import type {CustomRequestOptions} from '@/interceptor/request'
import {useConfigStore, useUserStore} from '@/store'
import Config from '@/config'
import {i18n} from "@/locale";

type IRes<T> = T extends ArrayBuffer ? ArrayBuffer : IResData<T>


export const http = <T>(options: CustomRequestOptions) => {
    console.log(options, 'options')
    // 1. 返回 Promise 对象
    return new Promise<IRes<T>>((resolve, reject) => {
        uni.request({
            ...options,
            dataType: 'json',
            // 响应成功
            success(res) {
                console.log(res, '111111')

                const ErrorMessage = {
                    401: i18n.global.t('common.prompt.authentication-failed-please-log-in'),
                    700: i18n.global.t('common.prompt.login-expired-please-log-in-again'),
                }
                const configStore = useConfigStore()
                const userStore = useUserStore()
                const data = res.data as IRes<T>

                if (!(data instanceof ArrayBuffer) && data.systemTime) {
                    // @ts-ignore
                    configStore.serverTime = +data.systemTime
                }
                if (data instanceof ArrayBuffer || data.code === 200) {
                    resolve(data)
                } else if (data.code === 401 || data.code === 700) {
                    uni.showToast({
                        icon: 'none',
                        title: ErrorMessage[data.code],
                    })

                    userStore?.clear?.()
                    uni.navigateTo({url: Config.loginPath})
                    reject(data)
                } else if (data.code === 711) {
                    reject(data)
                } else {
                    // 其他错误 -> 根据后端错误信息轻提示
                    !options.hideErrorToast &&
                    uni.showToast({
                        icon: 'none',
                        title: (res.data as IResData<T>).msg || i18n.global.t('common.prompt.request-incorrect'),
                    })
                    reject(data)
                }
            },
            // 响应失败
            fail(err) {
                uni.showToast({
                    icon: 'none',
                    title: i18n.global.t('common.prompt.request-failed-please-try-again-later'),
                })
                reject(err)
            },
        })
    })
}

/**
 * GET 请求
 * @param url 后台地址
 * @param query 请求query参数
 * @param responseType
 * @returns
 */
export const httpGet = <T>(url: string, query?: Record<string, any>, responseType: 'text' | 'arraybuffer' = 'text') => {
    return http<T>({
        url,
        query,
        responseType,
        method: 'GET',
    })
}

/**
 * DELETE 请求
 * @param url 后台地址
 * @param query 请求query参数
 * @param data 请求body参数
 * @param responseType
 * @returns
 */
export const httpDelete = <T>(
    url: string,
    query?: Record<string, any>,
    data?: Record<string, any>,
    responseType: 'text' | 'arraybuffer' = 'text',
) => {
    return http<T>({
        url,
        query,
        data,
        responseType,
        method: 'DELETE',
    })
}

/**
 * POST 请求
 * @param url 后台地址
 * @param data 请求body参数
 * @param query 请求query参数，post请求也支持query，很多微信接口都需要
 * @param responseType 数据响应格式
 * @returns
 */
export const httpPost = <T>(
    url: string,
    data?: Record<string, any> | string,
    query?: Record<string, any>,
    responseType: 'text' | 'arraybuffer' = 'text',
) => {
    return http<T>({
        url,
        query,
        data,
        responseType,
        method: 'POST',
    })
}

/**
 * PUT 请求
 * @param url 后台地址
 * @param data 请求body参数
 * @param query 请求query参数，post请求也支持query，很多微信接口都需要
 * @param responseType 数据响应格式
 * @returns
 */
export const httpPut = <T>(
    url: string,
    data?: Record<string, any> | string,
    query?: Record<string, any>,
    responseType: 'text' | 'arraybuffer' = 'text',
) => {
    return http<T>({
        url,
        query,
        data,
        responseType,
        method: 'PUT',
    })
}

http.get = httpGet
http.post = httpPost
http.put = httpPut
http.delete = httpDelete
