/**
 * 政策
 */

import * as verificationEnumTools from "../util/verificationEnum";
import * as configEnum from "../config/enum";
import * as policyData from "../data/policy";
import { checkChange, extractData } from "../util/piecemeal";
import * as splitResultConfig from '../config/splitResultConfig';
import { eccFormParam } from "../util/verificationParam";
import { PolicyAddConfig, PolicyUpdateConfig } from "../config/eccParam/admin";
import { randomId } from "../tools/system";
import { TABLEID } from "../config/enum/dbEnum";
import { BizError } from "../util/bizError";
import { ERRORENUM } from "../config/errorEnum";


/**
 * 政策-列表
 * @param title 政策标题
 * @param startTime 政策开始时间
 * @param endTime 政策结束时间
 * @param policyType 政策类型 财政补贴 资质申报 政策扶持
 * @param page 页
 */
export async function policyList(title:string, startTime:number, endTime:number, policyType:number, page:number) {
    let selectParam:any = {};
    if (title) {
        selectParam.title = {"$regex":`${title}`};
    }
    if (startTime && endTime) {
        // 条件：政策开始时间 <= 传入结束时间 且 政策结束时间 >= 传入开始时间
        selectParam.startTime = { "$lte": endTime };
        selectParam.endTime = { "$gte": startTime };
    }
    if (policyType) {
        verificationEnumTools.eccEnumValue('管理后台获取政策列表', 'policyType', configEnum.POLICYTYPE, policyType);
        selectParam.policyType = policyType;
    }
    /**需要用到的查询数据 */
    let policyDbList = await policyData.findPolicyListToPageSort(selectParam, (page - 1) * 10, {createTime: -1});
    let count = await policyData.findPolicyCount(selectParam);//符合查询条件的数据总数

    /**组合返回结果 */
    let dataList = [];
    policyDbList.forEach( info => {
        /**截取返回数据 */
        let changeData:any = extractData(splitResultConfig.policyListConfig, info, true);

        /**将枚举值转为字符 */
        changeData.policyType = verificationEnumTools.changeEnumValue(configEnum.POLICYTYPE, changeData.policyType);

        dataList.push(changeData);
    })

    return {count, dataList};
}


/**
 * 政策-新增
 * @param uscc 
 * @param param 
 */
export async function policyCreate(param) {
    /**校验表单参数 */
    eccFormParam("管理后台新增政策企业", PolicyAddConfig, param);
    /**校验枚举 */
    verificationEnumTools.eccEnumValue('管理后台新增政策', 'policyType', configEnum.POLICYTYPE, param.policyType);

    let enterpriseInfo = await policyData.findPolicyByParam({title:param.title});
    if (enterpriseInfo && enterpriseInfo.title)  throw new BizError(ERRORENUM.该政策已存在, `${param.title}已经在库中存在`);

    let policyInfo = {
        id: randomId(TABLEID.政策),
        title: param.title,
        policyType: param.policyType,
        startTime: param.startTime,
        endTime: param.endTime,
        source: param.source,
        desc:param.desc,
        createTime: new Date().valueOf(),
    }

    await policyData.createDataByParam(policyInfo);

    return {isSuccess:true};
}


/**
 * 政策-回显
 * @param uscc 
 */
export async function policyInfo(id:string) {
    /**校验企业 */
    let policyDbInfo = await policyData.findPolicyByParam({id});
    if (!policyDbInfo || !policyDbInfo.id) throw new BizError(ERRORENUM.未找到数据, `库中不存在id=${id}这个政策`);

    let dataInfo = {
        title: policyDbInfo.title,
        policyType: policyDbInfo.policyType,
        startTime: policyDbInfo.startTime,
        endTime: policyDbInfo.endTime,
        source: policyDbInfo.source,
        desc:policyDbInfo.desc,
    };

    return {dataInfo};
}


/**
 * 政策-修改
 * @param uscc 
 * @param param 
 */
