import { isObject } from '@vue/shared'
import { cloneDeep } from 'lodash'

/**
 * @description 添加单位
 * @param {String | Number} value 值 100
 * @param {String} unit 单位 px em rem
 */
export const addUnit = (value: string | number, unit = 'px') => {
    return !Object.is(Number(value), NaN) ? `${value}${unit}` : value
}

/**
 * @description 添加单位
 * @param {unknown} value
 * @return {Boolean}
 */
export const isEmpty = (value: unknown) => {
    return value == null && typeof value == 'undefined'
}

/**
 * @description 树转数组，队列实现广度优先遍历
 * @param {Array} data  数据
 * @param {Object} props `{ children: 'children' }`
 */

export const treeToArray = (data: any[], props = { children: 'children' }) => {
    data = cloneDeep(data)
    const { children } = props
    const newData = []
    const queue: any[] = []
    data.forEach((child: any) => queue.push(child))
    while (queue.length) {
        const item: any = queue.shift()
        if (item[children]) {
            item[children].forEach((child: any) => queue.push(child))
            delete item[children]
        }
        newData.push(item)
    }
    return newData
}

/**
 * @description 数组转
 * @param {Array} data  数据
 * @param {Object} props `{ parent: 'pid', children: 'children' }`
 */

export const arrayToTree = (
    data: any[],
    props = { id: 'id', parentId: 'pid', children: 'children' }
) => {
    data = cloneDeep(data)
    const { id, parentId, children } = props
    const result: any[] = []
    const map = new Map()
    data.forEach((item) => {
        map.set(item[id], item)
        const parent = map.get(item[parentId])
        if (parent) {
            parent[children] = parent[children] ?? []
            parent[children].push(item)
        } else {
            result.push(item)
        }
    })
    return result
}

/**
 * @description 获取正确的路经
 * @param {String} path  数据
 */
export function getNormalPath(path: string) {
    if (path.length === 0 || !path || path == 'undefined') {
        return path
    }
    const newPath = path.replace('//', '/')
    const length = newPath.length
    if (newPath[length - 1] === '/') {
        return newPath.slice(0, length - 1)
    }
    return newPath
}

/**
 * @description对象格式化为Query语法
 * @param { Object } params
 * @return {string} Query语法
 */
export function objectToQuery(params: Record<string, any>): string {
    let query = ''
    for (const props of Object.keys(params)) {
        const value = params[props]
        const part = encodeURIComponent(props) + '='
        if (!isEmpty(value)) {
            if (isObject(value)) {
                for (const key of Object.keys(value)) {
                    if (!isEmpty(value[key])) {
                        const params = props + '[' + key + ']'
                        const subPart = encodeURIComponent(params) + '='
                        query += subPart + encodeURIComponent(value[key]) + '&'
                    }
                }
            } else {
                query += part + encodeURIComponent(value) + '&'
            }
        }
    }
    return query.slice(0, -1)
}

/**
 * @description 时间格式化
 * @param dateTime { number } 时间戳
 * @param fmt { string } 时间格式
 * @return { string }
 */
// yyyy:mm:dd|yyyy:mm|yyyy年mm月dd日|yyyy年mm月dd日 hh时MM分等,可自定义组合
export const timeFormat = (dateTime: number, fmt = 'yyyy-mm-dd') => {
    // 如果为null,则格式化当前时间
    if (!dateTime) {
        dateTime = Number(new Date())
    }
    // 如果dateTime长度为10或者13，则为秒和毫秒的时间戳，如果超过13位，则为其他的时间格式
    if (dateTime.toString().length == 10) {
        dateTime *= 1000
    }
    const date = new Date(dateTime)
    let ret
    const opt: any = {
        'y+': date.getFullYear().toString(), // 年
        'm+': (date.getMonth() + 1).toString(), // 月
        'd+': date.getDate().toString(), // 日
        'h+': date.getHours().toString(), // 时
        'M+': date.getMinutes().toString(), // 分
        's+': date.getSeconds().toString() // 秒
    }
    for (const k in opt) {
        ret = new RegExp('(' + k + ')').exec(fmt)
        if (ret) {
            fmt = fmt.replace(
                ret[1],
                ret[1].length == 1 ? opt[k] : opt[k].padStart(ret[1].length, '0')
            )
        }
    }
    return fmt
}

/**
 * @description 获取不重复的id
 * @param length { Number } id的长度
 * @return { String } id
 */
export const getNonDuplicateID = (length = 8) => {
    let idStr = Date.now().toString(36)
    idStr += Math.random().toString(36).substring(3, length)
    return idStr
}

/**
 * 将数字转成中文大写
 * @params num
 */

