/*
  全局引入方式：src/main.js

  import * as filters from './app/core/utils/filters.util' // global filters

  // 注册全局的过滤器，在页面上直接使用无须再显示定义过滤器
  Object.keys(filters).forEach(key => {
    Vue.filter(key, filters[key])
  })

  使用方式：在页面中直接使用
  <template>
    {{'abc' | uppercaseFirst}}
  </template>
*/


/**
 * Parse the time to string
 * @param {(Object|string|number)} time
 * @param {string} cFormat
 * @returns {string | null}
 */
export function parseTime(time, cFormat) {
    if (arguments.length === 0 || !time) {
        return null
    }
    const format = cFormat || '{y}-{m}-{d} {h}:{i}:{s}'
    let date
    if (typeof time === 'object') {
        date = time
    } else {
        if ((typeof time === 'string')) {
            if ((/^[0-9]+$/.test(time))) {
                // support "1548221490638"
                time = parseInt(time)
            } else {
                // support safari
                // https://stackoverflow.com/questions/4310953/invalid-date-in-safari
                time = time.replace(new RegExp(/-/gm), '/')
            }
        }

        if ((typeof time === 'number') && (time.toString().length === 10)) {
            time = time * 1000
        }
        date = new Date(time)
    }
    const formatObj = {
        y: date.getFullYear(),
        m: date.getMonth() + 1,
        d: date.getDate(),
        h: date.getHours(),
        i: date.getMinutes(),
        s: date.getSeconds(),
        a: date.getDay()
    }
    const time_str = format.replace(/{([ymdhisa])+}/g, (result, key) => {
        const value = formatObj[key]
        // Note: getDay() returns 0 on Sunday
        if (key === 'a') {
            return ['日', '一', '二', '三', '四', '五', '六'][value]
        }
        return value.toString().padStart(2, '0')
    })
    return time_str
}

/**
 * @param {number} time
 * @param {string} option
 * @returns {string}
 */
export function formatTime(time, option) {
    if (('' + time).length === 10) {
        time = parseInt(time) * 1000
    } else {
        time = +time
    }
    const d = new Date(time)
    const now = Date.now()

    const diff = (now - d) / 1000

    if (diff < 30) {
        return '刚刚'
    } else if (diff < 3600) {
        // less 1 hour
        return Math.ceil(diff / 60) + '分钟前'
    } else if (diff < 3600 * 24) {
        return Math.ceil(diff / 3600) + '小时前'
    } else if (diff < 3600 * 24 * 2) {
        return '1天前'
    }
    if (option) {
        return parseTime(time, option)
    } else {
        return (
            d.getMonth() +
            1 +
            '月' +
            d.getDate() +
            '日' +
            d.getHours() +
            '时' +
            d.getMinutes() +
            '分'
        )
    }
}

/**
 * @param {string} url
 * @returns {Object}
 */
export function param2Obj(url) {
    const search = decodeURIComponent(url.split('?')[1]).replace(/\+/g, ' ')
    if (!search) {
        return {}
    }
    const obj = {}
    const searchArr = search.split('&')
    searchArr.forEach(v => {
        const index = v.indexOf('=')
        if (index !== -1) {
            const name = v.substring(0, index)
            const val = v.substring(index + 1, v.length)
            obj[name] = val
        }
    })
    return obj
}

/**
 * Show plural label if time is plural number
 * @param {number} time
 * @param {string} label
 * @return {string}
 */
function pluralize(time, label) {
    if (time === 1) {
        return time + label
    }
    return time + label + 's'
}

/**
 * @param {number} time
 */
export function timeAgo(time) {
    const between = Date.now() / 1000 - Number(time)
    if (between < 3600) {
        return pluralize(~~(between / 60), ' minute')
    } else if (between < 86400) {
        return pluralize(~~(between / 3600), ' hour')
    } else {
        return pluralize(~~(between / 86400), ' day')
    }
}

/**
 * Number formatting
 * like 10000 => 10k
 * @param {number} num
 * @param {number} digits
 */
export function numberFormatter(num, digits) {
    const si = [
        {value: 1E18, symbol: 'E'},
        {value: 1E15, symbol: 'P'},
        {value: 1E12, symbol: 'T'},
        {value: 1E9, symbol: 'G'},
        {value: 1E6, symbol: 'M'},
        {value: 1E3, symbol: 'k'}
    ]
    for (let i = 0; i < si.length; i++) {
        if (num >= si[i].value) {
            return (num / si[i].value).toFixed(digits).replace(/\.0+$|(\.[0-9]*[1-9])0+$/, '$1') + si[i].symbol
        }
    }
    return num.toString()
}

/**
 * 10000 => "10,000"
 * @param {number} num
 */
export function toThousandFilter(num) {
    return (+num || 0).toString().replace(/^-?\d+/g, m => m.replace(/(?=(?!\b)(\d{3})+$)/g, ','))
}

/**
 * Upper case first char
 * @param {String} string
 */
export function uppercaseFirst(string) {
    return string.charAt(0).toUpperCase() + string.slice(1)
}

/**
 * 保留两位小数点
 * @param value
 * @returns {*|string}
 */
export function toFixed2(value) {
    let result = ''
    if (value) {
        // 截取当前数据到小数点后两位
        result = value.toFixed(2)
    } else {
        result = '0.00'
    }
    return result
}

/**
 * 保留小数点位数
 * @param value
 * @param retain 保留小数点位数
 * @returns {*|string}
 */
export function toFixed(value, retain = 0) {
    let result = ''
    if (value) {
        // 截取当前数据到小数点后两位
        result = value.toFixed(retain)
    } else {
        result = 0.0.toFixed(retain);
    }
    return result
}

/**
 * 如果是null，则显示成空字符串
 * @param value
 * @param defaultValue
 * @returns {string}
 */
export function toEmptyStr(value, defaultValue) {
    value = value + '' // 转成字符串，数字没有.replace方法。
    if (value === null || value === undefined || value === 'null' || value === 'undefined' || value.replace(/(^\s*)|(\s*$)/g, '') === '') {
        if (defaultValue) {
            return defaultValue
        }
        return ''
    }
    return value
}

/**
 * 后台返回的base64字符串图片前端不能显示，需要使用这个过滤器后才能显示出来
 * @param value
 * @returns {*}
 */
export function captchaSrc(value) {
    let result = ''
    if (value) {
        return value.replace(/[\r\n]/g, '')
    }
    return result
}

/**
 * 输出对象某个属性值，如果属性不存在则返回null，防止a.b.c时a或b为null输出属性c报错。
 * @param value 实际对象需要调用的属性字符串形式
 * @param target 实际对象
 * @param defaultValue 如果对象中间的某个属性不存在则会报错，则返回默认值
 * @returns {*}
 *
 * 使用方式：
 *  过滤器作用：{{'selectedItem.code' | toValue(selectedItem)}}
 *  当普通函数使用：{{toValue('selectedItem.code', selectedItem) + 'abc'}}   // 需要在src/main.js配置Vue.prototype[key] = filters[key]
 */
export function toValue(value, target, defaultValue = null) {
    if (!target) {
        return defaultValue
    }
    let attrs = value.split('.')
    let clone = Object.assign({}, target)
    for (let i = 1; i < attrs.length; i++) {
        let attr = attrs[i]
        if (i < attrs.length - 1) {
            if (!clone[attr]) {
                return defaultValue
            } else {
                clone = clone[attr]
            }
        } else {
            return clone[attr]
        }
    }
    return defaultValue
}