export async function policyUpdate(id:string, param) {
    /**校验参数 */
    eccFormParam("管理后台修改政策企业", PolicyUpdateConfig, param);

    /**校验枚举 */
    verificationEnumTools.eccEnumValue('管理后台新增政策', 'policyType', configEnum.POLICYTYPE, param.policyType);

    /**校验企业 */
    let policyDbInfo = await policyData.findPolicyByParam({id});
    if (!policyDbInfo || !policyDbInfo.id) throw new BizError(ERRORENUM.未找到数据, `库中不存在id=${id}这个政策`);

    /**修改字段 */
    let changeList = checkChange(param, policyDbInfo);
    if (!changeList.length) throw new BizError(ERRORENUM.数据无更新, `${param.name}数据无更新`);
    changeList.forEach(key => {
        policyDbInfo[key] = param[key];
    });

    await policyDbInfo.save();

    return {isSuccess:true};
}


/**
 * 政策-删除
 * @param id 
 */
export async function policyDelete(id:string) {
    let policyDbInfo = await policyData.findPolicyByParam({id});
    if (!policyDbInfo || !policyDbInfo.id) throw new BizError(ERRORENUM.未找到数据, `库中不存在id=${id}这个政策`);

    await policyData.removeOneData(id);

    return {isSuccess:true};
}


/**
 * 导出政策信息列表
 * @param title 政策标题
 * @param startTime 开始时间
 * @param endTime 结束时间
 * @param policyType 政策类型
 * @returns 二维数组，第一行为表头，后续行为数据
 */
export async function outPutPolicyData(title: string, startTime: number, endTime: number, policyType: number, id: string[]) {
    /** 拼接查询条件 */
    let selectParam: any = {};
    if (title) {
        selectParam.title = { "$regex": `${title}` };
    }
    if (startTime && endTime) {
        selectParam.startTime = { "$lte": endTime };
        selectParam.endTime = { "$gte": startTime };
    } else if (startTime) {
        selectParam.startTime = { "$lte": endTime };
    } else if (endTime) {
        selectParam.endTime = { "$gte": startTime };
    }
    if (policyType) {
        selectParam.policyType = policyType;
    }
    if (id) {
        selectParam.id = {"$in": id};
    }

    /** 查询政策数据 */
    let policyDbList = await policyData.findPolicyByParamSort(selectParam, {createTime: -1});

    /** 表头定义 */
    const titleList = [
        "政策标题",
        "政策类型",
        "生效时间",
        "失效时间",
        "政策来源",
        // "政策内容"
    ];

    let dataList = [titleList]; // 第一行为表头

    policyDbList.forEach(info => {
        /** 提取数据 */
        let changeData: any = extractData(splitResultConfig.policyListConfig, info, true);

        /** 枚举值转文本 */
        changeData.policyType = verificationEnumTools.changeEnumValue(configEnum.POLICYTYPE, changeData.policyType) || "未分类";

        /** 时间格式化 */
        changeData.startTime = changeData.startTime ? formatDate(changeData.startTime) : "长期有效";
        changeData.endTime = changeData.endTime ? formatDate(changeData.endTime) : "长期有效";

        /** 处理政策内容（过长时截取） */
        let descText = changeData.desc || "-";
        if (descText.length > 100) {
            descText = descText.substring(0, 100) + "...";
        }

        /** 生成一行数据 */
        let row = [
            changeData.title || "-",
            changeData.policyType,
            changeData.startTime,
            changeData.endTime,
            changeData.source || "-",
            // descText
        ];

        dataList.push(row);
    });

    return dataList;
}

/**
 * 导出政策详细信息（带状态计算）
 * @param title 政策标题
 * @param startTime 开始时间
 * @param endTime 结束时间
 * @param policyType 政策类型
 * @returns 二维数组，带政策状态计算
 */
