import { WxLoginUsingGetResponse } from "@/apis/userApi";
import APPConfig from "@/config";
import Taro from "@tarojs/taro";
import qs from "qs";
import ModalUtil from "./modalUtil";
import StorageUtil, { EStorage } from "./storageUtil";
import UserHelper from '@/helper/userHelper';

interface IRequestBaseResult<T> {
    code?: Number;
    data: T;
    msg: string;
}

interface IRequestOptions {
    tips?: string | true;
    success?: string | true;
    errorTips?: string | true;
    loading?: string | true;
    contentType?: "json" | "urlencoded" | "formData";
    data?: Record<string, any>,
    params?: Record<string, any>,
}

export interface AxiosRequestConfigFunc<B, P> extends Omit<IRequestOptions, "data" | "params"> {
    data?: B,
    params?: P
}

export default class RequestUtil<T> {
    promise: Promise<Taro.request.SuccessCallbackResult<IRequestBaseResult<T>>>;


    public constructor(url: string, method: "POST" | "GET" | "PUT" | "DELETE", options: IRequestOptions) {
        this.promise = this.runRequest(url, method, options);
    }

    public runRequest(url: string, method: "POST" | "GET" | "PUT" | "DELETE", options: IRequestOptions) {
        options.loading && Taro.showLoading();
        return new Promise<Taro.request.SuccessCallbackResult<IRequestBaseResult<T>>>((resolve, rej) => {
            if (options.params) {
                url += "?" + qs.stringify(options.params);
            }
            url = APPConfig.HOST + url;
            let userInfo = StorageUtil.get<WxLoginUsingGetResponse>(EStorage.userInfo);
            Taro.request({
                url,
                method,
                header: { userId: userInfo?.userId?userInfo?.userId:0, "appId": APPConfig.APPID, runPlatform: 1, token: userInfo?.token?userInfo?.token:'' },
                data: options.data,
                fail: () => {
                    options.loading && Taro.hideLoading();
                    rej();
                },
                success: (res) => {
                    options.loading && Taro.hideLoading();
                    let _success = this.checkSuccessSync(res);
                    if (_success && options.success) {
                        ModalUtil.toast(typeof (options.success) === "string" ? options.success : res.data.msg);
                    }
                    else {
                        options.errorTips && ModalUtil.toast(res.data.msg);
                    }
                    resolve(res);
                },
            })
        });

    }


    private checkSuccessSync(data: Taro.request.SuccessCallbackResult<IRequestBaseResult<T>>) {
        return data.statusCode >= 200 && data.statusCode < 300 && data.data.code === 0;
    }
    private h5checkSuccessSync(data: Taro.request.SuccessCallbackResult<IRequestBaseResult<T>>) {
        return data.statusCode >= 200 && data.statusCode < 300 && data.data.code === 0 || data.data.code == 1;
    }

    /**是否正确 */
    public async checkSuccess() {
        return this.promise.then(this.checkSuccessSync)
    }

    public async toData() {
        return this.promise
            .then((p) => {
                if (this.checkSuccessSync(p)) {
                    return p.data.data;
                }

                // 登录状态失效
                if (p.data.code == -130) {
                    UserHelper.outLogin()
                    return null 
                }

                return null;
            })
    }
    public async h5toData() {
        return this.promise
            .then((p) => {
                if (this.h5checkSuccessSync(p)) {
                    return p.data;
                }
                return null;
            })
    }
}