/**
 * 答题自评
 */

import moment = require("moment");
import { OPERATIONALDATATYPE, TABLEID, TABLENAME } from "../config/enum/dbEnum";
import { changeEnumValue } from "../util/verificationEnum";
import { operationalData, selectData, selectManyTableData } from "../data/operationalData";
import { INDUSTRY, STATE } from "../config/enum/enum";
import { getMySqlMs, randomId } from "../tools/system";
import { BizError } from "../util/bizError";
import { ERRORENUM } from "../config/enum/errorEnum";


/**
 * ----------------------------------租房补贴评价答题
 */


/**
 * 题目
 */
export async function zuFangAnswerOption() {
    let answerInfo = await selectData(OPERATIONALDATATYPE.查询多个, TABLENAME.租房补贴企业自评, {}, []);

    //按照顺序返回题目
    answerInfo.sort( (a, b) => {
        return a.sort - b.sort;
    })

    let answerOption = []
    answerInfo.forEach( info => {
        answerOption.push(info);
    })

    return answerOption;
}


/**
 * 存储答题明细
 * @param eId 提交企业
 * @param zaId 关联题目id
 * @param options 选择的选项（1表示是，0表示否）
 * @returns 
 */
export async function addZuFangAnswerrecord(eId, zaId, options) {
    // 1.检查/创建答题记录
    let record:any = await checkOrCreateRecord(eId, "租房补贴答题记录");

    // 2.检查是否已答过本题
    let existingDetail = await selectData(OPERATIONALDATATYPE.查询单个, TABLENAME.租房补贴答题记录明细, {zaId, zarId:record.zarId}, []);

    // 3：更新或创建明细记录
    if (Object.keys(existingDetail).length) { //如果本题记录已存在，修改已答题过的记录
        await operationalData(OPERATIONALDATATYPE.修改, TABLENAME.租房补贴答题记录明细, { options }, {zadId:existingDetail.zadId});
    } else {
        let addInfo = {
            zadId: randomId(TABLEID.租房补贴答题记录明细),
            zarId: record.zarId,
            zaId,
            options,
        }
        await operationalData(OPERATIONALDATATYPE.增加, TABLENAME.租房补贴答题记录明细, addInfo, {});
    }

    //4：完成全部答题
    let answerInfo = await selectData(OPERATIONALDATATYPE.查询单个, TABLENAME.租房补贴企业自评, {zaId}, []);
    if (answerInfo.answerType == "是否认定科小或创新型中小企业") {
        let updateInfo = {
            answerStatus: STATE.是
        }
        await operationalData(OPERATIONALDATATYPE.修改, TABLENAME.租房补贴答题记录, updateInfo, {zarId:record.zarId});
    }

    return {zarId:record.zarId};
}


/**
 * 企业租房自评结果
 */
export async function enterpriseZuFangResults(zarId) {
    console.log(zarId);
    //获取企业租房自评答题记录
    let manyTableInfo:any = {};
    manyTableInfo[TABLENAME.租房补贴答题记录] = {column:["totalScore", "answerTime", "answerStatus"], where:{} };
    manyTableInfo[TABLENAME.租房补贴企业自评] = {column:["zaId", "answerType", "sort", "subject"], where:{} };
    let answerInfo = await selectManyTableData(OPERATIONALDATATYPE.多表联查, TABLENAME.租房补贴答题记录明细, {zarId}, ["zadId", "zarId", "zaId", "options"], manyTableInfo);

    if (!answerInfo) throw new BizError(ERRORENUM.答题记录不存在);

    //scores：0 = 否
    let scores = {
        是否有研发费用:STATE.否,
        是否有缴纳社保:STATE.否,
        是否有软著等知识产权:STATE.否,
        是否认定科小或创新型中小企业:STATE.否
    }
    answerInfo.forEach( detail => {
        let type = detail.zufang_answer.answerType;
        scores[type] = detail.options;
    })

    //计算各个类型得分 0 = 否
    let totalScore = STATE.是;
    for (let key in scores) {
        if (scores[key] == STATE.否) totalScore = STATE.否;
    }

    //更新是否符合租房补贴条件
    let updateAddInfo = {
        totalScore
    }
    await operationalData(OPERATIONALDATATYPE.修改, TABLENAME.租房补贴答题记录, updateAddInfo, {zarId});

    return {totalScore};
}


