import useUserStore from "../stores/useUserStore";
import { sm4Encrypt, sm4Decrypt } from '@/utils/crypto';

import {
    request,
    createRequest,
    uploadFile,
	myRequest
} from "../utils/request";
import streamRequest, {
    chatRequest
} from "../utils/streamRequest.js";

export const CloneDeep = (props) => {
    if (typeof props !== 'object' || props === null) {
        return props
    }

    let result
    if (props) {
        result = []
    } else {
        result = {}
    }

    for (let key in props) {
        if (props.hasOwnProperty(key)) {
            result[key] = CloneDeep(props[key])
        }
    }

    return result
}


export const msg = (title, duration = 1500, mask = false, icon = 'none', image) => {
    if (Boolean(title) === false) {
        return;
    }
    uni.showToast({
        title,
        duration,
        mask,
        icon,
        image
    });
}

const prePage = () => {
    let pages = getCurrentPages();
    let prePage = pages[pages.length - 2];
    return prePage.$vm;
}

// export const urls ='http://10.110.145.145/images/train/'
export const urls ='https://www.xjksly.cn/images/train/'

/**
 * 页面跳转封装，支持 query 参数传递和返回回调
 * @param {string} url - 跳转路径
 * @param {object} options
 * @param {boolean} options.needLogin - 是否需要登录
 * @param {object} options.query - 携带参数
 * @param {function} options.onBack - 页面返回时的回调（目标页调用 uni.navigateBack 时传递数据）
 */
export const navTo = function(url, {
    needLogin = false,
    query = {},
    onBack = null
} = {}) {
    const userStore = useUserStore();

    if (needLogin && !userStore.hasLogin) {
        const pages = getCurrentPages();
        if (pages.length >= 10) {
            uni.redirectTo({
                url: '/packageA/pages/complete-info/complete-info',
                fail: (err) => {
                    console.error('页面跳转失败:', err);
                }
            });
        } else {
            uni.navigateTo({
                url: '/packageA/pages/complete-info/complete-info',
                fail: (err) => {
                    console.error('页面跳转失败:', err);
                    uni.redirectTo({
                        url: '/packageA/pages/complete-info/complete-info',
                        fail: (err2) => {
                            console.error('redirectTo也失败:', err2);
                        }
                    });
                }
            });
        }
        return;
    }

    const queryStr = Object.entries(query)
        .map(([key, val]) => `${key}=${encodeURIComponent(val)}`)
        .join('&');
    const finalUrl = queryStr ? `${url}?${queryStr}` : url;

    if (onBack) {
        const pages = getCurrentPages();
        const currentPage = pages[pages.length - 1];
        currentPage.__onBackCallback__ = onBack;
    }

    const pages = getCurrentPages();
    if (pages.length >= 10) {
        // 页面栈已满，使用redirectTo替代
        uni.redirectTo({
            url: finalUrl,
            fail: (err) => {
                console.error('页面跳转失败:', err);
            }
        });
    } else {
        uni.navigateTo({
            url: finalUrl,
            fail: (err) => {
                console.error('页面跳转失败:', err);
                // 失败后尝试redirectTo
                uni.redirectTo({
                    url: finalUrl,
                    fail: (err2) => {
                        console.error('redirectTo也失败:', err2);
                    }
                });
            }
        });
    }
};

export const navBack = function({
    delta = 1,
    data = null,
    fallbackUrl = '/pages/index/index'
} = {}) {
    const pages = getCurrentPages();

    if (pages.length > 1) {
        const prevPage = pages[pages.length - 1 - delta];

        // 如果上一页存在回调函数，调用
        if (data && prevPage?.__onBackCallback__) {
            prevPage.__onBackCallback__(data);
        }

        uni.navigateBack({
            delta
        });
    } else {
        // 没有可返回的页面，直接跳转 fallback 页面
        uni.reLaunch({
            url: fallbackUrl
        });
    }
};
// // 默认返回上一页
// navBack();