export async function outPutPolicyDetailData(title: string, startTime: number, endTime: number, policyType: number) {
    /** 拼接查询条件 */
    let selectParam: any = {};
    if (title) {
        selectParam.title = { "$regex": `${title}` };
    }
    if (startTime && endTime) {
        selectParam.startTime = { "$gte": startTime };
        selectParam.endTime = { "$lte": endTime };
    } else if (startTime) {
        selectParam.startTime = { "$gte": startTime };
    } else if (endTime) {
        selectParam.endTime = { "$lte": endTime };
    }
    if (policyType) {
        selectParam.policyType = policyType;
    }

    /** 查询政策数据 */
    let policyDbList = await policyData.findPolicyListByParam(selectParam);
    
    const now = Date.now();

    /** 表头定义 - 增加状态、剩余时间等字段 */
    const titleList = [
        "政策标题",
        "政策类型",
        "生效时间",
        "失效时间",
        "政策状态",
        "剩余/已过期时间",
        "政策来源",
        "政策内容摘要",
        "政策ID",
        "创建时间"
    ];

    let dataList = [titleList];

    policyDbList.forEach(info => {
        /** 提取数据 */
        let changeData: any = extractData(splitResultConfig.policyListConfig, info, true);

        /** 枚举值转文本 */
        const policyTypeText = verificationEnumTools.changeEnumValue(configEnum.POLICYTYPE, changeData.policyType) || "未分类";

        /** 时间格式化 */
        const startTimeText = changeData.startTime ? formatDate(changeData.startTime) : "长期有效";
        const endTimeText = changeData.endTime ? formatDate(changeData.endTime) : "长期有效";
        const createTimeText = changeData.createTime ? formatDateTime(changeData.createTime) : "-";

        /** 计算政策状态 */
        let policyStatus = "";
        let remainingTime = "";
        
        if (!changeData.startTime && !changeData.endTime) {
            // 无时间限制
            policyStatus = "长期有效";
            remainingTime = "无限制";
        } else if (changeData.startTime && changeData.endTime) {
            // 有明确起止时间
            if (now < changeData.startTime) {
                // 未生效
                const daysLeft = Math.ceil((changeData.startTime - now) / (1000 * 3600 * 24));
                policyStatus = "未生效";
                remainingTime = `${daysLeft}天后生效`;
            } else if (now > changeData.endTime) {
                // 已失效
                const daysAgo = Math.ceil((now - changeData.endTime) / (1000 * 3600 * 24));
                policyStatus = "已失效";
                remainingTime = `已过期${daysAgo}天`;
            } else {
                // 有效期内
                const daysLeft = Math.ceil((changeData.endTime - now) / (1000 * 3600 * 24));
                policyStatus = "生效中";
                remainingTime = `剩余${daysLeft}天`;
            }
        } else if (changeData.startTime && !changeData.endTime) {
            // 只有生效时间，无失效时间
            if (now < changeData.startTime) {
                const daysLeft = Math.ceil((changeData.startTime - now) / (1000 * 3600 * 24));
                policyStatus = "未生效";
                remainingTime = `${daysLeft}天后生效`;
            } else {
                policyStatus = "生效中";
                remainingTime = "长期有效";
            }
        } else if (!changeData.startTime && changeData.endTime) {
            // 只有失效时间
            if (now > changeData.endTime) {
                const daysAgo = Math.ceil((now - changeData.endTime) / (1000 * 3600 * 24));
                policyStatus = "已失效";
                remainingTime = `已过期${daysAgo}天`;
            } else {
                const daysLeft = Math.ceil((changeData.endTime - now) / (1000 * 3600 * 24));
                policyStatus = "生效中";
                remainingTime = `剩余${daysLeft}天`;
            }
        }

        /** 处理政策内容摘要 */
        let descText = changeData.desc || "-";
        if (descText.length > 80) {
            descText = descText.substring(0, 80) + "...";
        }

        /** 生成一行数据 */
        let row = [
            changeData.title || "-",
            policyTypeText,
            startTimeText,
            endTimeText,
            policyStatus,
            remainingTime,
            changeData.source || "-",
            descText,
            changeData.id || "-",
            createTimeText
        ];

        dataList.push(row);
    });

    return dataList;
}

