/**
 * 管理后台 孵化器信息相关接口
 * 作者:lxm
 */

import * as eccFormParamConfig from "../../../config/eccParam/admin";
import * as enterpriseData from "../../../data/enterprise/enterprise";
import * as fuhuaqiData from "../../../data/fuHuaQi/fuhuaqi";
import * as splitResultConfig from "../../../config/splitResultConfig";
import * as configEnum from "../../../config/enum";
import { extractData } from "../../../util/piecemeal";
import { BizError } from "../../../util/bizError";
import { ERRORENUM } from "../../../config/errorEnum";
import { eccFormParam } from "../../../util/verificationParam";
import { changeEnumValue, eccEnumValue } from "../../../util/verificationEnum";
import { changeAddToString, getPwdMd5, md5PwdStr } from "../../../tools/system";
import * as taskTool from "../../../tools/taskTool";
import moment = require("moment");
import * as monthTableData from "../../../data/fuHuaQi/monthTask/monthTable";
import * as taskData from "../../../data/fuHuaQi/monthTask/task";
import { logHandle } from "../../../util/log";
import * as scoreData from "../../../data/fuHuaQi/score";
import * as scoreLogData from "../../../data/fuHuaQi/scoreLog";
import { starCount } from "../../mobileFuHuaQi/fuHuaQi/score";
import { sendInitPointOut } from "../../sms";

/**
 * 获取孵化器基本信息列表
 * @param lv 孵化器等级
 * @param institutionalNature 机构性质
 * @param industry 领域
 * @param operationModel 运营模式
 * @param foundingTeam 创业团队
 * @param name 运营机构名称
 * @param page 页数
 * @returns 
 */