// // 返回上两层
// navBack(2);

// // 没有历史页面时跳转首页
// navBack(1, '/pages/home/home');

function getdeviceInfo() {
    const globalData = {
        statusBarHeight: 0, // 状态导航栏高度
        topHeight: 0, // 距离顶部高度
        navHeight: 0, // 总体高度
        windowHeight: 0, // 可使用窗口高度
        tabBarHight: 0, //底部导航栏高度
    };
    let systemInfo = uni.getSystemInfoSync()
    globalData.windowHeight = systemInfo.screenHeight
    // 底部导航栏
    globalData.tabBarHight = systemInfo.screenHeight - systemInfo.safeArea.bottom
    // 状态栏高度
    globalData.statusBarHeight = systemInfo.statusBarHeight
    // #ifdef MP-MP-WEIXIN
    let menuButtonInfo = uni.getMenuButtonBoundingClientRect()
    // 胶囊距离顶部高度
    globalData.topHeight = menuButtonInfo.top
    // 胶囊高度
    globalData.navHeight = menuButtonInfo.height​
    // #endif
    return {
        ...globalData
    }
}

function sleep(time) {
    return new Promise((resolve) => setTimeout(resolve, time))
}
const cloneDeep = (obj) => {
    // 1.1 判断是否是对象
    const isObject = (obj) => (typeof obj === 'object' || typeof obj === 'function') && obj !== 'null'

    if (!isObject(obj)) {
        throw new Error('参数不是对象')
    }
    // 1.3 如果参数为数组，则复制数组各元素，否则复制对象属性
    const newObject = Array.isArray(obj) ? [...obj] : {
        ...obj
    }
    // 1.4 迭代
    Object.keys(newObject).forEach((key) => {
        // 1.5 判断如果遍历到的属性值为对象，则继续递归cloneDeep
        if (isObject(newObject[key])) {
            newObject[key] = cloneDeep(newObject[key])
        }
    })
    return newObject
}

const CopyText = (text) => {
    let input = document.createElement('textarea');
    input.value = text;
    document.body.appendChild(input);
    input.select();
    let flag = document.execCommand('copy')
    if (flag) {
        message.success('成功复制到剪贴板')
    } else {
        message.success('复制失败')
    }
    document.body.removeChild(input)
}

// 柯里化 降低使用范围，提高适用性
function Exp(regExp) {
    return (str) => {
        return regExp.test(str)
    }
}

const checkingPhoneRegExp = Exp(/^1[3-9]{1}\d{9}/)
// 手机号校验 checkingPhoneRegExp(phone)

const checkingEmailRegExp = Exp(/^[a-z0-9_\.-]+@[a-z0-9_\.-]+[a-z0-9]{2,6}$/i)
// 邮箱校验 checkingEmailRegExp(email)


function throttle(fn, delay = 300) {
    let valid = true
    let savedArgs = null // 参数存储器 
    let savedContext = null // 上下文存储器

    return function(...args) {
        // 保存当前参数和上下文 
        savedArgs = args
        savedContext = this

        if (!valid) return false
        valid = false
        setTimeout(() => {
            fn.apply(savedContext, savedArgs)
            valid = true
            savedArgs = null // 清空存储 
            savedContext = null
        }, delay)
    }
}

function debounce(fun, delay) {
    return function(args) {
        let that = this
        let _args = args
        clearTimeout(fun.id)
        fun.id = setTimeout(function() {
            fun.call(that, _args)
        }, delay)
    }
}


function toRad(degree) {
    return degree * Math.PI / 180;
}

