import ls from '@/utils/Storage'
import { ACCESS_TOKEN, PERMISSION, USER_INFO, MENU_NAV, DEPART_INFO, ROLE_INFO, TOKEN, GOLBAL_TBSDY } from '@/store/mutation-types'
import dayjs from 'dayjs';
import utc from 'dayjs/plugin/utc'
import timezone from 'dayjs/plugin/timezone'
import { VaildMessageConstant } from './constant.js'

dayjs.extend(utc)
dayjs.extend(timezone)

export function clearUserInfo() {
    ls.remove(ACCESS_TOKEN)
    ls.remove(PERMISSION)
    ls.remove(USER_INFO)
    ls.remove(DEPART_INFO)
    ls.remove(GOLBAL_TBSDY)
    ls.remove(ROLE_INFO)
    ls.remove(TOKEN)
    ls.remove(USER_INFO)
    ls.remove(MENU_NAV)
}

export function timeFix() {
    const time = new Date()
    const hour = time.getHours()
    return hour < 9 ? '早上好' : hour <= 11 ? '上午好' : hour <= 13 ? '中午好' : hour < 20 ? '下午好' : '晚上好'
}

// aes encryption key
export const encryptKeys = {
    // key最少4位,否则报错
    key: '1111',
    iv: '1',
};