export async function fuHuaQiBaseList(lv:number, institutionalNature:number, industry:number, operationModel:number, foundingTeam:number, name:string, page:number) {
    /**拼接查询条件 并且校验是否符合枚举范围  可优化 抽出一个方法统一校验 */
    let selectParam:any = {};
    if (lv) {
        eccEnumValue("管理后台查询孵化器列表", " 孵化器级别 ", configEnum.FUHUAQILV, lv);
        selectParam.lv = lv;
    }
    if (institutionalNature) {
        eccEnumValue("管理后台查询孵化器列表", " 机构性质 ", configEnum.INSTITUTIONALNATURE, institutionalNature);
        selectParam.institutionalNature = institutionalNature;
    }
    if (industry){
        eccEnumValue("管理后台查询孵化器列表", " 领域 ", configEnum.FUHUAINDUSTRY, industry);
        selectParam.industry = industry;
    }
    if (operationModel) {
        eccEnumValue("管理后台查询孵化器列表", " 运营模式 ", configEnum.OPERATIONMODEL, operationModel);
        selectParam.operationModel = operationModel;
    }
    if (foundingTeam) {
        eccEnumValue("管理后台查询孵化器列表", " 创业团队 ", configEnum.TEAM, foundingTeam);
        selectParam.foundingTeamType = foundingTeam;
    }
    if (name) {
        selectParam.operationName = {"$regex":`${name}`};
    }

    let startEnterpriseParam:any = {"$or":[{"$and":[{"draftLock":true}, {"taskId":{"$ne":null}}]}, {"$and":[{"draftLock":false}, {"taskId":null}]}]};
    let enterpriseMap = await enterpriseData.groupFindEnterpriseCountByParam(startEnterpriseParam);//计算孵化器拥有的累计企业数量
    startEnterpriseParam.state = configEnum.FUHUASTATE.实体孵化;
    let shiTiEnterpriseMap = await enterpriseData.groupFindEnterpriseCountByParam(startEnterpriseParam);//实体
    startEnterpriseParam.state = configEnum.FUHUASTATE.虚拟孵化;
    let xuNiEnterpriseMap = await enterpriseData.groupFindEnterpriseCountByParam(startEnterpriseParam);//虚拟
    

    let dataBaseList = await fuhuaqiData.findFuHuaQiListByPage(selectParam, (page-1)*10 );
    let count = await fuhuaqiData.findFuHuaQiCount(selectParam);

    /**拼接返回结果 */
    let dataList = [];
    dataBaseList.forEach( info => {
        /**截取所需字段 */
        let changeData:any = extractData(splitResultConfig.FuHuaQiBaseListConfig, info, true);

        changeData.enterpriseTotal = enterpriseMap[info.uscc]  || 0; //企业孵化总数（包括历史）
        changeData.virtualEnterpriseNum = xuNiEnterpriseMap[info.uscc] || 0;//虚拟企业数量
        changeData.shiTiEnterpriseNum = shiTiEnterpriseMap[info.uscc] || 0;//实体企业数量
        changeData.zaiFuEnterpriseNum = changeData.shiTiEnterpriseNum + changeData.virtualEnterpriseNum;//在孵
        let outEnterpriseNum = changeData.enterpriseTotal - changeData.zaiFuEnterpriseNum;
        changeData.outEnterpriseNum = outEnterpriseNum < 0 ? 0 : outEnterpriseNum;//迁出

        /**备案地址转换 */
        if (changeData.hatchingGround) {
            let hatchingGround = [];
            changeData.hatchingGround.forEach(info => {
                info.personInChargeAdd = changeAddToString(info.personInChargeAddress);
                hatchingGround.push({
                    siteAcreage:info.siteAcreage,//孵化场地面积(㎡)
                    leasePrice:info.leasePrice,//孵化场地出租单价
                    personInChargeAdd:changeAddToString(info.personInChargeAddress)
                });
            });
            changeData.hatchingGround = hatchingGround;
        }

        /**枚举转换 */
        changeData.lv = changeEnumValue(configEnum.FUHUAQILV, changeData.lv);
        changeData.industry = changeEnumValue(configEnum.FUHUAINDUSTRY, changeData.industry);
        changeData.institutionalNature = changeEnumValue(configEnum.INSTITUTIONALNATURE, changeData.institutionalNature);
        changeData.operationModel = changeEnumValue(configEnum.OPERATIONMODEL, changeData.operationModel);
        changeData.fuHuaLianXiDiZhi = changeAddToString(info.fuHuaLianXiDiZhi);
        changeData.fuHuazhuCeDiZhi = changeAddToString(info.fuHuazhuCeDiZhi);

        changeData.foundingTeamStr = changeData.foundingTeamType ? changeEnumValue(configEnum.TEAM, changeData.foundingTeamType) : "无";
        let foundingTeam = [];
        if (changeData.foundingTeam && changeData.foundingTeam.length) {
            changeData.foundingTeam.forEach(item => {
                let {memberName,  memberAge,  memberSchool,  des} = item;
                let type = changeEnumValue(configEnum.TEAM, item.type);//人才类型
                foundingTeam.push({
                    memberName,  memberAge,  memberSchool,  des, type,
                    memberSex : changeEnumValue(configEnum.SEX, item.memberSex),//成员性别
                    memberDEGREE : changeEnumValue(configEnum.DEGREE, item.memberDEGREE),//成员最高学历
                });

            });
            changeData.foundingTeam = foundingTeam;
        }

        changeData.ruZhuFeiFuHuaQiYe = 0;//入住非孵化企业
        changeData.caiLiHuGuanDiZhi = "-";//财力互管地址

        dataList.push(changeData);
    });

    return {count, dataList};
}



/**
 * 导出符合条件的孵化器基本信息数据 
  * @param lv 孵化器等级
 * @param institutionalNature 机构性质
 * @param industry 领域
 * @param operationModel 运营模式
 * @param foundingTeam 创业团队
 * @param type 导出类型 OUTPUTTYPE 枚举
 * @returns 
 */