function haversine(lat1, lon1, lat2, lon2) {
    const R = 6371; // 地球半径，单位为公里
    const a1 = toRad(lat1);
    const a2 = toRad(lat2);
    const b1 = toRad(lat2 - lat1);
    const b2 = toRad(lon2 - lon1);

    const a = Math.sin(b1 / 2) * Math.sin(b1 / 2) +
        Math.cos(a1) * Math.cos(a2) * Math.sin(b2 / 2) * Math.sin(b2 / 2);
    const c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
    const distance = R * c; // 计算得到的距离，单位为公里

    return distance;
}

export function getDistanceFromLatLonInKm(lat1, lon1, lat2, lon2) {
    const R = 6371; // 地球平均半径，单位为公里
    const dLat = deg2rad(lat2 - lat1);
    const dLon = deg2rad(lon2 - lon1);
    const a =
        Math.sin(dLat / 2) * Math.sin(dLat / 2) +
        Math.cos(deg2rad(lat1)) * Math.cos(deg2rad(lat2)) *
        Math.sin(dLon / 2) * Math.sin(dLon / 2);
    const c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
    const d = R * c;
    return {
        km: d,
        m: d * 1000
    };
}

// 将角度转换为弧度
function deg2rad(deg) {
    return deg * (Math.PI / 180);
}

function vacanciesTo(vacancies) {
    if (vacancies >= 0) {
        return vacancies + "人"
    } else {
        return '不限人数'
    }
}

function salaryGlobal(type = 'min') {
    const salay = [2, 5, 10, 15, 20, 25, 30, 50, 80];
    const salaymax = [2, 5, 10, 15, 20, 25, 30, 50, 80, 100];
    const salarys = salay.map((item, index) => ({
        label: item + 'k',
        value: item * 1000,
        children: CloneDeep(salaymax).splice(index).map((vItem) => ({
            label: vItem + 'k',
            value: vItem * 1000,
        }))
    }))

    return salarys
}

class CustomSystem {
    constructor() {
        const systemInfo = uni.getSystemInfoSync();
        this.systemInfo = systemInfo
    }
}
const customSystem = new CustomSystem()

function setCheckedNodes(nodes, ids) {
    const isClear = ids.length === 0;

    nodes.forEach((firstLayer) => {
        // 每次处理都先重置
        firstLayer.checkednumber = 0;

        const traverse = (node) => {
            if (isClear) {
                node.checked = false;
            } else {
                node.checked = ids.includes(node.id);
            }

            if (node !== firstLayer && node.checked) {
                firstLayer.checkednumber++;
            }

            if (node.children && node.children.length) {
                node.children.forEach(child => traverse(child));
            }
        };

        traverse(firstLayer);
    });

    return nodes;
}
const formatTotal = (total) => {
    if (total < 10) return total.toString(); // 直接返回小于 10 的数

    const magnitude = Math.pow(10, Math.floor(Math.log10(total))); // 计算数量级
    const roundedTotal = Math.floor(total / magnitude) * magnitude; // 去掉零头

    return `${roundedTotal}+`;
};

export function sm2_Decrypt(word, key) {
    return SM.decrypt(word, key);
}

export function sm2_Encrypt(word, key) {
    return SM.encrypt(word, key);
}

export function formatDate(isoString) {
    const date = new Date(isoString);
    const year = date.getFullYear();
    const month = String(date.getMonth() + 1).padStart(2, '0'); // 月份从 0 开始，需要 +1
    const day = String(date.getDate()).padStart(2, '0');
    const hours = String(date.getHours()).padStart(2, '0');
    const minutes = String(date.getMinutes()).padStart(2, '0');
    const seconds = String(date.getSeconds()).padStart(2, '0');

    return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;
}

