import { Gender } from "@/services/enums";

/** 身份证信息 */
export type IdCardInfo = {
    /** 身份证号码 */
    idNumber: string;
    /** 性别 */
    gender?: Gender;
    /** 出生日期 */
    birthDate?: Date;
    /** 出生日期字符串 */
    birth?: string;
    /** 验证是否成功 */
    success: boolean;
    /** 错误消息 */
    errorMessage: string;
};

// /**
//  * 验证身份证号码
//  * @param id 身份证号码
//  * @returns
//  */
// export function validateIdCard(id: string) {
//     // 15位和18位身份证号码的正则表达式
//     const regIdCard =
//         /^(^[1-9]\d{7}((0\d)|(1[0-2]))(([0|1|2]\d)|3[0-1])\d{3}$)|(^[1-9]\d{5}[1-9]\d{3}((0\d)|(1[0-2]))(([0|1|2]\d)|3[0-1])((\d{4})|\d{3}[Xx])$)$/;

//     const ret: IdCardInfo = {
//         idNumber: id,
//         success: false,
//         errorMessage: '',
//     };

//     if (regIdCard.test(id)) {
//         if (id.length === 18) {
//             const idCardWi = new Array(7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2); // 将前17位加权因子保存在数组里
//             const idCardY = new Array(1, 0, 10, 9, 8, 7, 6, 5, 4, 3, 2); // 这是除以11后，可能产生的11位余数、验证码，也保存成数组
//             let idCardWiSum = 0; // 用来保存前17位各自乖以加权因子后的总和
//             for (let i = 0; i < 17; i++) {
//                 idCardWiSum += parseInt(id.substring(i, i + 1)) * idCardWi[i];
//             }
//             const idCardMod = idCardWiSum % 11; // 计算出校验码所在数组的位置
//             const idCardLast = id.substring(17); // 得到最后一位身份证号码
//             if (idCardMod === 2 && (idCardLast === 'X' || idCardLast === 'x')) {
//                 //如果等于2，则说明校验码是10，身份证号码最后一位应该是X
//                 ret.success = true;
//             } else if (idCardLast === `${idCardY[idCardMod]}`) {
//                 // 用计算出的验证码与最后一位身份证号码匹配，如果一致，说明通过，否则是无效的身份证号码
//                 ret.success = true;
//             }
//             else {
//                 ret.errorMessage = '';
//             }
//         }
//         else {
//             ret.errorMessage = '';
//         }
//     }
//     if (ret.success) {
//         ret.gender = parseInt(id[16]) % 2 === 1 ? Gender.MALE : Gender.FEMALE;
//         ret.birthDate = new Date(
//             parseInt(id.substring(6, 10)),
//             parseInt(id.substring(10, 12)) - 1,
//             parseInt(id.substring(12, 14)),
//         );
//         ret.birth = `${id.substring(6, 10)}-${id.substring(10, 12)}-${id.substring(12, 14)}`;
//     }

//     return ret;
// }

/**
 * 验证身份证号码
 * @param idNumber 身份证号码
 * @returns 
 */
export function validateIdCard(idNumber: string): IdCardInfo {
    const id = idNumber.trim();
    const regIdCard = /(^\d{18}$)|(^\d{17}(\d|X|x)$)/;

    let ret: IdCardInfo = {
        idNumber: id,
        success: false,
        errorMessage: '',
    };

    // 格式验证
    if (!regIdCard.test(id)) {
        ret.errorMessage = '格式（应为18位数字，或17位数字+X）';
        return ret;
    }

    // 出生日期验证
    ret.birth = `${id.substring(6, 10)}-${id.substring(10, 12)}-${id.substring(12, 14)}`;
    const year = parseInt(id.substring(6, 10));
    const month = parseInt(id.substring(10, 12)) - 1;
    const day = parseInt(id.substring(12, 14));
    const birthDate = new Date(year, month, day);
    if (birthDate.getFullYear() !== year || birthDate.getMonth() !== month || birthDate.getDate() !== day) {
        ret.errorMessage = "第7至14位出生日期";
        return ret;
    }
    ret.birthDate = birthDate;

    // 校验码验证
    const idCardWi = new Array(7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2); // 将前17位加权因子保存在数组里
    const idCardY = new Array(1, 0, 10, 9, 8, 7, 6, 5, 4, 3, 2); // 这是除以11后，可能产生的11位余数、验证码，也保存成数组
    let idCardWiSum = 0; // 用来保存前17位各自乖以加权因子后的总和
    for (let i = 0; i < 17; i++) {
        idCardWiSum += parseInt(id.substring(i, i + 1)) * idCardWi[i];
    }
    const idCardMod = idCardWiSum % 11; // 计算出校验码所在数组的位置
    const idCardLast = id.substring(17); // 得到最后一位身份证号码
    if (!(
        idCardMod === 2 && (idCardLast === 'X' || idCardLast === 'x') //如果等于2，则说明校验码是10，身份证号码最后一位应该是X
        || idCardLast === `${idCardY[idCardMod]}` // 用计算出的验证码与最后一位身份证号码匹配，如果一致，说明通过，否则是无效的身份证号码
    )) {
        ret.errorMessage = '第18位（校验位）';
        return ret;
    }

    // 性别
    ret.gender = parseInt(id[16]) % 2 === 1 ? Gender.MALE : Gender.FEMALE;
    ret.success = true;
    return ret;
}

/**
 * 验证手机号码格式
 * @param value 手机号码
 * @param ignoreBlank 是否忽略空
 * @returns
 */
export function validateMobilePhone(value: string, ignoreBlank: boolean = true): boolean {
    const reg_tel = /^(13[0-9]|14[01456879]|15[0-35-9]|16[2567]|17[0-8]|18[0-9]|19[0-35-9])\d{8}$/;
    if (ignoreBlank && (value === null || value === undefined || value === '')) {
        return true;
    }
    return reg_tel.test(value);
}
