import moment from 'moment'
import storeInfo from '../../store/index'
import router from "../../router"
import { isIdentityId } from '@/views/utils/validate'
import * as XLSX from 'xlsx'
import * as XLSXStyle from 'xlsx-style'
import { FundFilled } from '@ant-design/icons'

//对象、一维数组去重(返回一个新数组)
export const singleArr = (arr, val) => {
    let newArr = arr.concat()
    let len = newArr.length;
    if (val) {
        for (let i = 0; i < len; i++) {
            for (let j = i + 1; j < len; j++) {
                if (newArr[i][val] == newArr[j][val]) {
                    newArr.splice(j, 1);
                    len--;
                    j--;
                }
            }
        }
    } else {
        for (let i = 0; i < len; i++) {
            for (let j = i + 1; j < len; j++) {
                if (newArr[i] == newArr[j]) {
                    newArr.splice(j, 1);
                    len--;
                    j--;
                }
            }
        }
    }

    return newArr;
}

//删除关闭详情的页面
export const closedDetail = (url, goToUrl) => {
    let tabs = JSON.parse(window.sessionStorage.getItem('tabs'))
    for (let i = 0; i < tabs.length; i++) {
        if (tabs[i].key == url) {
            tabs.splice(i, 1)
            window.sessionStorage.setItem('tabs', JSON.stringify(tabs))
            storeInfo.commit('changeTabs', tabs)
            if (goToUrl) {
                router.push(goToUrl)
            } else {
                router.push(tabs[i - 1].path)
            }
        }
    }


}
//判断对象values是否为空 并返回不为空对象
export const isEmptyParams = (obj) => {
    let obje = {}
    Object.assign(obje, obj)
    for (let key in obje) {
        if (obje[key] === '' || typeof obje[key] === 'undefined' || obje[key] === null || obje[key].length == 0) {
            delete obje[key]
        }
        if (obje[key] instanceof Array) {
            for (let i in obje[key]) {
                if (obje[key][i] instanceof Object) {
                    for (let j in obje[key][i]) {
                        if (obje[key][i][j] === '' || typeof obje[key][i][j] === 'undefined' || obje[key][i][j] === null || obje[key][i][j].length == 0) {
                            delete obje[key][i][j]
                        }
                    }
                }
            }
        }
    }
    return obje
}

//数组转为树形结构
// toTree(数组,父id,父id属性key, id当前节点id key)
export const toTree = (list, parId, pId, id) => {
    let len = list.length
    function loop (parId) {
        let res = [];
        for (let i = 0; i < len; i++) {
            let item = list[i]
            if (item[pId] == parId) {
                item.children = loop(item[id])
                res.push(item)
            }
        }
        return res
    }
    return loop(parId)
}

//树形数据转数组
export const treeToArray = (source) => {
    let res = []
    const fn = (source) => {
        source.forEach(el => {
            res.push(el)
            el.children && el.children.length > 0 ? fn(el.children) : ""
        })
        return res
    }
    return fn(source)
}

//删除树状结构数据中空children
export const removeEmptyChildren = (data) => {
    data.forEach(item => {
        if (item.children === null || item.children.length === 0) {
            delete item.children
        } else {
            removeEmptyChildren(item.children)
        }
    })
    return data
}

//修改时间格式
export const timeFormat = (time, format = 'YYYY-MM-DD') => {
    let atime = moment(time).format(format)
    return atime
}

/**
 * 非空判断 已挂载到原型上$isNot
 * 解决Vue Template模板中无法使用可选链的问题
 * eg:
 * let ces = {
                    data: {
                        data1: {
                            name: '测试'
                        }
                    }
                }
 let b = this.$isNot(ces, 'data', 'data1', 'name') //测试
 {{$isNot(ces, 'data', 'data1', 'name')}} //测试
 */
// export const optionalChaining = (obj, ...rest) => {
//     let tmp = obj;
//     for (let key in rest) {
//         let name = rest[key];
//         tmp = tmp?.[name]; //es11可选链
//     }
//     return tmp ?? "未知";
// };

// 校验时间域
export const checkDateRange = (rule, dates, callback) => {
    if (dates.length === 2) {
        if (!dates[0] || !dates[1]) {
            callback('请选择时间')
        } else {
            callback()
        }
    } else {
        callback('请选择时间')
    }
}

// 校验手机号
export const checkPhone = (rule, value, callback) => {
    if (value == '' || value == undefined) {
        callback()
    }
    var ckPhone = /^1(?:3[0-9]|4[5-9]|5[0-9]|6[12456]|7[0-8]|8[0-9]|9[0-9])[0-9]{8}$/;
    if (ckPhone.test(value)) {
        callback()
    } else {
        callback(new Error('请输入正确的手机号'));
    }
}