export function insertSortData(data, attribute = 'createTime') {
    const sortedData = data.sort((a, b) => new Date(b[attribute]) - new Date(a[attribute])); // 按时间降序排序
    const result = [];
    let lastDate = '';
    let lastTitle = ''


    const now = new Date();
    const todayStr = now.toISOString().split('T')[0]; // 获取今天的日期字符串
    const yesterday = new Date(now.setDate(now.getDate() - 1)).toISOString().split('T')[0]; // 获取昨天的日期字符串
    const twoDaysAgo = new Date(now.setDate(now.getDate() - 1)).toISOString().split('T')[0]; // 获取前天的日期字符串

    sortedData.forEach(item => {
        const itemAttribute = item[attribute].replace('T', ' ')
        const itemDate = itemAttribute.split(' ')[0]; // 提取日期部分

        let title = itemDate;
        if (itemDate === todayStr) {
            title = '今天';
        } else if (itemDate === yesterday) {
            title = '昨天';
        } else if (itemDate === twoDaysAgo) {
            title = '前天';
        }

        if (lastDate !== itemDate) {
            result.push({
                title,
                isTitle: true
            });
            lastDate = itemDate;
            lastTitle = title;
        }

        result.push({
            ...item,
            isTitle: false
        });
    });

    return [result, lastTitle];
}

function getWeeksOfMonth(year, month) {
    const firstDay = new Date(year, month - 1, 1); // 当月第一天
    const lastDay = new Date(year, month, 0); // 当月最后一天
    const weeks = [];
    let week = [];

    for (let d = new Date(firstDay); d <= lastDay; d.setDate(d.getDate() + 1)) {
        // 补充第一周的上个月日期
        if (week.length === 0 && d.getDay() !== 1) {
            let prevMonday = new Date(d);
            prevMonday.setDate(d.getDate() - (d.getDay() === 0 ? 6 : d.getDay() - 1));
            while (prevMonday < d) {
                week.push({
                    year: prevMonday.getFullYear(),
                    month: prevMonday.getMonth() + 1,
                    day: prevMonday.getDate(),
                    fullDate: getLocalYYYYMMDD(prevMonday), // 修正
                    weekday: ["星期日", "星期一", "星期二", "星期三", "星期四", "星期五", "星期六"][prevMonday.getDay()],
                    isCurrent: false // 上个月日期
                });
                prevMonday.setDate(prevMonday.getDate() + 1);
            }
        }

        // 添加当前月份的日期
        week.push({
            year: d.getFullYear(),
            month: d.getMonth() + 1,
            day: d.getDate(),
            fullDate: getLocalYYYYMMDD(d), // 修正
            weekday: ["星期日", "星期一", "星期二", "星期三", "星期四", "星期五", "星期六"][d.getDay()],
            isCurrent: true // 当前月的日期
        });

        // 如果到了月末但当前周未满7天，需要补足到周日
        if (d.getTime() === lastDay.getTime() && week.length < 7) {
            let nextDay = new Date(d);
            nextDay.setDate(d.getDate() + 1);
            while (week.length < 7) {
                week.push({
                    year: nextDay.getFullYear(),
                    month: nextDay.getMonth() + 1,
                    day: nextDay.getDate(),
                    fullDate: getLocalYYYYMMDD(nextDay), // 修正
                    weekday: ["星期日", "星期一", "星期二", "星期三", "星期四", "星期五", "星期六"][nextDay.getDay()],
                    isCurrent: false // 下个月日期
                });
                nextDay.setDate(nextDay.getDate() + 1);
            }
        }

        // 如果本周满了（7天）或者到了月末
        if (week.length === 7 || d.getTime() === lastDay.getTime()) {
            weeks.push([...week]); // 存入当前周
            week = []; // 清空，准备下一周
        }
    }

    return weeks;
}

// 新增工具函数：将日期格式化为本地 YYYY-MM-DD 字符串 
function getLocalYYYYMMDD(date) {
    const y = date.getFullYear();
    const m = String(date.getMonth() + 1).padStart(2, '0');
    const d = String(date.getDate()).padStart(2, '0');
    return `${y}-${m}-${d}`;
}