/**
 * ----------------------------------高新企业创新能力评价答题
 */

/**
 * 高新技术企业自评
 * @param eId 
 */
 export async function gaoxinAnswerList(eId) { 
    let filesList = ["eId", "logonTime", "industry"];
    let iprInfo = await selectData(OPERATIONALDATATYPE.查询单个, TABLENAME.企业基础信息表, {eId}, filesList);

    let islogonTime = false;
    let isindustry = false;
    // let islogonTime = true;
    // let isindustry = true;

    if (iprInfo.logonTime) {
        let regDate = moment(iprInfo.logonTime, 'YYYY-MM-DD');
        // 创建加一年后的日期（自动处理闰年）
        let anniversary = regDate.clone().add(1, 'years');
        //判断当前时间是否晚于加一年后的日期
        let sameAfter = moment().isSameOrAfter(anniversary);
        if (sameAfter) islogonTime = true;
    }

    // todo 行业领域范围还没给到我
    let industry = [];
    if (iprInfo.industry) {
        let industryList = JSON.parse(iprInfo.industry || '[]');
        industryList.forEach( item => {
            if (item == INDUSTRY["信息传输、软件和信息技术服务业"] || item == INDUSTRY.科学研究和技术服务业 || item == INDUSTRY.制造业) {
                isindustry = true;
            }
            industry.push(changeEnumValue(INDUSTRY, item))
        })
    }

    let dataList = [
        {
            key:"1.注册时间：企业注册成立≥一年",
            value:moment(iprInfo.logonTime).format("YYYY-MM-DD") || "",
            isOk:islogonTime
        },
        {
            key:"2.业务领域范围",
            value:industry.join(',') || "",
            isOk:isindustry
        },
    ];
    

    return {dataList};
}


/**
 * 题目
 */
export async function gaoxinAnswerOption() {
    let manyTableInfo:any = {};
    manyTableInfo[TABLENAME.高新企业创新能力评价选项] = {column:["goId", "gaId", "sort", "answer", "option", "notes", "score"], where:{} };
    let answerFile = ["gaId", "answerType", "sort", "subject", "isMultipleChoice", "questionType"];
    let answerInfo = await selectManyTableData(OPERATIONALDATATYPE.多表联查, TABLENAME.高新企业创新能力评价答题, {}, answerFile, manyTableInfo);

    //按照顺序返回题目
    answerInfo.sort( (a, b) => {
        return a.sort - b.sort;
    })

    let answerOption = {
        知识产权:[],
        科技成果:[],
        研发管理:[],
        企业成长:[]
    }

    answerInfo.forEach( info => {
        info.gaoxin_options.sort( (a, b) => {
            return a.sort - b.sort;
        })
        info.subject = `${info.subject}（${info.questionType}）`;
        /**除了知识产权、科技成果、研发管理、企业成长剩余题目类型不返回 */
        if (answerOption[info.answerType]) answerOption[info.answerType].push(info);
    })
    

    return answerOption;
}


/**
 * 完成全部答题
 * @param garId 答题记录id
 */
async function changeAnswerStatu(garId) {
    console.log("完成全部答题：", garId)
    let updateInfo = {
        answerStatus: STATE.是
    }
    await operationalData(OPERATIONALDATATYPE.修改, TABLENAME.答题记录, updateInfo, {garId});
    
    return {isSuccess:true};
}


/**
 * 存储答题明细
 * @param eId 提交企业
 * @param gaId 关联题目id
 * @param options 选择的选项ID数组 ["", ""]
 * @param assetGrowth 净资产增长率(0-1小数形式)
 * @param revenueGrowth 销售收入增长率(0-1小数形式)
 * @returns 
 */
