/**
 * @description  公共方法
 * @author       朱琦
 * @date         2022/3/4
 */

/**
 * 过滤点位数据
 * @param {Array} data 数据
 * @param {String} id 键值名
 * @param {String | Function} name 键值名 或 模板字符串
 * @param {String} lon 经度 键值名
 * @param {String} lat 纬度 键值名
 * @param { String | Function | Array} iconFilter 图标配置 非必传
 * @param {Object}  extend 扩展数据
 * @returns {Array} 过滤后的数据
 */
const filterPointData = (data, id, name, lon, lat, iconFilter, extend = {}) => {
    let list = []
    if (!data || data.length === 0) {
        return list
    }

    if (name && name.constructor === String && !RegExp(/\{\{(\w+)\}\}/).test(name)) {
        name = `{{${name}}}`
    }

    data.forEach(item => {
        const lonVal = parseFloat(getObjVal(item, lon))
        const latVal = parseFloat(getObjVal(item, lat))
        if (lonVal && latVal) {
            let nameText = null
            if (name) {
                nameText = name.constructor === Function ? name(item) : getTemplateVal(name, item)
            }
            list.push({
                ...item,
                ...extend,
                id: getObjVal(item, id),
                name: nameText,
                path: [lonVal, latVal],
                icon: getIconName(item, iconFilter)
            })
        }
    })
    return list
}

/**
 * 获取icon图标名
 * @param {Object} item 单项数据
 * @param {Array} iconFilter icon过滤规则
 * @returns icon name
 */
const getIconName = (item, iconFilter) => {
    if (!iconFilter) return null

    let icon = null
    if (iconFilter.constructor === Function) {
        // 函数
        icon = iconFilter(item)
    } else if (iconFilter.constructor === Array && iconFilter.length) {
        // 数组
        const arr = [...iconFilter]
        const length = arr.length

        if (length == 1) {
            icon = arr[0]
        } else {
            let func = arr[length - 1]
            let newArr = arr.concat()
            newArr.pop()
            const keyArr = newArr.map(i => item[i])
            icon = func(keyArr)
        }
    } else if (iconFilter.constructor === String) {
        // 字符串
        icon = iconFilter
    }

    return icon
}

/**
 * 获取 模板字符串解析 结果
 * @param {String} template 模板字符串解析
 * @param {Object} data     数据
 * @returns {String} 解析结果
 */
const getTemplateVal = (template, data) => {
    let string = template
    if (template && data) {
        string = template.replace(/\{\{([\w.]+)\}\}/g, (match, key) => {
            return getObjVal(data, key) || ''
        })
    }
    return string;
}

/**
 * 获取对象里的对应的键值
 * @param {Object} object 对象
 * @param {String} key 查询嵌套的键值以点连接，例 'obj.a'
 * @param {String} defaultVal 查找结果为非真时，返回的默认值
 * @returns value 查找到的键值
 */
const getObjVal = (object, key, defaultVal) => {
    if (!key || key.length <= 0) {
        return null
    }

    const sp = key.split('.')
    let returnValue = object
    for (const i in sp) {
        returnValue = returnValue[sp[i]]
        if (!returnValue) return defaultVal
    }
    return returnValue
}

/**
 * 合并过滤数组对象
 * @param {Array} originalArray 原始数组
 * @param {Array} newArray      新数组
 * @param {Sting} key           对比的key值
 * @returns {Array} 合并过滤后的数组
 */
const concatArrayObject = (originalArray, newArray, key) => {
    const newArr = [...newArray]
    const originalArr = originalArray.map(item => {
        let obj = null
        const index = newArr.findIndex(i => i[key] === item[key])
        if (index > -1) {
            obj = newArr[index]
            newArr.splice(index, 1)
        }
        return {
            ...item,
            ...obj
        }
    })
    return originalArr.concat(newArr)
}

/**
 * 递归组件的所有子组件 执行方法并传参 仅vue2可用
 * @param {vue component} component vue 组件
 * @param {String} funName 方法名
 * @param {any} param 参数
 */
const getComponentChildren = (component, funName, param) => {
    try {
        component[funName] && component[funName](param);
        component.$children.forEach((chilComponent) => getComponentChildren(chilComponent, funName, param))
    } catch (e) {
        console.error("map load event,exception is " + e);
    }
}

const isValidPath = (path) => {
    if (!path || path.constructor !== Array || !path.length) return false

    if (path[0].constructor !== Array) {
        if (!Number(path[0]) || !Number(path[1])) return false
    }

    return true
}

export {
    filterPointData,
    getTemplateVal,
    concatArrayObject,
    getComponentChildren,
    getIconName,
    isValidPath,
    getObjVal
}