function isFutureDate(dateStr) {
    const inputDate = new Date(dateStr);
    const today = new Date();

    // 只比较年月日，不考虑具体时间
    today.setHours(0, 0, 0, 0);
    inputDate.setHours(0, 0, 0, 0);

    return inputDate > today;
}

function parseQueryParams(url = window.location.href) {
    const queryString = url.split('?')[1]?.split('#')[0];
    const params = {};
    if (!queryString) return params;

    queryString.split('&').forEach(param => {
        const [key, value] = param.split('=');
        if (key) {
            params[decodeURIComponent(key)] = decodeURIComponent(value || '');
        }
    });

    return params;
}

function formatFileSize(bytes) {
    if (bytes < 1024) return bytes + ' B'
    else if (bytes < 1024 * 1024) return (bytes / 1024).toFixed(2) + ' KB'
    else if (bytes < 1024 * 1024 * 1024) return (bytes / (1024 * 1024)).toFixed(2) + ' MB'
    else return (bytes / (1024 * 1024 * 1024)).toFixed(2) + ' GB'
}


function sendingMiniProgramMessage(data = {
    text: 'hello'
}, action = 'defalut') {
    jWeixin.miniProgram.postMessage({
        data,
        action
    });
}

function copyText(text) {
    uni.setClipboardData({
        data: text,
        showToast: false,
        success(res) {
            msg('复制成功')
        },
    });
}

function appendScriptTagElement(src) {
    if (!src) return null;
    return new Promise((resolve, reject) => {
        const script = document.createElement('script');
        script.src = src;
        script.onload = () => {
            resolve()
        };
        script.onerror = () => {
            reject()
        };
        document.body.appendChild(script);
    })
}

function isInWechatMiniProgramWebview() {
    const ua = navigator.userAgent.toLowerCase()
    return ua.includes('miniprogram') || window.__wxjs_environment === 'miniprogram'
}

function isEmptyObject(obj) {
    return obj && typeof obj === 'object' && !Array.isArray(obj) && Object.keys(obj).length === 0;
}

/**
 * 农历日期工具
 * 提供公历转农历日期的中文表示
 */
export const LunarUtil = {
    /**
     * 获取农历日期的中文表示
     * @param {number} year - 公历年
     * @param {number} month - 公历月 (1-12)
     * @param {number} day - 公历日
     * @returns {string} 农历日期的中文表示（初一、初二...三十）
     */
    getLunarDayInChinese(year, month, day) {
        // 这里使用简化的农历转换算法
        // 实际项目中可以根据需要扩展更完整的农历功能
        const lunarDays = this.solarToLunar(year, month, day);
        return this.getDayInChinese(lunarDays.day);
    },
    
    /**
     * 简化的公历转农历日期算法
     * 注意：这是一个简化版，实际农历计算更复杂
     * 仅用于生成初一到三十的日期表示
     */
    solarToLunar(year, month, day) {
        // 这里使用简化算法，实际项目中可以使用更精确的算法
        // 对于本项目，我们只需要生成初一到三十的序列
        // 实际的农历计算需要考虑节气、闰月等因素
        const daysInMonth = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
        
        // 处理闰年
        if ((year % 4 === 0 && year % 100 !== 0) || year % 400 === 0) {
            daysInMonth[1] = 29;
        }
        
        // 计算当年已过天数
        let dayOfYear = 0;
        for (let i = 0; i < month - 1; i++) {
            dayOfYear += daysInMonth[i];
        }
        dayOfYear += day;
        
        // 简化的农历月份计算（实际农历月份计算更复杂）
        const lunarMonth = Math.ceil(dayOfYear / 29.5);
        const lunarDay = (dayOfYear % 29) || 29;
        
        return {
            month: lunarMonth,
            day: lunarDay
        };
    },
    
    /**
     * 将农历日期转换为中文表示
     * @param {number} day - 农历日
     * @returns {string} 中文表示（初一、初二...三十）
     */
    getDayInChinese(day) {
        if (day === 1) {
            return '初一';
        } else if (day === 15) {
            return '十五';
        } else if (day === 30) {
            return '三十';
        } else {
            const digits = ['', '一', '二', '三', '四', '五', '六', '七', '八', '九', '十'];
            if (day <= 10) {
                return '初' + digits[day];
            } else if (day <= 19) {
                return '十' + (day === 10 ? '' : digits[day - 10]);
            } else if (day <= 29) {
                return '廿' + (day === 20 ? '' : digits[day - 20]);
            } else {
                return '三十';
            }
        }
    }
};