export const toChinesNum = (money: any) => {
    // 汉字的数字
    const cnNums = ['零', '壹', '贰', '叁', '肆', '伍', '陆', '柒', '捌', '玖']
    // 基本单位
    const cnIntRadice = ['', '拾', '佰', '仟']
    // 对应整数部分扩展单位
    const cnIntUnits = ['', '万', '亿', '兆']
    // 对应小数部分单位
    const cnDecUnits = ['角', '分', '毫', '厘']
    // 整数金额时后面跟的字符
    const cnInteger = '整'
    // 整型完以后的单位
    const cnIntLast = '元'
    // 最大处理的数字
    const maxNum = 999999999999999.9999
    // 金额整数部分
    let integerNum
    // 金额小数部分
    let decimalNum
    // 输出的中文金额字符串
    let chineseStr = ''
    // 分离金额后用的数组，预定义
    let parts
    if (money == '') {
        return ''
    }
    money = parseFloat(money)
    if (money >= maxNum) {
        // 超出最大处理数字
        return ''
    }
    if (money == 0) {
        chineseStr = cnNums[0] + cnIntLast + cnInteger
        return chineseStr
    }
    // 转换为字符串
    money = money.toString()
    if (money.indexOf('.') == -1) {
        integerNum = money
        decimalNum = ''
    } else {
        parts = money.split('.')
        integerNum = parts[0]
        decimalNum = parts[1].substr(0, 4)
    }
    // 获取整型部分转换
    if (parseInt(integerNum, 10) > 0) {
        let zeroCount = 0
        const IntLen = integerNum.length
        for (let i = 0; i < IntLen; i++) {
            const n = integerNum.substr(i, 1)
            const p = IntLen - i - 1
            const q = p / 4
            const m = p % 4
            if (n == '0') {
                zeroCount++
            } else {
                if (zeroCount > 0) {
                    chineseStr += cnNums[0]
                }
                // 归零
                zeroCount = 0
                chineseStr += cnNums[parseInt(n)] + cnIntRadice[m]
            }
            if (m == 0 && zeroCount < 4) {
                chineseStr += cnIntUnits[q]
            }
        }
        chineseStr += cnIntLast
    }
    // 小数部分
    if (decimalNum != '') {
        const decLen = decimalNum.length
        for (let i = 0; i < decLen; i++) {
            const n = decimalNum.substr(i, 1)
            if (n != '0') {
                chineseStr += cnNums[Number(n)] + cnDecUnits[i]
            }
        }
    }
    if (chineseStr == '') {
        chineseStr += cnNums[0] + cnIntLast + cnInteger
    } else if (decimalNum == '') {
        chineseStr += cnInteger
    }
    return chineseStr
}


// 转换每个小节的函数
function convertSection(section) {
    const cnNums = ["零", "壹", "贰", "叁", "肆", "伍", "陆", "柒", "捌", "玖"];
    const cnIntUnits = ["", "拾", "佰", "仟"];


    let sectionStr = "";
    let unitPos = 0; // 记录当前位置的单位
    let zero = true; // 连续的零
  
    while (section > 0) {
      let num = section % 10;
      if (num === 0) {
        if (!zero) {
          zero = true;
          sectionStr = cnNums[num] + sectionStr;
        }
      } else {
        zero = false;
        sectionStr = cnNums[num] + cnIntUnits[unitPos] + sectionStr;
      }
  
      section = Math.floor(section / 10);
      unitPos++;
    }
  
    return sectionStr;
  }
  
/**
 * 将数字人民币转成中文大写
 * @params num
 */

export const convertToChinese = (num: any) => {
    const cnNums = ["零", "壹", "贰", "叁", "肆", "伍", "陆", "柒", "捌", "玖"];
    const cnIntUnits = ["", "拾", "佰", "仟"];
    const cnDecUnits = ["角", "分"];
    const cnInteger = "整";
    const cnIntLast = "元";
    const cnIntWan = "万";
    const cnIntYi = "亿";
  
    let integerNum = Math.floor(num); // 整数部分
    let decimalNum = Math.round((num - integerNum) * 100); // 小数部分
    let cnIntStr = ""; // 中文整数字符串
    let cnDecStr = ""; // 中文小数字符串
  
    // 处理亿位
    let yuan = Math.floor(integerNum / 100000000);
    if (yuan > 0) {
      cnIntStr += convertSection(yuan) + cnIntYi;
      integerNum %= 100000000;
    }
  
    // 处理万位
    let wan = Math.floor(integerNum / 10000);
    if (wan > 0) {
      cnIntStr += convertSection(wan) + cnIntWan;
      integerNum %= 10000;
    }
  
    // 处理其他部分
    if (integerNum === 0) {
      cnIntStr += cnNums[0];
    } else {
      cnIntStr += convertSection(integerNum);
    }
  
    // 处理小数部分
    if (decimalNum === 0) {
      cnDecStr = cnInteger;
    } else {
      let decIndex = 0;
      while (decimalNum > 0 && decIndex < cnDecUnits.length) {
        let num = decimalNum % 10;
        if (num !== 0) {
          cnDecStr += cnNums[num] + cnDecUnits[decIndex];
        }
        decimalNum = Math.floor(decimalNum / 10);
        decIndex++;
      }
    }
  
    return cnIntStr + cnIntLast + cnDecStr;
}




  
  