export async function outPutFuHuaQiBaseData(lv:number, institutionalNature:number, industry:number, operationModel:number, foundingTeam:number,  name:string, type:Number) {
    let selectParam:any = {};
    if (type == configEnum.OUTPUTTYPE.当前数据) {
        /**当选择了当前数据时 拼接查询条件 */
        if (lv) {
            eccEnumValue("管理后台查询孵化器列表", " 孵化器级别 ", configEnum.FUHUAQILV, lv);
            selectParam.lv = lv;
        }
        if (institutionalNature) {
            eccEnumValue("管理后台查询孵化器列表", " 机构性质 ", configEnum.INSTITUTIONALNATURE, institutionalNature);
            selectParam.institutionalNature = institutionalNature;
        }
        if (industry){
            eccEnumValue("管理后台查询孵化器列表", " 领域 ", configEnum.FUHUAINDUSTRY, industry);
            selectParam.industry = industry;
        }
        if (operationModel) {
            eccEnumValue("管理后台查询孵化器列表", " 运营模式 ", configEnum.OPERATIONMODEL, operationModel);
            selectParam.operationModel = operationModel;
        }
        if (foundingTeam) {
            eccEnumValue("管理后台查询孵化器列表", " 创业团队 ", configEnum.TEAM, foundingTeam);
            selectParam.foundingTeamType = foundingTeam;
        }
        if (name) {
            selectParam.operationName = {"$regex":`${name}`};
        }
    }

    let startEnterpriseParam:any = {"$or":[{"$and":[{"draftLock":true}, {"taskId":{"$ne":null}}]}, {"$and":[{"draftLock":false}, {"taskId":null}]}]};
    let enterpriseMap = await enterpriseData.groupFindEnterpriseCountByParam(startEnterpriseParam);//计算孵化器拥有的累计企业数量
    startEnterpriseParam.state = configEnum.FUHUASTATE.实体孵化;
    let shiTiEnterpriseMap = await enterpriseData.groupFindEnterpriseCountByParam(startEnterpriseParam);//实体
    startEnterpriseParam.state = configEnum.FUHUASTATE.虚拟孵化;
    let xuNiEnterpriseMap = await enterpriseData.groupFindEnterpriseCountByParam(startEnterpriseParam);//虚拟

    let dataBaseList = await fuhuaqiData.findFuHuaQiList(selectParam);

    /**拼接二维数组 */
    let keyList = [
        "name", "operationName", "uscc", "enterpriseTotal", "virtualEnterpriseNum", "shiTiEnterpriseNum","zaiFuEnterpriseNum", "outEnterpriseNum",
        "logonTime", "incubatedAcreage","acreageTotal", "acreagePersonalUse", "lv", "identificationTime", 
        "industry", "institutionalNature","liaison", "liaisonPhone", "personInCharge", "personInChargePhone", 
        "operationModel", "foundingTeamType",
    ];
    let titleList = [
        "名称", "运营机构名称", "统一信用代码", "累计孵化企业数量", "虚拟孵化", "实体孵化","在孵企业数","迁出企业数",
        "注册时间", "在孵面积", "孵化器总面积", "孵化器自用面积", "孵化器级别", "认定时间",
        "领域", "机构性质", "联系人", "联系电话", "负责人", "负责人联系电话",
        "运营模式","孵化器创始团队"
    ];
    let dataList = [];
    let maxTeamNumber = 0;//最大团队数
    let maxHatching = 0;//最大场地数
    dataBaseList.forEach( info => {
        let {uscc} = info;
        /**截取需要的返回字段 */
        let changeData:any = extractData(splitResultConfig.FuHuaQiBaseListConfig, info, true);

        changeData.enterpriseTotal = enterpriseMap[uscc]  || 0; //企业孵化总数（包括历史）
        changeData.virtualEnterpriseNum = xuNiEnterpriseMap[uscc] || 0;//虚拟企业数量
        changeData.shiTiEnterpriseNum = shiTiEnterpriseMap[uscc] || 0;//实体企业数量
        changeData.zaiFuEnterpriseNum = changeData.shiTiEnterpriseNum + changeData.virtualEnterpriseNum;
        let outEnterpriseNum = changeData.enterpriseTotal - changeData.zaiFuEnterpriseNum ;
        changeData.outEnterpriseNum = outEnterpriseNum <= 0 ? 0 : outEnterpriseNum;

        /**枚举转换 */
        changeData.lv = changeEnumValue(configEnum.FUHUAQILV, changeData.lv);
        changeData.industry = changeEnumValue(configEnum.FUHUAINDUSTRY, changeData.industry);
        changeData.institutionalNature = changeEnumValue(configEnum.INSTITUTIONALNATURE, changeData.institutionalNature);
        changeData.operationModel = changeEnumValue(configEnum.OPERATIONMODEL, changeData.operationModel);
        changeData.foundingTeamType = changeEnumValue(configEnum.TEAM, changeData.foundingTeamType) || "无";

        /**算出最大的创始团队和场地 用于计算x轴下标 */
        if (changeData.foundingTeam && changeData.foundingTeam.length ) {
            maxTeamNumber = Math.max(changeData.foundingTeam.length, maxTeamNumber);
        }
        if (changeData.hatchingGround && changeData.hatchingGround.length ) {
            maxHatching = Math.max(changeData.hatchingGround.length, maxHatching);
        }

        /**生成除了创始团队和场地之外的 小数组 */
        let subList = [];
        keyList.forEach(key => {
            let value = changeData[key];
            if (value == null || value == undefined) value = "-";
            subList.push(value);
        });

        dataList.push(subList);
    });

    /**根据最大的创始团队数量 生成标题 */
    let teamKeyList = ["memberName", "memberSexStr", "memberAge", "memberDEGREEStr", "memberSchool", "des"];
    let teamTitleList = ["成员姓名", "成员性别", "成员年龄", "成员最高学历", "毕业学校", "履历描述"];
    for (let i = 0; i < maxTeamNumber; i++) {//平铺的插入数据
        let teamNum = i+1;
        teamTitleList.forEach(title => {
            titleList.push(`成员${teamNum}-${title}`);
        });
    }
    let firstTitleAndTeamTitleIndex = titleList.length-1;

    /**根据最大的场地数量 生成标题 */
    // let hatchingKeyList = [ "personInChargeAddress", "siteAcreage", "leasePrice" ];
    let hatchingTitleList = ["孵化场地地址", "孵化场地面积", "孵化场地出租单价" ];
    for (let i = 0; i < maxHatching; i++) {
        let hatchingNumber = i+1;
        hatchingTitleList.forEach(title => {
            titleList.push(`场地${hatchingNumber}-${title}`);
        });
    }

    /**创始团队初始插入数据的x轴下标 = titleList的长度
     * 场地初始插入数据的x轴下标 = titleList的长度+(创始团队长度*标题个数)
     * 按照这个规则依次插入数据即可
    */
    dataBaseList.forEach((info, index) => {
        if (info.foundingTeam && info.foundingTeam.length ) {
            info.foundingTeam.forEach(teamInfo => {
                teamInfo.memberSexStr = changeEnumValue(configEnum.SEX, teamInfo.memberSex);
                teamInfo.memberDEGREEStr = changeEnumValue(configEnum.DEGREE, teamInfo.memberDEGREE);
                teamKeyList.forEach( teamKey => {
                    dataList[index].push(teamInfo[teamKey]);
                });
            });
        }
        if (info.hatchingGround && info.hatchingGround.length ) {
            info.hatchingGround.forEach((hatchingInfo, hatchingIndex) => {
                let itemStartIndex = firstTitleAndTeamTitleIndex+(hatchingIndex*3);
                let personInChargeAdd = hatchingInfo["personInChargeAddress"] ? JSON.stringify(hatchingInfo["personInChargeAddress"]) : '-'; 
                dataList[index][itemStartIndex+1] =  personInChargeAdd;
                dataList[index][itemStartIndex+2] = hatchingInfo["siteAcreage"] || "-";
                dataList[index][itemStartIndex+3] = hatchingInfo["leasePrice"] || "-";
            });
        }
    });

    /**将标题作数组为二维数组的第一个子数组 */
    dataList.unshift(titleList)
    return dataList;
}