/**
 * 身份证号码校验工具
 * 支持15位和18位身份证号码校验
 * 提供详细的校验结果和错误信息
 */
export const IdCardValidator = {
    // 每位加权因子
    powers: ['7', '9', '10', '5', '8', '4', '2', '1', '6', '3', '7', '9', '10', '5', '8', '4', '2'],

    // 第18位校检码
    parityBit: ['1', '0', 'X', '9', '8', '7', '6', '5', '4', '3', '2'],

    // 省市地区码映射
    provinceAndCitys: {
        11: '北京',
        12: '天津',
        13: '河北',
        14: '山西',
        15: '内蒙古',
        21: '辽宁',
        22: '吉林',
        23: '黑龙江',
        31: '上海',
        32: '江苏',
        33: '浙江',
        34: '安徽',
        35: '福建',
        36: '江西',
        37: '山东',
        41: '河南',
        42: '湖北',
        43: '湖南',
        44: '广东',
        45: '广西',
        46: '海南',
        50: '重庆',
        51: '四川',
        52: '贵州',
        53: '云南',
        54: '西藏',
        61: '陕西',
        62: '甘肃',
        63: '青海',
        64: '宁夏',
        65: '新疆',
        71: '台湾',
        81: '香港',
        82: '澳门',
        91: '国外'
    },

    /**
     * 验证身份证号码
     * @param {string} idCardNo - 身份证号码
     * @returns {Object} 校验结果 { valid: boolean, message: string, info: Object }
     */
    validate(idCardNo) {
        // 检查是否为空
        if (this._isEmpty(idCardNo)) {
            return this._createResult(false, '身份证号码不能为空');
        }

        // 去除空格
        idCardNo = idCardNo.trim();

        // 检查长度，支持15位和18位
        if (idCardNo.length === 15) {
            return this._validate15IdCardNo(idCardNo);
        } else if (idCardNo.length === 18) {
            return this._validate18IdCardNo(idCardNo);
        } else {
            return this._createResult(false, '身份证号码长度必须是15位或18位');
        }
    },

    /**
     * 验证18位身份证号码
     * @param {string} idCardNo - 18位身份证号码
     * @returns {Object} 校验结果
     */
    _validate18IdCardNo(idCardNo) {
        // 18位身份证号码的基本格式校验
        if (!/^[1-9]\d{5}[1-9]\d{3}((0[1-9])|(1[0-2]))((0[1-9])|([1-2][0-9])|(3[0-1]))\d{3}(\d|x|X)$/.test(
                idCardNo)) {
            return this._createResult(false, '身份证号码格式不正确');
        }

        // 校验地址码
        const addressCode = idCardNo.substring(0, 6);
        const addressResult = this._checkAddressCode(addressCode);
        if (!addressResult.valid) {
            return addressResult;
        }

        // 校验日期码
        const birDayCode = idCardNo.substring(6, 14);
        const birthResult = this._checkBirthDayCode(birDayCode);
        if (!birthResult.valid) {
            return birthResult;
        }

        // 验证校检码
        if (!this._checkParityBit(idCardNo)) {
            return this._createResult(false, '身份证号码校验码错误');
        }

        // 提取身份证信息
        const info = this._extractInfo(idCardNo, 18);

        return this._createResult(true, '身份证号码校验通过', info);
    },

    /**
     * 验证15位身份证号码
     * @param {string} idCardNo - 15位身份证号码
     * @returns {Object} 校验结果
     */
    _validate15IdCardNo(idCardNo) {
        // 15位身份证号码的基本格式校验
        if (!/^[1-9]\d{5}\d{2}((0[1-9])|(1[0-2]))((0[1-9])|([1-2][0-9])|(3[0-1]))\d{3}$/.test(idCardNo)) {
            return this._createResult(false, '身份证号码格式不正确');
        }

        // 校验地址码
        const addressCode = idCardNo.substring(0, 6);
        const addressResult = this._checkAddressCode(addressCode);
        if (!addressResult.valid) {
            return addressResult;
        }

        // 校验日期码（15位身份证年份是两位，这里转换为四位）
        const year = `19${idCardNo.substring(6, 8)}`; // 15位身份证一般是1900年以后出生
        const month = idCardNo.substring(8, 10);
        const day = idCardNo.substring(10, 12);
        const birDayCode = `${year}${month}${day}`;

        const birthResult = this._checkBirthDayCode(birDayCode);
        if (!birthResult.valid) {
            return birthResult;
        }

        // 提取身份证信息
        const info = this._extractInfo(idCardNo, 15);

        return this._createResult(true, '身份证号码校验通过', info);
    },

    /**
     * 校验地址码
     * @param {string} addressCode - 地址码
     * @returns {Object} 校验结果
     */
    _checkAddressCode(addressCode) {
        if (!/^[1-9]\d{5}$/.test(addressCode)) {
            return this._createResult(false, '地址码格式不正确');
        }

        const provinceCode = parseInt(addressCode.substring(0, 2));
        if (!this.provinceAndCitys[provinceCode]) {
            return this._createResult(false, '地址码对应的地区不存在');
        }

        return this._createResult(true);
    },

    /**
     * 校验日期码
     * @param {string} birDayCode - 日期码 (格式：YYYYMMDD)
     * @returns {Object} 校验结果
     */
    _checkBirthDayCode(birDayCode) {
        if (!/^[1-9]\d{3}((0[1-9])|(1[0-2]))((0[1-9])|([1-2][0-9])|(3[0-1]))$/.test(birDayCode)) {
            return this._createResult(false, '出生日期格式不正确');
        }

        const year = parseInt(birDayCode.substring(0, 4), 10);
        const month = parseInt(birDayCode.substring(4, 6), 10);
        const day = parseInt(birDayCode.substring(6), 10);

        // 检查年份范围（合理的出生年份范围）
        const currentYear = new Date().getFullYear();
        if (year < 1900 || year > currentYear) {
            return this._createResult(false, '出生年份超出合理范围');
        }

        // 检查日期有效性
        const date = new Date(year, month - 1, day);
        if (
            date.getFullYear() !== year ||
            date.getMonth() !== month - 1 ||
            date.getDate() !== day
        ) {
            return this._createResult(false, '出生日期无效');
        }

        // 检查是否为未来日期
        if (date > new Date()) {
            return this._createResult(false, '出生日期不能是未来日期');
        }

        return this._createResult(true);
    },

    /**
     * 验证校检码
     * @param {string} idCardNo - 18位身份证号码
     * @returns {boolean} 校验结果
     */
    _checkParityBit(idCardNo) {
        const parityBit = idCardNo.charAt(17).toUpperCase();
        return this._getParityBit(idCardNo) === parityBit;
    },

    /**
     * 计算校检码
     * @param {string} idCardNo - 18位身份证号码
     * @returns {string} 校检码
     */
    _getParityBit(idCardNo) {
        const id17 = idCardNo.substring(0, 17);
        let power = 0;

        for (let i = 0; i < 17; i++) {
            power += parseInt(id17.charAt(i), 10) * parseInt(this.powers[i], 10);
        }

        const mod = power % 11;
        return this.parityBit[mod];
    },

    /**
     * 提取身份证信息
     * @param {string} idCardNo - 身份证号码
     * @param {number} type - 类型 15或18
     * @returns {Object} 身份证信息
     */
    _extractInfo(idCardNo, type) {
        let addressCode, birthYear, birthMonth, birthDay, genderCode, gender;

        // 地址码
        addressCode = idCardNo.substring(0, 6);
        const provinceCode = parseInt(addressCode.substring(0, 2));
        const province = this.provinceAndCitys[provinceCode] || '';

        // 出生日期
        if (type === 18) {
            birthYear = idCardNo.substring(6, 10);
            birthMonth = idCardNo.substring(10, 12);
            birthDay = idCardNo.substring(12, 14);
            genderCode = idCardNo.substring(14, 17);
        } else {
            birthYear = `19${idCardNo.substring(6, 8)}`;
            birthMonth = idCardNo.substring(8, 10);
            birthDay = idCardNo.substring(10, 12);
            genderCode = idCardNo.substring(12, 15);
        }

        // 性别
        gender = parseInt(genderCode, 10) % 2 === 1 ? '男' : '女';

        return {
            addressCode,
            province,
            birthday: `${birthYear}-${birthMonth}-${birthDay}`,
            gender,
            length: type
        };
    },

    /**
     * 检查是否为空
     * @param {*} value - 要检查的值
     * @returns {boolean} 是否为空
     */
    _isEmpty(value) {
        return value === null || value === undefined || value === '';
    },

    /**
     * 创建校验结果对象
     * @param {boolean} valid - 是否有效
     * @param {string} message - 消息
     * @param {Object} info - 附加信息
     * @returns {Object} 校验结果
     */
    _createResult(valid, message = '', info = {}) {
        return {
            valid,
            message,
            info
        };
    },

    /**
     * 将15位身份证升级为18位
     * @param {string} idCardNo - 15位身份证号码
     * @returns {string|boolean} 18位身份证号码或false(无效的15位身份证)
     */
    upgrade15To18(idCardNo) {
        if (idCardNo.length !== 15) {
            return false;
        }

        // 先验证15位身份证是否有效
        const validateResult = this._validate15IdCardNo(idCardNo);
        if (!validateResult.valid) {
            return false;
        }

        // 转换出生年份为4位
        const year = `19${idCardNo.substring(6, 8)}`;
        const rest = idCardNo.substring(8);

        // 拼接17位
        const id17 = `${idCardNo.substring(0, 6)}${year}${rest}`;

        // 计算校验码
        let power = 0;
        for (let i = 0; i < 17; i++) {
            power += parseInt(id17.charAt(i), 10) * parseInt(this.powers[i], 10);
        }
        const mod = power % 11;
        const parityBit = this.parityBit[mod];

        // 拼接18位身份证
        return `${id17}${parityBit}`;
    }
};



export const $api = {
    msg,
    prePage,
    sleep,
    request,
    createRequest,
    streamRequest,
    chatRequest,
    insertSortData,
    uploadFile,
    formatFileSize,
    sendingMiniProgramMessage,
    copyText,
	myRequest
}



export default {
    $api,
	urls,
    navTo,
    navBack,
    cloneDeep,
    formatDate,
    IdCardValidator,
    LunarUtil,
    getdeviceInfo,
    checkingPhoneRegExp,
    checkingEmailRegExp,
    throttle,
    debounce,
    haversine,
    getDistanceFromLatLonInKm,
    vacanciesTo,
    salaryGlobal,
    customSystem,
    setCheckedNodes,
    formatTotal,
    getWeeksOfMonth,
    isFutureDate,
    parseQueryParams,
    appendScriptTagElement,
    insertSortData,
    isInWechatMiniProgramWebview,
    isEmptyObject,
    sm4Decrypt,
    sm4Encrypt,
    sm2_Decrypt,
    sm2_Encrypt,
}