export const checkEmail = (rule, value, callback) => {
    if (value == '' || value == undefined) {
        callback()
    }
    var ckEmail = /^([a-zA-Z0-9_-])+@([a-zA-Z0-9_-])+(\.[a-zA-Z0-9_-])+/;
    if (ckEmail.test(value)) {
        callback()
    } else {
        callback(new Error('请输入正确的邮箱'));
    }
}

export const checkIdentitytionId = (rule, value, callback) => {
    if (value == '' || value == undefined) {
        callback()
    }
    var errorMsg = isIdentityId(value);
    if (errorMsg != "") {
        callback(new Error(errorMsg));
    }
    callback()
}

export const personBirthday = (identityId) => {
    return (
        identityId.substr(6, 4) +
        "-" +
        Number(identityId.substr(10, 2)) +
        "-" +
        Number(identityId.substr(12, 2))
    )
    //return new Date(sBirthday);
}

export const personGender = (identityId) => {
    let sex = identityId.substr(16, 1)
    return sex % 2 === 0 ? '女' : '男'
}

//根据枚举标识获取下拉数据
export const getEnumByFlag = (enumFlag) => {
    let result = []
    let enumSessionStorange = JSON.parse(window.sessionStorage.getItem('allEnum'))
    if (enumSessionStorange && enumFlag) {
        for (let obj in enumSessionStorange) {
            if (obj == enumFlag) {
                result = enumSessionStorange[obj]
            }
        }
    }
    return result
}

/**
 * 获取js变量的数据类型
 * @param obj
 * @returns {*}
 */
export const getType = (obj) => {
    const type = typeof obj;
    if (type !== 'object') {
        return type;
    }
    return Object.prototype.toString.call(obj).replace(/^\[object (\S+)\]$/, '$1');
};

/**
 * 把文件按照二进制进行读取
 * @param file 
 * @returns 
 */
export function readFile (file) {
    return new Promise(resolve => {
        let reader = new FileReader();
        reader.readAsBinaryString(file);
        reader.onload = ev => {
            resolve(ev.target?.result);
        }
    });
}

export function hideIdCard (idCard) {
    return idCard.replace(/^(.{8})(?:\w+)(.{1})$/, "\$1*********\$2")
}

export function hidePhone (phone) {
    return phone.replace(/(\d{3})\d{4}(\d{4})/, '\$1****\$2');
}

export function getCardInfo (idCard) {
    let sex = null;
    let birth = null;
    let myDate = new Date();
    let month = myDate.getMonth() + 1;
    let day = myDate.getDate();
    let age = 0;

    if (idCard.length === 18) {
        age = myDate.getFullYear() - idCard.substring(6, 10) - 1;
        sex = idCard.substring(16, 17);
        birth = idCard.substring(6, 10) + "-" + idCard.substring(10, 12) + "-" + idCard.substring(12, 14);
        if (idCard.substring(10, 12) < month || idCard.substring(10, 12) === month && idCard.substring(12, 14) <= day) age++;

    }
    if (idCard.length === 15) {
        age = myDate.getFullYear() - idCard.substring(6, 8) - 1901;
        sex = idCard.substring(13, 14);
        birth = "19" + idCard.substring(6, 8) + "-" + idCard.substring(8, 10) + "-" + idCard.substring(10, 12);
        if (idCard.substring(8, 10) < month || idCard.substring(8, 10) === month && idCard.substring(10, 12) <= day) age++;
    }

    if (sex % 2 === 0)
        sex = '女';  // 性别代码 1代表男,0代表女,暂时不涉及其他类型性别
    else
        sex = '男';
    return { age, sex, birth }
}

export async function readExcelFile (file, sheetIndex) {
    let data = await readFile(file);
    let workbook = XLSX.read(data, { type: 'binary' });
    let worksheet = workbook.Sheets[workbook.SheetNames[sheetIndex]];
    data = XLSX.utils.sheet_to_json(worksheet);
    return data;
}

/**
 * @function 生成表格的方法
 * @param {String} excelName 文件名
 * @param {Array} titleArr 数据表头显示
 * @param {Array} dataArr 数据内容显示
 */
export const ToDoExcel = (excelName, titleArr, dataArr) => {
    var filename = excelName + ".xlsx" //文件名称
    var data = [titleArr, ...dataArr]  //数据,一定注意需要时二维数组
    var ws_name = "Sheet1" //Excel第一个sheet的名称
    var wb = XLSX.utils.book_new(), ws = XLSX.utils.aoa_to_sheet(data)
    XLSX.utils.book_append_sheet(wb, ws, ws_name)  //将数据添加到工作薄
    XLSX.writeFile(wb, filename)
}