export async function addAnswerrecord(eId, gaId, options, assetGrowth, revenueGrowth) {
    // 1.检查/创建答题记录
    let record:any = await checkOrCreateRecord(eId, "答题记录");

    // 2.检查是否已答过本题
    let existingDetail = await selectData(OPERATIONALDATATYPE.查询单个, TABLENAME.答题记录明细, {gaId, garId:record.garId}, []);
    
    // 3.计算本题得分 选项得分计算
    let answerInfo = await selectData(OPERATIONALDATATYPE.查询单个, TABLENAME.高新企业创新能力评价答题, {gaId}, []);
    let gaoxinOption = [];
    console.log(answerInfo.answerType)
    if (answerInfo.answerType == "企业成长") {
        gaoxinOption = await calculateGrowthScore(assetGrowth, revenueGrowth);
    } else {
        gaoxinOption = await selectData(OPERATIONALDATATYPE.查询多个, TABLENAME.高新企业创新能力评价选项, {gaId, goId:{"%in%":options}}, ["goId", "score"]);
    }
    /**
     * gaoxinOption = [
            {id:1, score:5},
            {id:2}, // 无score属性
            {id:3, score:3}
        ];
        options 计算结果：5 + 0 + 3 = 8
     */
    let score = gaoxinOption.reduce((sum, opt) => sum + (opt.score || 0), 0)

    // 4：更新或创建明细记录
    if (Object.keys(existingDetail).length) { //如果本题记录已存在，修改已答题过的记录
        await operationalData(OPERATIONALDATATYPE.修改, TABLENAME.答题记录明细, { options:JSON.stringify(options), questionScore:score }, {gadId:existingDetail.gadId});
    } else {
        let addInfo = {
            gadId: randomId(TABLEID.答题记录明细),
            garId: record.garId,
            gaId,
            options:JSON.stringify(options),
            questionScore: score
        }
        await operationalData(OPERATIONALDATATYPE.增加, TABLENAME.答题记录明细, addInfo, {});
    }
    
    // 步骤5：更新总分
    await updateTotalScore(record.garId);

    //完成全部答题
    if (answerInfo.answerType == "企业成长") {
        await changeAnswerStatu(record.garId);
    }

    return {garId:record.garId};
}


/**
 * 查找未完成的记录
 * @param eId 
 */
export async function checkOrCreateRecord(eId, tableName) {
    let addInfo = {};
    if (tableName == "租房补贴答题记录") {
        let existingRecord = await selectData(OPERATIONALDATATYPE.查询单个, TABLENAME.租房补贴答题记录, {eId, answerStatus:STATE.否}, []);
    
        addInfo = existingRecord;
        /**如果没有未完成答题记录，创建一条新的 */
        if (!Object.keys(existingRecord).length) {
            addInfo = {
                zarId:randomId(TABLEID.租房补贴答题记录),
                eId,
                answerTime: getMySqlMs(),
                totalScore: 0,
                answerStatus: STATE.否
            };
            await operationalData(OPERATIONALDATATYPE.增加, TABLENAME.租房补贴答题记录, addInfo, {});
        }
    } else if (tableName == "答题记录") {
        let existingRecord = await selectData(OPERATIONALDATATYPE.查询单个, TABLENAME.答题记录, {eId, answerStatus:STATE.否}, []);
    
        addInfo = existingRecord;
        /**如果没有未完成答题记录，创建一条新的 */
        if (!Object.keys(existingRecord).length) {
            addInfo = {
                garId:randomId(TABLEID.答题记录),
                eId,
                answerTime: getMySqlMs(),
                totalScore: 0,
                answerStatus: STATE.否
            };
            await operationalData(OPERATIONALDATATYPE.增加, TABLENAME.答题记录, addInfo, {});
        }
    }
    
    return addInfo;
}