/**
 * 按政策类型分组导出
 * @returns 二维数组，按政策类型分组
 */
export async function outPutPolicyByTypeData() {
    /** 查询所有政策数据 */
    let policyDbList = await policyData.findPolicyListByParam({});

    /** 按政策类型分组 */
    const policyTypeMap = new Map();
    
    policyDbList.forEach(info => {
        /** 提取数据 */
        let changeData: any = extractData(splitResultConfig.policyListConfig, info, true);
        
        const policyType = changeData.policyType || 0;
        const policyTypeText = verificationEnumTools.changeEnumValue(configEnum.POLICYTYPE, policyType) || "未分类";
        
        if (!policyTypeMap.has(policyType)) {
            policyTypeMap.set(policyType, {
                typeName: policyTypeText,
                policies: []
            });
        }
        
        // 时间格式化
        changeData.startTime = changeData.startTime ? formatDate(changeData.startTime) : "长期有效";
        changeData.endTime = changeData.endTime ? formatDate(changeData.endTime) : "长期有效";
        
        policyTypeMap.get(policyType).policies.push(changeData);
    });

    /** 表头定义 */
    const titleList = [
        "政策类型",
        "政策标题",
        "生效时间",
        "失效时间",
        "政策来源",
        "政策内容摘要"
    ];

    let dataList = [titleList];

    /** 按政策类型顺序输出 */
    const policyTypeOrder = Object.keys(configEnum.POLICYTYPE).filter(key => isNaN(Number(key))).map(key => configEnum.POLICYTYPE[key]);
    
    policyTypeOrder.forEach(typeId => {
        if (policyTypeMap.has(typeId)) {
            const group = policyTypeMap.get(typeId);
            
            // 添加分类标题行（可选）
            // dataList.push(new Array(titleList.length).fill(""));
            // const headerRow = new Array(titleList.length).fill("");
            // headerRow[0] = `【${group.typeName}】`;
            // dataList.push(headerRow);
            
            group.policies.forEach((policy, index) => {
                let row = [
                    index === 0 ? group.typeName : "", // 只在第一条显示类型
                    policy.title || "-",
                    policy.startTime,
                    policy.endTime,
                    policy.source || "-",
                    policy.desc ? (policy.desc.length > 80 ? policy.desc.substring(0, 80) + "..." : policy.desc) : "-"
                ];
                
                dataList.push(row);
            });
            
            // 在不同类型之间添加空行
            dataList.push(new Array(titleList.length).fill(""));
        }
    });

    return dataList;
}

/**
 * 日期格式化辅助函数（仅日期）
 * @param timestamp 时间戳
 * @returns 格式化后的日期字符串
 */
function formatDate(timestamp: number): string {
    const date = new Date(timestamp);
    const year = date.getFullYear();
    const month = (date.getMonth() + 1).toString().padStart(2, '0');
    const day = date.getDate().toString().padStart(2, '0');
    
    return `${year}-${month}-${day}`;
}

/**
 * 时间格式化辅助函数（日期+时间）
 * @param timestamp 时间戳
 * @returns 格式化后的时间字符串
 */
function formatDateTime(timestamp: number): string {
    const date = new Date(timestamp);
    const year = date.getFullYear();
    const month = (date.getMonth() + 1).toString().padStart(2, '0');
    const day = date.getDate().toString().padStart(2, '0');
    const hours = date.getHours().toString().padStart(2, '0');
    const minutes = date.getMinutes().toString().padStart(2, '0');
    
    return `${year}-${month}-${day} ${hours}:${minutes}`;
}