/**
 * 生成导出Excel的数据数组
 * @param {Array} tableColumns 列名数组
 * @param {Array} tableData 导出数据
 * @returns 
 */
export const filterExportExcelData = (tableColumns, tableData) => {
    let arr = []
    tableData.forEach((val, index, val_arr) => {
        let arr1 = []
        for (let j = 0; j < tableColumns.length; j++) {
            for (let i = 0; i < Object.getOwnPropertyNames(val).length; i++) {
                if (tableColumns[j].dataIndex === undefined) {
                    if (tableColumns[j].scopedSlots.customRender === Object.keys(val)[i]) {
                        arr1.push(val[Object.keys(val)[i]])
                        break
                    }
                }
                else if (tableColumns[j].dataIndex === Object.keys(val)[i]) {
                    arr1.push(val[Object.keys(val)[i]])
                    break
                }
            }
        }
        arr.push(arr1)
    })
    return arr
}

/**
 * 生成导出Excel列名
 * @param {Array} tableColumns 列名数组
 */
export const tableColumnsName = (tableColumns) => {
    let arr = []
    tableColumns.map((item) => {
        if (item.title !== '操作')
            arr.push(item.title)
    })
    return arr
}

/**
 * 生成UUID
 * @returns 
 */
export function CreateUUID () {
    var s = [];
    var hexDigits = "0123456789abcdef";
    for (var i = 0; i < 36; i++) {
        s[i] = hexDigits.substr(Math.floor(Math.random() * 0x10), 1);
    }
    s[14] = "4"; // bits 12-15 of the time_hi_and_version field to 0010
    s[19] = hexDigits.substr((s[19] & 0x3) | 0x8, 1); // bits 6-7 of the clock_seq_hi_and_reserved to 01
    s[8] = s[13] = s[18] = s[23] = "-";

    var uuid = s.join("");
    return uuid;
}

export function getFileExtension (fileName) {
    return fileName.substring(fileName.lastIndexOf('.') + 1, fileName.length).toLowerCase()
}

/**
 * 验证文件是否为图片
 * @param {文件名称} fileName 
 * @returns 
 */
export function checkImageFileType (fileName) {
    let fileType = getFileExtension(fileName).toLowerCase()
    var imgType = ['bmp', 'jpg', 'jpeg', 'png', 'tif', 'gif', 'pcx', 'tga', 'exif', 'fpx', 'svg', 'psd', 'cdr', 'pcd', 'dxf', 'ufo', 'eps', 'ai', 'raw', 'WMF', 'webp', 'avif', 'apng']
    if (imgType.includes(fileType))
        return true
    else
        return false
}

/**
 * 验证文件是否为可查看文件
 * @param {文件名称} fileName 
 * @returns 
 */
export function checkDocumentFileType (fileName) {
    let fileType = getFileExtension(fileName).toLowerCase()
    var wordType = ['text', 'pdf', 'doc', 'docx', 'xls', 'xlsx', 'bmp', 'jpg', 'jpeg', 'png', 'tif', 'gif']
    //'ppt','pptx','rar','zip','7z','apz','ar','bz','car','dar','cpgz','f','ha','hbc','hbc2','hbe','hpk','hyp'
    if (wordType.includes(fileType))
        return true
    else
        return false
}

const enums = {
    fileColor: {
        text: 'gray',
        pdf: 'red',
        doc: 'blue',
        docx: 'blue',
        xls: 'green',
        xlsx: 'green',
        bmp: 'pink',
        jpg: 'pink',
        jpeg: 'pink',
        png: 'pink',
        tif: 'pink',
        gif: 'pink'
    }
}
export { enums }

export function toTextarea (str) {
    if (str == undefined) {
        return ''
    }
    str = str.replace(/\n|\r\n/g, '<br>')
    str = str.replace(/ /g, ' &nbsp')
    return str
}

export function mergeRow (key, data) {
    const tableData = data
    for (var i = 0; i < tableData.length; i++) {
        const item = tableData[i]
        let count = 1
        for (let j = i + 1; j < tableData.length; j++) {
            // 如果是同一个值,往后递增
            if (item[key] === tableData[j][key]) {
                count++
                // 往后相同的值都设为空单元格
                tableData[j][`${key}RowSpan`] = 0
                // 只有同值第一个才设置合并的单元格数
                item[`${key}RowSpan`] = count
                // 所有都是为同一个值的情况
                // 如果到了尾部,则循环结束
                if (j === tableData.length - 1) {
                    return tableData
                }
            } else {
                // 指针跳转到下一个,从下一排开始
                i = j - 1
                count = 1
                tableData[j][`${key}RowSpan`] = 0
                break
            }
        }
    }
    return tableData
}