/**
 * 修改账号状态  禁用/启用 
 * @param uscc 孵化器统一信用代码
 * @param userStatem 是否禁用  true=启用 false=禁用
 * @returns 
 */
export async function updateState(uscc:string, userState:boolean) {
    let fuhuaqiInfo = await fuhuaqiData.findFuHuaQiByUSCC(uscc);
    if(!fuhuaqiInfo) throw new BizError(ERRORENUM.账号不存在);
    
    fuhuaqiInfo.userState = userState;
    await fuhuaqiInfo.save();
    
    return {isSuccess:true};
}


/**
 * 添加孵化器账号
 * @param param 表单信息
 * @returns 
 */
export async function addUser(param) {
    eccFormParam("新增孵化器账号信息", eccFormParamConfig.FuHuaQiUserConfig, param);//校验表单参数

    let uscc = param.uscc;//统一信用代码

    let fuhuaqiInfo = await fuhuaqiData.findFuHuaQiByUSCC(uscc);
    if ( fuhuaqiInfo ) throw new BizError(ERRORENUM.该孵化器账号信息已存在, `${uscc}`);
    
    /**生成密码 */
    const Pwd = uscc.slice(uscc.length-6);
    param.pwd = getPwdMd5(uscc, md5PwdStr(Pwd));
    
    param.createTime = new Date().valueOf(); //创建时间

    //创建孵化器账号
    await fuhuaqiData.createFuHuaQiUser(param); 
    //初始化分数
    await scoreData.createFuHuaQiScore(param.uscc, 400);
    
    const MonthNumber = moment().subtract(1, 'months').month() + 1;//数据填报月份
    const YearNumber =moment().subtract(1, 'months').year();//数据填报年度
    const TimeKey = taskTool.getTimeKey();//获取当前时间标识
    let taskId = taskTool.generateMonthTaskId(uscc);//生成月度任务Id

    //月度任务列表
    let taskAddList = [
        { key:TimeKey, type:configEnum.TASKTYPEENUM.孵化器月度填报, month:MonthNumber, taskId, fuHuaQiUscc:uscc, isSubmit:false, year:YearNumber},
        { key:TimeKey, type:configEnum.TASKTYPEENUM.新注册或迁入企业登记, month:MonthNumber, taskId, fuHuaQiUscc:uscc, isSubmit:false , year:YearNumber},
        { key:TimeKey, type:configEnum.TASKTYPEENUM.融资企业填报, taskId, month:MonthNumber, fuHuaQiUscc:uscc, isSubmit:false, year:YearNumber}
    ];
    
    /**任务报表的初始状态为 草稿(draftLock=fals) 未被编辑(isUpdate=false) 月度填报列表 */
    let monthList = [
        { taskId, name:`${MonthNumber}月孵化器月度填报`, fuHuaQiUscc:uscc, month:MonthNumber, year:YearNumber, draftLock:false, isUpdate:false }
    ];

    try {
        /**初始化 任务 */
        await taskData.createTaskToList(taskAddList);
        logHandle(`${uscc} 月度任务初始化成功`);
         /**初始化 月度填报表 */
        await monthTableData.createMonthTableToList(monthList);
        logHandle(`${uscc} 月度填报初始化成功`);
    } catch (err) {
        new BizError(ERRORENUM.系统错误, '添加任务和月度报表的时候 出现了异常 请检查数据库  ', err);
    }

    /**发送初始化账号短信提示 */
    await sendInitPointOut(param.personInChargePhone);
    
    return {isSuccess:true};
}


