
import { Client, Dashboard, Project } from '@/enums/api';
import { login } from '../api/base/client';
import { useUserStore } from '@/stores'
const host = 'https://pmr.surkw.com:1443';
const prefix = '/'
const whiteUrl: string[] = [Client.LOGIN]

const authorizeWhiteUrl: string[] =  [Client.GET_PERMISSIONS, Client.AUTHORIZE_MOBILE, Dashboard.REPORT_PRJOJECT_CAT_STAT, Dashboard.REPORT_PRJOJECT_COUNT_STAT, Dashboard.REPORT_PRJOJECT_MULTI_STAT, Dashboard.REPORT_PRJOJECT_PLAN_STAT, Project.PROJECT_WORK_STAT]

let publicParams = {
    ver: '1.0',
    app_id: 'wx78e79f8a976d3952',
    timestamp: new Date().getTime()
}

enum HttpMethod {
    GET,
    POST
}


interface RequestConfig {
    url: string,
    method?: HttpMethod,
    data?: any,
    header?: Object
}

// 接口正常返回数据
export interface Result {
    api: string, code: number, msg: string
    data?: { [key: string]: any },
}

// 添加拦截器
const httpInterceptor = {
    // 拦截前触发
    invoke(options: UniApp.RequestOptions) {
    },
}

uni.addInterceptor('request', httpInterceptor)

const CODEMESSAGE: { [key: number]: string } = {
    400: '发出的请求有错误，服务器没有进行新建或修改数据的操作。',
    401: '用户没有权限（令牌、用户名、密码错误）。',
    403: '用户得到授权，但是访问是被禁止的。',
    404: '发出的请求针对的是不存在的记录，服务器没有进行操作。',
    406: '请求的格式不可得。',
    410: '请求的资源被永久删除，且不会再得到的。',
    422: '当创建一个对象时，发生一个验证错误。',
    500: '服务器发生错误，请检查服务器。',
    502: '网关错误。',
    503: '服务不可用，服务器暂时过载或维护。',
    504: '网关超时(Gateway Timeout)。'
}

class HttpRequest {

    private static instance: HttpRequest;
    private constructor() {
    }

    /**
     * 单例
     */
    public static getInstance(): HttpRequest {
        if (!this.instance) {
            this.instance = new HttpRequest();
        }
        return this.instance;
    }

    /**
     * 公用请求方法
     */
    public request<T = any>(requestConfig: RequestConfig): Promise<T> {
        const me = this;
        return new Promise((resolve, reject) => {
            let header = {
                'content-type': 'application/json'
            };
            // 判断url是否在白名单，如果不在则获取token 并对请求数据加上该字段
            const userStore = useUserStore()
            const token = userStore.getToken
            const isWhiteUrl = whiteUrl.includes(requestConfig.url)
            const isAuthorizeWhiteUrl = authorizeWhiteUrl.includes(requestConfig.url)
            const { mobile } = uni.getStorageSync('info_status')
            // console.log('mobile')
            // console.log(requestConfig.url)
            // console.log(mobile)
            if (!isWhiteUrl && !isAuthorizeWhiteUrl && !mobile) {
                console.log('mobile')
                console.log(requestConfig.url)
                console.log(mobile)
                if (!mobile) {
                    uni.hideLoading();
                    uni.redirectTo({
                        url: '/pages/authorize/index'
                    })
                    return 
                }
            }
            Object.assign(publicParams, { token })
            const data = requestConfig.method === HttpMethod.POST ? Object.assign(publicParams, { data: { ...requestConfig?.data } }) : requestConfig?.data
            uni.request({
                url: `${host}${prefix}${requestConfig.url}`,
                data,
                timeout: 6000,
                method: requestConfig.method === HttpMethod.GET ? 'GET' : 'POST',
                header: Object.assign(header, requestConfig?.header),
                success: async function (res: any) {
                    if (res.statusCode == 200) { //网络请求状态
                        const { data } = res
                        if (!data) {
                            // return '[HTTP] Request has no return value';
                            throw new Error('返回数据错误！')
                        }
                        const { code, msg, api, ...result } = data as Result
                        const hasSuccess =
                            data && Reflect.has(data, 'code') && code === 10000
                        if (hasSuccess) {
                            return resolve(result.data as unknown as Promise<T>)
                        }
                        const isLogout =
                            data && Reflect.has(data, 'code') && code === 11000
                        if (isLogout) {
                            await me.updateToken();
                           return resolve(me.request(requestConfig))
                        }
                        uni.showModal({
                            title: '请求失败',
                            showCancel: false,
                            content: `${msg}`
                        })
                        return reject(data);
                    }
                    checkStatus(res.statusCode)
                    return reject();
                },
                fail: function (error: any) {
                    uni.showModal({
                        title: '请求失败',
                        showCancel: false,
                        content: `${error.errMsg}`
                    })
                    reject(error)
                }
            })
        })
    };

    public get(url: string, config?: Object): Promise<Object> {
        return this.request({ url, method: HttpMethod.GET, ...config })
    }

    public post<T = any>(url: string, data: Object, config?: Object): Promise<T> {
        return this.request({ url, method: HttpMethod.POST, data, ...config })
    }

    public async updateToken(): Promise<void> {
        try {
            const res = await uni.login();
    
            if (res.code) {
                // 发起网络请求
                const userStore = useUserStore();
                const { token, info_status } = await login({ code: res.code, platform: 1 });
                userStore.setLoginInfo(info_status, token);
            } else {
                throw new Error(res.errMsg);
            }
        } catch (error) {
            uni.showModal({
                title: '登录失败！',
                showCancel: false,
                content: error instanceof Error ? error.message : '登录过程中发生错误'
            });
            throw error; // 抛出错误，让调用者处理
        }
    }
    /**
     * 更新token, 验证是否授权手机号，跳转到授权页
     */
    // public updateToken() {
    //     return new Promise((resolve, reject) => {
    //         uni.login({
    //             async success(res) {
    //                 if (res.code) {
    //                     // 发起网络请求
    //                     const userStore = useUserStore()
    //                     const { token, info_status } = await login({ code: res.code, platform: 1 })
    //                     userStore.setLoginInfo(info_status, token)
    //                     return resolve({})

    //                 } else {
    //                     uni.showModal({
    //                         title: '登录失败！',
    //                         showCancel: false,
    //                         content: `${res.errMsg}`
    //                     })
    //                     return reject()
    //                 }
    //             }
    //         })
    //     })
    // }

}

export function checkStatus(status: number, statusText?: string): void {
    if ((status >= 200 && status < 300) || status === 401 || status === undefined)
        return
    const errorText = CODEMESSAGE[status] || statusText
    uni.showModal({
        title: '请求失败',
        showCancel: false,
        content: `${status}: ${errorText}`
    })
    throw new Error(errorText)
}



export default HttpRequest.getInstance();