import { route, baseConfig, Global } from './config';
import { builtIn } from '../vueRouter/base';
import { err, log, warn } from './warn';

/**
 * 当前是不是H5运行环境
 */
export const isH5 = function () {
    return typeof window !== 'undefined' && typeof document !== 'undefined';
};
/**
 * 判断当前变量是否为Object
 * @param {Object} strObj
 */
export const isObject = function (strObj) {
    return strObj.toString() === '[object Object]' && strObj.constructor === Object;
};
/**
 * 获取当前运行平台
 * @param {Boolean} applets 默认false  true时所有小程序平台统一返回 APPLETS
 */
export const appPlatform = function (applets = false) {
    let platform = '';

    // #ifdef APP-PLUS-NVUE
    platform = 'APPNVUE';
    // #endif

    // #ifdef APP-PLUS
    platform = 'APP';
    // #endif

    // #ifdef H5
    platform = 'H5';
    // #endif

    // #ifdef MP-ALIPAY
    platform = 'ALIPAY';
    // #endif

    // #ifdef MP-BAIDU
    platform = 'BAIDU';
    // #endif

    // #ifdef MP-QQ
    platform = 'QQ';
    // #endif

    // #ifdef MP-WEIXIN
    platform = 'WEIXIN';
    // #endif

    // #ifdef MP-TOUTIAO
    platform = 'TOUTIAO';
    // #endif

    if (applets) {
        // #ifdef MP
        platform = 'APPLETS';
        // #endif
    }

    return platform;
};
/**
 * 定义一个空方法 如果最后一个参数为true则打印所有参数
 * @param  {...any} args
 */
export const noop = function (...args) {
    if (args[args.length - 1] === true) {
        log(args);
    }
};
/**
 * 格式化基础配置信息 通过new Router传递过来的参数
 */
export const formatConfig = function (userConfig) {
    if (!userConfig.routes || userConfig.routes.constructor !== Array) {
        return err(`路由参数 'routes' 必须传递 \r\n\r\n${JSON.stringify(userConfig)}`);
    }
    if (userConfig.h5 != null && userConfig.h5.constructor !== Object) {
        return err(`h5参数传递错误,应该是一个 'Object' 类型 示例:\r\n\r\n${JSON.stringify(baseConfig.h5)}`);
    }
    const config = Object.create(null);
    const baseConfigKeys = Object.keys(baseConfig);
    for (let i = 0; i < baseConfigKeys.length; i += 1) {
        const key = baseConfigKeys[i];
        if (userConfig[key] != null) {
            if (userConfig[key].constructor === Object) {
                config[key] = {
                    ...baseConfig[key],
                    ...userConfig[key],
                };
            } else if (key == 'routes') { // 需要加入已知的白名单
                config[key] = [...baseConfig[key], ...userConfig[key], ...builtIn];
            } else {
                config[key] = userConfig[key];
            }
        } else {
            config[key] = baseConfig[key];
        }
    }
    return config;
};
export const filter = function (str) {
    str += '';
    str = str.replace(/%/g, '%25');
    str = str.replace(/\+/g, '%2B');
    str = str.replace(/ /g, '%20');
    str = str.replace(/\//g, '%2F');
    str = str.replace(/\?/g, '%3F');
    str = str.replace(/&/g, '%26');
    str = str.replace(/=/g, '%3D');
    str = str.replace(/#/g, '%23');
    return str;
};
/**
 * 使用encodeURI:true的情况	需要进行编码后再传递,解码等等 可以传递深度对象并会在路径后面加入一个query=
 *
 * @param {String} routerName //路径名称
 * @param {JSON} query 	//需要格式化参数
 * @param {Boolean} Encode 	//是获取还是编码后传递
 */
export const parseQueryN = function (routerName, query, Encode) {
    if (Encode) {
        return {
            url: routerName,
            query: JSON.parse(decodeURIComponent(query.replace(/^query=/, ''))),
        };
    }
    return {
        url: routerName,
        query: `query=${encodeURIComponent(JSON.stringify(query))}`,
    };
};
/**
 * 使用encodeURI:false的情况 直接格式化为普通的queryURl参数形式传递即可 扁平深度对象
 *
 * @param {String} routerName //路径名称
 * @param {JSON} query 	//需要格式化参数
 * @param {Boolean} Encode 	//是获取还是编码后传递
 */
export const parseQueryD = function (routerName, query, Encode) {
    if (Encode) {
        const obj = {};
        const reg = /([^=&\s]+)[=\s]*([^&\s]*)/g;
        while (reg.exec(query)) {
            obj[RegExp.$1] = RegExp.$2;
        }
        return {
            url: routerName,
            query: obj,
        };
    }
    const encodeArr = [];
    const queryKeys = Object.keys(query);
    for (let i = 0; i < queryKeys.length; i += 1) {
        const attr = queryKeys[i];
        let encodeStr = '';
        if (query[attr].constructor == Object) {
            encodeStr = parseQueryD(routerName, query[attr], Encode).query;
            encodeArr.push(encodeStr);
        } else {
            encodeStr = filter(query[attr]);
            encodeArr.push(`${attr}=${encodeStr}`);
        }
    }
    return {
        url: routerName,
        query: encodeArr.join('&'),
    };
};
/**
 * @param {String} routerName //路径名称
 * @param {JSON} query 	//需要格式化参数
 * @param {Boolean} Encode 	//是获取还是编码后传递
 */
export const parseQuery = function (routerName, query, Encode = false) {
    if (Global.Router.CONFIG.encodeURI) {
        return parseQueryN(routerName, query, Encode);
    }
    return parseQueryD(routerName, query, Encode);
};

export const exactRule = function (cloneRule, routes, ruleKey, getRule = false) {
    const params = {};
    let i = 0;
    // eslint-disable-next-line
    while (true) {
        const item = routes[i];
        if (item == null) {
            if (!getRule) {
                err(`路由表中未查找到 '${ruleKey}' 为 '${cloneRule[ruleKey]}'`);
            }
            return {
                path: '',
                name: '',
            };
        }
        if (item[ruleKey] != null && item[ruleKey] === cloneRule[ruleKey]) {
            if (!getRule) {
                params.url = item.path;
                params.rule = item;
                if (isH5()) { // 如果是h5 则使用优先使用自定义路径名称
                    params.url = item.aliasPath || item.path;
                }
                return params;
            }
            return item;
        }
        i += 1;
    }
};

export const resolveRule = function (router, rule, query = {}, ruleKey = 'path') {
    const ruleInfo = route(
        exactRule({
            ...rule,
        },
        router.CONFIG.routes,
        ruleKey,
        router),
    );
    return {
        ...ruleInfo,
        query,
    };
};
/**
 * 把一些不必要的参数进行格式化掉,完成url的美观
 * @param {String} URLQuery URL中传递的参数
 */
export const formatURLQuery = function (URLQuery) {
    switch (URLQuery.trim()) {
    case 'query=%7B%7D':
    case '%7B%7D':
    case '?query=%7B%7D':
    case '?':
    case '?[object Object]':
    case '?query={}':
        URLQuery = '';
        break;
    default:
        warn('url已经很完美啦,不需要格式化!');
        break;
    }
    return URLQuery;
};
/**
 * 拷贝对象
 * @param {Object} object
 */
export const copyObject = function (object) {
    return JSON.parse(JSON.stringify(object));
};