/**
 * 孵化器账号信息列表
 * @param operationName 运营机构名称
 * @param page 页数
 * @returns 
 */
export async function fuHuaQiUserList(operationName:string, page:number) {
    let selectParam:any = {};
    if (operationName) {
        selectParam.operationName = {"$regex":`${operationName}`};
    }

    let dataBaseList = await fuhuaqiData.findFuHuaQiListByPage(selectParam, (page-1)*10 );
    let count = await fuhuaqiData.findFuHuaQiCount(selectParam);
    let dataList = [];
    dataBaseList.forEach( info => {
        let changeData:any = extractData(splitResultConfig.FuHuaQiListConfig, info, true);
        changeData.liaison = info.personInCharge;//todo 这里陈金晶写的有bug 后续记得把协议和后台重新顶一下
        dataList.push(changeData);
    });

    return {count, dataList};
}


/**
 * 查询孵化器评分排名
 * @param time 月份时间戳
 * @param name 孵化器机构名称  带模糊查询
 * @param pange 查询页面
 */
export async function fuHuaQiScore(time:number, name:string, page:number) {
    let nameMap = await fuhuaqiData.findFuHuaQiOperationNameMapByParam({});
    let param:any = {};
    if (name) {
        param.uscc = "-1";
        for (let key in nameMap) {
            if (nameMap[key] == name) param.uscc = key;
        }
    }

    let rankList = [];
    if (!time) {
        let scoreDataList = await scoreData.findScoreDataByParam(param);
        
        scoreDataList.forEach((info) => {
            let name = nameMap[info.uscc]
            if (!name) return;
            let score = Math.ceil(info.startScore+info.myDataScore+info.baseDataScore+info.myEnterpriseScore+info.taskScore);
            let star = starCount(score);
            rankList.push({ uscc:info.uscc, name, star, score });
        });
       
        
    } else {
        param.timeMs = {"$lt":moment(time).endOf('month').valueOf() } 
        let datList = await scoreLogData.getUptotheminuteScore(param);
        
        datList.forEach(info => {
            let name = nameMap[info._id]
            if (!name) return;
            let score = Math.ceil(info.maxScore);
            let star = starCount(score);
            rankList.push({ uscc:info._id, name, star, score });
        });

    }
    rankList.sort((a, b) => { return b.score - a.score} );
    rankList.forEach((info, index) => {
        info.rank = index + 1;
    });

    let resultList = rankList.splice((page-1 )* 10, 10);
    let pageCount = Math.ceil(rankList.length/10);

    return {count:rankList.length, dataList:resultList, pageCount };
}