/**
 * 更新总分函数
 * @param garId 答题记录
 */
async function updateTotalScore(garId) {
    let existingDetail = await selectData(OPERATIONALDATATYPE.查询多个, TABLENAME.答题记录明细, {garId}, ["questionScore"]);
    let sumScore = 0;
    existingDetail.forEach( info => {
        sumScore += parseInt(info.questionScore);
    })
    
    let updateInfo = {
        totalScore: sumScore || 0
    }
    await operationalData(OPERATIONALDATATYPE.修改, TABLENAME.答题记录, updateInfo, {garId});
}


/**
 * 企业成长性评分计算
 * @param assetGrowth 净资产增长率(0-1小数形式)
 * @param revenueGrowth 销售收入增长率(0-1小数形式)
 * @returns number 综合得分 0/6/8/10
 * >35%：10分
    25%-35% 8分
    15%-24% 6分
    <15%:0分
 */
async function calculateGrowthScore(assetGrowth, revenueGrowth) {
    // 处理负增长情况
    let validAsset = Math.max(0, assetGrowth);
    let validRevenue = Math.max(0, revenueGrowth);

    let assetGrowthScore = 0;
    // 净资产增长率阶梯式评分
    if (validAsset > 35) assetGrowthScore = 10;
    else if (validAsset >= 25) assetGrowthScore = 8;
    else if (validAsset >= 15) assetGrowthScore = 6;
    
    let revenueGrowthScore = 0;
    // 销售收入增长率阶梯式评分
    if (validRevenue > 35) revenueGrowthScore = 10;
    else if (validRevenue >= 25) revenueGrowthScore = 8;
    else if (validRevenue >= 15) revenueGrowthScore = 6;
    
    let result = [
        {id:"jzczzl1", score:assetGrowthScore},
        {id:"xssrzzl2", score:revenueGrowthScore},
    ];
    return result;
}


/**
 * 企业自评结果
 */
export async function enterpriseResults(garId) {
    console.log(garId);
    //获取企业自评答题记录
    let manyTableInfo:any = {};
    manyTableInfo[TABLENAME.答题记录] = {column:["totalScore", "answerTime", "answerStatus"], where:{} };
    manyTableInfo[TABLENAME.高新企业创新能力评价答题] = {column:["gaId", "answerType", "sort", "subject", "isMultipleChoice", "questionType"], where:{} };
    let answerInfo = await selectManyTableData(OPERATIONALDATATYPE.多表联查, TABLENAME.答题记录明细, {garId}, ["gadId", "garId", "gaId", "options", "questionScore"], manyTableInfo);

    if (!answerInfo) throw new BizError(ERRORENUM.答题记录不存在);

    let scores = {
        知识产权:0,
        科技成果:0,
        研发管理:0,
        企业成长:0
    }

    //计算各个类型得分
    let totalScore = 0;
    answerInfo.forEach( detail => {
        totalScore = parseInt(detail.gaoxin_answerrecord.totalScore);
        let type = detail.gaoxin_answer.answerType;
        scores[type] += parseInt(detail.questionScore);
    })

    //是否达标
    let isReach = "未达标";
    if (totalScore >= 71) isReach = "已达标";

    let lowestType = getLowestScoreRateType(scores);

    return {isReach, totalScore, scores, lowestType};
}


//计算最低得分率类型
function getLowestScoreRateType(scores) {
    // 定义各类型权重
    let weights = {
      '知识产权': 0.3,
      '科技成果': 0.3,
      '研发管理': 0.2,
      '企业成长': 0.2
    };
  
    // 计算加权得分率并找出最小值
    let results = [];
    let minRate = Infinity;
    for (let type in scores) {
        let rate = scores[type] * weights[type];
        if (rate < minRate) {
            minRate = rate;
            results.length = 0; // 清空之前的结果
            results.push(type);
        } else if (rate === minRate) {
            results.push(type);
        }
    }

    return results;
}