export const getQueryParameters = (options) => {
    const url = options.url
    const search = url.split('?')[1]
    if (!search) {
        return {}
    }
    return JSON.parse('{"' + decodeURIComponent(search)
        .replace(/"/g, '\\"')
        .replace(/&/g, '","')
        .replace(/=/g, '":"') + '"}')
}

export const getBody = (options) => {
    return options.body && JSON.parse(options.body)
}

export function scorePassword(pass) {
    let score = 0
    if (!pass) {
        return score
    }
    // award every unique letter until 5 repetitions
    const letters = {}
    for (let i = 0; i < pass.length; i++) {
        letters[pass[i]] = (letters[pass[i]] || 0) + 1
        score += 5.0 / letters[pass[i]]
    }

    // bonus points for mixing it up
    const variations = {
        digits: /\d/.test(pass),
        lower: /[a-z]/.test(pass),
        upper: /[A-Z]/.test(pass),
        nonWords: /\W/.test(pass)
    }

    let variationCount = 0
    for (var check in variations) {
        variationCount += (variations[check] === true) ? 1 : 0
    }
    score += (variationCount - 1) * 10

    return parseInt(score)
}

export const firstLetterIsUpperCase = function (str) {
    var reg = /^[A-Z][A-z0-9]*$/;
    return reg.test(str);
};

export const separator = ';'

export const divisionStringToArray = (string, customSeparator) => {
    return string ? string.split(customSeparator || separator) : []
}

export const getWeek = (week: number, useZhou) => {
    let txt = ''
    switch (week) {
        case 1:
            txt = '一'
            break
        case 2:
            txt = '二'
            break
        case 3:
            txt = '三'
            break
        case 4:
            txt = '四'
            break
        case 5:
            txt = '五'
            break
        case 6:
            txt = '六'
            break
        case 0:
            txt = '日'
            break
        default:
            return 'getWeekError'
    }
    return useZhou ? '周' : '星期' + txt
}

const sitUrl = 'xxxxx'
export const isDev = import.meta.env.DEV
export const baseURL = isDev ? '/api/' : '生产地址'

export function toLocalTimeStr({ date, format = 'YYYY-MM-DD HH:mm:ss' }) {
    if (!date) return null;
    return dayjs(date).format(format)
}

export function objToArr(obj) {
    let arr: any = []
    for (const o in obj) {
        arr.push({ label: o, txt: obj[o] })
    }
    return arr
}

export function clearObj(obj) {
    for (const key in obj) {
        obj[key] = undefined
    }
}

export function delArrItem(arr, item) {
    const index = arr.indexOf(item);
    arr.splice(index, 1);
}

export const useImageUrl = (name: string, type: string = 'png'): string => {
    /**
     * @method vite动态引入图片
     * @params folder 文件夹名称 name 文件名称 type 文件格式 一般为png/jpg/webp/gif等...
     * @returns 图片
     */
    return new URL(`../assets/images/${name}.${type}`, import.meta.url).href
}

export const batchDispatch = (dispatch, arr) => {
    arr.forEach(item => {
        dispatch(item)
    });
}

export const createFormData = (formDatas, file) => {
    const formData = new FormData()
    if (file.length) {
        file.map(item => {
            formData.append('file', item)
        })
    } else {
        formData.append('file', file)
    }
    for (const item in formDatas) {
        formData.append(item, formDatas[item] || '')
    }
    return formData
}

/**
 * 重构rules,对必输，最小长度，最大长度校验信息进行处理
 * @param {*} rules
 * @param {*} propLabel
 * @param {*} propLabel  upKey上一层key
 */
export function rebuildVaildMessage(rules, propLabel, upKey) {
    for (let key in rules) {
        let rule = rules[key]
        //解决嵌套rules校验提示信息无法修复问题，rules:{a:{b:[max:5]}}
        if (rule?.constructor == Object) {
            rebuildVaildMessage(rule, propLabel, key)
        }
        if (upKey) {
            key = upKey + "." + key
        }
        let label = propLabel[key]
        //prop与label映射中不存在该key时直接放过
        if (!label) continue
        if (rule && rule.length > 0) {
            rule.forEach(item => {
                let { required, max, min, type } = item
                let props = { label, max, min }
                //必输检验提示信息
                if (required && VaildMessageConstant.required) {
                    item.message = formatString(VaildMessageConstant.required, props)
                    //最大长度检验提示信息
                } else if (max != undefined && min == undefined && VaildMessageConstant.max) {
                    //max对字符串、数组进行长度比较;对数字进行值比较
                    if (type == "number") {
                        item.message = formatString(VaildMessageConstant.number_max, props)
                    } else {
                        item.message = formatString(VaildMessageConstant.max, props)
                    }
                    //最小长度检验提示信息
                } else if (max == undefined && min != undefined && VaildMessageConstant.min) {
                    if (type == "number") {
                        item.message = formatString(VaildMessageConstant.number_min, props)
                    } else {
                        item.message = formatString(VaildMessageConstant.min, props)
                    }
                    //长度区间
                } else if (max != undefined && min != undefined && VaildMessageConstant.range) {
                    if (type == "number" && VaildMessageConstant.number_range) {
                        item.message = formatString(VaildMessageConstant.number_range, props)
                    } else {
                        item.message = formatString(VaildMessageConstant.range, props)
                    }
                }
            })
        }
    }
}

/**
 * 格式化字符串
 * @param {*} string  要格式化的字符串  "${label}不能为空!"
 * @param {*} props   格式化参数  {label:"用户名"}
 */
export function formatString(string, props) {
    if (props) {
        const keys = Object.keys(props)
        keys.forEach(key => {
            if (string) {
                string = string.replace("${" + key + "}", props[key])
            }
        })
        return string
    }
    return string
}

/**
 * 金额格式化(三位一逗)
 * @param {*} value
 * @returns
 */
export function amtFormatter(value) {
    if (value == undefined || value == null) {
        value = ""
    }
    value = value + ""
    const data = value.split(".")
    if (data.length == 1) {
        return `${data[0]}`.replace(/\B(?=(\d{3})+(?!\d))/g, ',')
    } else {
        return `${data[0]}`.replace(/\B(?=(\d{3})+(?!\d))/g, ',') + "." + data[1]
    }
}

/**
 * 文件流转blob对象下载,请求中需添加responseType: 'blob'
 * @param {*} data blob数据
 * @param {*} fileName 下载的文件名
 */
export function downloadFile(data, fileName) {
    if (window.navigator && window.navigator.msSaveOrOpenBlob) {
        //兼容ie浏览器
        window.navigator.msSaveOrOpenBlob(data, fileName)
    } else {
        //谷歌,火狐等浏览器
        let url = window.URL.createObjectURL(data)
        let downloadElement = document.createElement("a")
        downloadElement.style.display = "none"
        downloadElement.href = url
        downloadElement.download = fileName
        document.body.appendChild(downloadElement)
        downloadElement.click()
        document.body.removeChild(downloadElement)
        window.URL.revokeObjectURL(url)//释放data
    }
}

/**
 * This is just a simple version of deep copy
 * Has a lot of edge cases bug
 * If you want to use a perfect deep copy, use lodash's _.cloneDeep
 * @param {Object} source
 * @returns {Object}
 */
export function deepClone(source) {
    if (!source && typeof source !== 'object') {
        throw new Error('error arguments', 'deepClone')
    }
    const targetObj = source.constructor === Array ? [] : {}
    Object.keys(source).forEach(keys => {
        if (source[keys] && typeof source[keys] === 'object') {
            targetObj[keys] = deepClone(source[keys])
        } else {
            targetObj[keys] = source[keys]
        }
    })
    return targetObj
}

/**
 * 获取数组项的索引，当没有找到该项时返回-1
 * @param a 数组
 * @param o 数组中的项
 * @param id
 * @returns
 */
export function indexOfArray(a, o, id) {
    for (let i = 0, len = a.length; i < len; i++) {
        if (id == undefined) {
            if (a[i] == o) { return i; }
        } else {
            if (a[i][o] == id) { return i; }
        }
    }
    return -1;
}