/**
 * 导出孵化器评分排名
 * @param time 月份时间戳
 */
export async function outPutFuHuaQiScore(time:number) {
    let nameMap = await fuhuaqiData.findFuHuaQiOperationNameMapByParam({});
    let param:any = {};
    let outPutName = "";
    let rankList = [];
    if (!time) {
        outPutName = "当前";
        let scoreDataList = await scoreData.findScoreDataByParam(param);
        
        scoreDataList.forEach((info) => {
            let name = nameMap[info.uscc]
            if (!name) return;
            let score = info.startScore+info.myDataScore+info.baseDataScore+info.myEnterpriseScore+info.taskScore;
            let star = starCount(score);
            rankList.push({ uscc:info.uscc, name, star, score });
        });
       
        
    } else {
        param.timeMs = {"$lt":moment(time).endOf('month').valueOf() } 
        let datList = await scoreLogData.getUptotheminuteScore(param);
        outPutName = `${new Date(time).getFullYear()}年${new Date(time).getMonth() + 1}月`;
        datList.forEach(info => {
            let name = nameMap[info._id]
            if (!name) return;
            let star = starCount(info.maxScore);
            rankList.push({ uscc:info._id, name, star, score:info.maxScore });
        });

    }
    rankList.sort((a, b) => { return b.score - a.score} );

    let outPutList = [["孵化器运营机构名称", "当前排名", "当前分值（本年度）", "当前孵化器等级"]];

    rankList.forEach((info, index) => {
        info.rank = index + 1;
        outPutList.push([info.name, info.rank, info.score, info.star]); 
    });

    return {outPutList, outPutName};
}


/**
 * 修改孵化器联系人和联系人号码
 * @param uscc 孵化器统一信用代码
 * @param phone 联系人电话
 * @param name 联系人
 * @returns 
 */
export async function updateFuHuaQiData(uscc:string, phone:string, name:string) {
    let fuHuaQiInfo = await fuhuaqiData.findFuHuaQiByUSCC(uscc);

    if (!fuHuaQiInfo) throw new BizError(ERRORENUM.未找到数据, '管理后台修改孵化器信息');

    fuHuaQiInfo.personInCharge = name;
    fuHuaQiInfo.personInChargePhone = phone;

    await fuHuaQiInfo.save();

    return {isSuccess:true};
}
