/**
 * 小程序端 孵化器入口 企业相关逻辑
 * 作者: lxm
 * 包括新注册企业，迁入企业
 * 
 */

import * as eccFormParamConfig from "../../../config/eccFormParamConfig";
import { ERRORENUM } from "../../../config/errorEnum";
import { BizError } from "../../../util/bizError";
import * as sysTools from "../../../tools/system";
import * as enterpriseData from "../../../data/enterprise/enterprise";
import * as splitResultConfig from "../../../config/splitResultConfig";
import * as configEnum from "../../../config/enum";
import { eccFormParam, eccReqParamater } from "../../../util/verificationParam";
import * as verificationEnumTools from "../../../util/verificationEnum";
import { checkChange, extractData } from "../../../util/piecemeal";
import * as scoreBiz from "../fuHuaQi/score";


/**
 * 添加新注册企业
 * 小程序端
 * @param uscc 孵化器统一信用代码
 * @param param 表单参数
 * @returns {isSuccess:true/false}
 */
export async function registerEnterprise(uscc:string, param) {
    /**校验表单参数 */
    eccFormParam("新注册企业", eccFormParamConfig.RegisterEnterpriseParamConfig, param);
    verificationEnumTools.eccEnumValue('添加新注册企业', 'industry', configEnum.INDUSTRY, param.industry);
    if ( !sysTools.eccUscc(param.uscc) ) throw new BizError(ERRORENUM.统一社会信用代码不合法);

    /**不能出现重复的统一社会信用代码 草稿的也不行 */
    let dataBaseInfo = await enterpriseData.findEnterpriseByUscc(param.uscc);
    if ( dataBaseInfo&& dataBaseInfo.uscc)  throw new BizError(ERRORENUM.该企业已存在, `${param.uscc}已经在库中存在`);

    /**添加新注册企业标识 */
    param.draftId = sysTools.getDraftId(uscc);//草稿箱id
    param.isCreate = true;//标识此次操作是否是新注册企业并不是迁入企业
    const TaskId = sysTools.getTaskId(uscc);
    param.state = configEnum.FUHUASTATE.实体孵化;
    await enterpriseData.createEnterprise(uscc, TaskId, param);

    return {isSuccess:true};
}


/**
 * 修改新注册企业的表单
 * 小程序端
 * @param uscc 孵化器统一信用代码
 * @param param 表单参数
 * @returns {isSuccess:true/false}
 */
export async function updateRegisterEnterprise(uscc:string, param) {
    /**校验表单参数 */
    eccFormParam("新注册企业表单修改", eccFormParamConfig.EnterpriseParamFormConfig, param );
    verificationEnumTools.eccEnumValue('修改新注册企业', 'industry', configEnum.INDUSTRY, param.industry);
    if ( !sysTools.eccUscc(param.uscc) ) throw new BizError(ERRORENUM.统一社会信用代码不合法);

    let dataBaseInfo = await enterpriseData.findEnterpriseByDraftId(param.draftId);
    if (!dataBaseInfo || !dataBaseInfo.uscc) throw new BizError(ERRORENUM.未找到数据, `库中不存在${param.uscc}这个企业`);

    /**修改时校验uscc是否重复 */
    let selectInfo = await enterpriseData.selectOneEnterpriseByParam({uscc:param.uscc, draftId:{"$ne":param.draftId} });
    if (selectInfo && selectInfo.uscc) throw new BizError(ERRORENUM.统一社会信用代码重复, `${param.uscc}已经在库中存在 不可以修改为这个统一信用代码`);

    /**如果是本月提交的，可以修改，如果不是，则不可以修改 */
    if ( sysTools.getThisMonthMs() > dataBaseInfo.createTime) {
        throw new BizError(ERRORENUM.不能修改过期任务数据, `修改新注册企业的表单 ${uscc} 违法操作`);
    }

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

    await dataBaseInfo.save();

    return {isSuccess:true};
}


/**
 * 添加迁入企业登记
 * 小程序端
 * @param uscc 孵化器统一信用代码
 * @param param 表单参数
 * @returns {isSuccess:true/false}
 */
export async function moveInEnterprise(uscc:string, param) {
    /**校验表单参数 */
    eccFormParam("迁入企业登记", eccFormParamConfig.MoveInEnterpriseParamConfig, param );
    verificationEnumTools.eccEnumValue('添加迁入企业', 'industry', configEnum.INDUSTRY, param.industry);
    if ( !sysTools.eccUscc(param.uscc) ) throw new BizError(ERRORENUM.统一社会信用代码不合法);

    /**不能出现重复的统一社会信用代码 草稿的也不行 */
    let dataBaseInfo = await enterpriseData.findEnterpriseByUscc(param.uscc);
    if ( dataBaseInfo&& dataBaseInfo.uscc)  throw new BizError(ERRORENUM.该企业已存在, `${param.uscc}已经在库中存在`);

    /**添加新注册企业标识 */
    param.draftId = sysTools.getDraftId(uscc);//草稿箱id
    param.isCreate = false;//标识此次操作是否是迁入企业并不是新注册企业
    const TaskId =  sysTools.getTaskId(uscc);
    param.state = configEnum.FUHUASTATE.实体孵化;//默认就是实体孵化

    await enterpriseData.createEnterprise(uscc, TaskId, param);

    return {isSuccess:true};
}


/**
 * 修改迁入企业登记信息
 * 小程序端
 * @param uscc 孵化器统一信用代码
 * @param param 表单参数
 * @returns {isSuccess:true/false}
 */
export async function updateMoveInEnterprise(uscc:string, param) {
    /**校验表单参数 */
    eccFormParam("修改迁入企业登记信息", eccFormParamConfig.EnterpriseInPutParamFormConfig, param);
    verificationEnumTools.eccEnumValue('修改迁入企业', 'industry', configEnum.INDUSTRY, param.industry);
    if ( !sysTools.eccUscc(param.uscc) ) throw new BizError(ERRORENUM.统一社会信用代码不合法);

    /**企业库中是否存在记录 */
    let dataBaseInfo = await enterpriseData.findEnterpriseByDraftId(param.draftId);
    if (!dataBaseInfo || !dataBaseInfo.uscc) throw new BizError(ERRORENUM.未找到数据, `库中不存在${param.uscc}这个企业`);

    /**修改时校验uscc是否重复 */
    let selectInfo = await enterpriseData.selectOneEnterpriseByParam({uscc:param.uscc, draftId:{"$ne":param.draftId} });
    if (selectInfo && selectInfo.uscc) throw new BizError(ERRORENUM.统一社会信用代码重复, `${param.uscc}已经在库中存在 不可以修改为这个统一信用代码`);

    /**如果是本月提交的，可以修改，如果不是，则不可以修改 */
    if ( sysTools.getThisMonthMs() > dataBaseInfo.createTime) {
        throw new BizError(ERRORENUM.不能修改过期任务数据, `修改新注册企业的表单 ${uscc} 违法操作`);
    }
    
    /**修改数据 */
    let changeList = checkChange(param, dataBaseInfo);
    if ( !changeList.length ) throw new BizError(ERRORENUM.数据无更新, `${param.uscc}数据无更新`);
    changeList.forEach(key => {
        dataBaseInfo[key] = param[key];
    });
    await dataBaseInfo.save();

    return {isSuccess:true};
}


/**
 * 根据企业id查询企业信息
 * 包括新迁入企业和新注册企业的回显
 * 小程序端  回显
 * @param uscc 企业统一信用代码
 * @param draftId 草稿id
 * @returns {data} data 返回表单
 */
export async function getEnterpriseByDraftId(draftId:string) {
    let dataBaseInfo = await enterpriseData.findEnterpriseByDraftId(draftId);
    if (!dataBaseInfo || !dataBaseInfo.uscc) throw new BizError(ERRORENUM.未找到数据, `库中不存在draftId=${draftId}这个企业`);

    /**新注册企业和迁入企业回显信息不一样 */
    let data:any = {};
    if (dataBaseInfo.isCreate) data = extractData(splitResultConfig.EnterpriseInfoConfig, dataBaseInfo, false);
    else data = extractData(splitResultConfig.EnterpriseMoveInInfoConfig, dataBaseInfo, false);

    return {data};
}


/**
 * 根据企业id删除草稿企业
 * 小程序端
 * @param uscc 企业统一信用代码
 * @param draftId 草稿id
 * @returns {isSuccess:true/false}
 */
export async function deleteEnterpriseByDraftId(draftId:string) {
    let dataBaseInfo = await enterpriseData.findEnterpriseByDraftId(draftId);
    /**删除限制 */
    if (!dataBaseInfo || !dataBaseInfo.uscc) throw new BizError(ERRORENUM.未找到数据, `库中不存在draftId=${draftId}这个企业`);
    if (dataBaseInfo.draftLock) throw new BizError(ERRORENUM.已入库的数据不能删除, draftId);

    await enterpriseData.deleteEnterprise(draftId);

    return {isSuccess:true};
}


/**
 * 我的企业列表
 * 小程序端 2.0
 * @param uscc 孵化器统一信用代码
 * @param state 孵化器状态 遵循 枚举FUHUASTATE
 * @param name 孵化器名称
 * @param page 当前页面
 */
export async function myEnterprise(uscc:string, state:number, name:string, page:number) {
    
    let result:any = {};

    let selectParam:any = { fuHuaQiUscc:uscc};
    if (name) selectParam.name = {"$regex":`${name}`};
    if (state == configEnum.INSIDESTATE.全部) {
        selectParam.state = {"$lt":4};
    } else selectParam.state = state;
    
    let dataList = await enterpriseData.findEnterpriseListToPage(selectParam, (page-1)*10);

    /**当前条件数据量 */
    let dataCount = await enterpriseData.findEnterpriseCount(selectParam);
    /**当前条件页面数量 */
    result.dataCount = dataCount;
    result.pageCount = Math.ceil(dataCount/10);

    if (state != configEnum.FUHUASTATE.迁出) {
        /**查询所有的数据量 */
        let allCount = await enterpriseData.findEnterpriseCount({ fuHuaQiUscc:uscc });
        let virtualCount = 0;
        if (state == configEnum.FUHUASTATE.虚拟孵化) virtualCount = dataCount;
        else virtualCount = await enterpriseData.findEnterpriseCount({ fuHuaQiUscc:uscc, state:configEnum.FUHUASTATE.虚拟孵化 });

        result.dataNumberList = [
            {key:configEnum.INSIDESTATE.全部, value:`全部(${allCount})`},
            {key:configEnum.INSIDESTATE.实体孵化, value:`实体孵化(${allCount-virtualCount})`},
            {key:configEnum.INSIDESTATE.虚拟孵化, value:`虚拟孵化(${virtualCount})`},
        ];

    }

    let enterpriseList = [];

    dataList.forEach(info => {
        let changeData:any = extractData(splitResultConfig.MyEnterpriseDataConfig, info, false);
        if (state != configEnum.FUHUASTATE.迁出) {
            changeData.virtualCause = info.virtualCause || 0;
            changeData.virtualCauseDes = info.virtualCauseDes || "";
        }

        changeData.state = verificationEnumTools.changeEnumValue(configEnum.FUHUASTATE, changeData.state);
      
        enterpriseList.push(changeData);
    });

    result.enterpriseList = enterpriseList;
    
    return result;
}


/**
 * 修改企业孵化状态 修改为实体
 * 小程序端 2.0
 * @param fuHuaQiUscc 孵化器统一信用代码
 * @param uscc 企业统一信用代码
 * @param leasedArea 租赁面积
 * @returns {isSuccess:true/false}
 */
export async function updatePhysicalInfo(fuHuaQiUscc:string, uscc:string, leasedArea:number) {
    let enterpriseInfo = await enterpriseData.findEnterpriseByUscc(uscc);
    if (!enterpriseInfo) throw new BizError(ERRORENUM.该企业不存在, "修改企业孵化状态 修改为实体",`孵化器 ${fuHuaQiUscc} -> 企业${uscc}`);

    if (enterpriseInfo.fuHuaQiUscc != fuHuaQiUscc) throw new BizError(ERRORENUM.无法操作其他孵化器的企业, "修改企业孵化状态 修改为实体",`孵化器 ${fuHuaQiUscc} -> 企业${uscc}`);

    enterpriseInfo.leasedArea = leasedArea;
    enterpriseInfo.state = configEnum.FUHUASTATE.实体孵化;

    /**修改为实体，需要把虚拟的和迁出的字段清空 */
    enterpriseInfo.virtualCause = null;//虚拟孵化模式
    enterpriseInfo.virtualCauseDes = "";//虚拟孵化原因
    enterpriseInfo.moveOutType = null;//迁出类型
    enterpriseInfo.moveOutCause = [];//迁出原因
    enterpriseInfo.moveOutTime = 0;

    await enterpriseInfo.save();

    return {isUsccess:true};
}


/**
 * 修改企业孵化状态 修改为虚拟
 * 小程序端 2.0
 * @param fuHuaQiUscc 孵化器统一信用代码
 * @param uscc 企业统一信用代码
 * @param virtualCauseDes 虚拟孵化其他原因
 * @param virtualCause 虚拟孵化模式
 * @returns {isSuccess:true/false}
 */
export async function updateVirtualInfo(fuHuaQiUscc:string, uscc:string, virtualCauseDes:string, virtualCause:number) {
    verificationEnumTools.eccEnumValue('修改企业孵化状态', '修改为虚拟', configEnum.VIRTUALCAUSE, virtualCause);

    if (virtualCause == configEnum.VIRTUALCAUSE.其他 && !virtualCauseDes) {
        throw new BizError(ERRORENUM.请填入其他原因, "修改企业孵化状态 修改为虚拟", `virtualCause:${virtualCause}, virtualCauseDes:${virtualCauseDes}`);
    }

    let enterpriseInfo = await enterpriseData.findEnterpriseByUscc(uscc);
    if (!enterpriseInfo) throw new BizError(ERRORENUM.该企业不存在, "修改企业孵化状态 修改为实体",`孵化器 ${fuHuaQiUscc} -> 企业${uscc}`);

    if (enterpriseInfo.fuHuaQiUscc != fuHuaQiUscc) throw new BizError(ERRORENUM.无法操作其他孵化器的企业, "修改企业孵化状态 修改为实体",`孵化器 ${fuHuaQiUscc} -> 企业${uscc}`);

    enterpriseInfo.virtualCause = virtualCause;
    if (virtualCauseDes)  enterpriseInfo.virtualCauseDes = virtualCauseDes;

    enterpriseInfo.state = configEnum.FUHUASTATE.虚拟孵化;

    /**修改为虚拟时，需要把实体的和迁出的字段清空 */
    enterpriseInfo.moveOutType = null;//迁出类型
    enterpriseInfo.moveOutCause = [];//迁出原因
    enterpriseInfo.leasedArea = 0;//租赁面积
    enterpriseInfo.moveOutTime = 0;

    await enterpriseInfo.save();

    return {isUsccess:true};
}


/**
 * 修改企业孵化状态 修改为迁出
 * 小程序端 2.0
 * @param fuHuaQiUscc 孵化器统一信用代码
 * @param uscc 企业统一信用代码
 * @param moveOutType 迁出类型
 * @param moveOutTrace 迁出去向 2.3新加字段
 * @param moveOutCause 迁出原因 多选
 * @returns {isSuccess:true/false}
 */
export async function updateMoveOutInfo(fuHuaQiUscc:string, uscc:string,  moveOutType:number, moveOutTrace:number, moveOutCause ) {
    /**校验参数 */
    verificationEnumTools.eccEnumValue('修改企业孵化状态', '修改为迁出', configEnum.MOVEOUTTYPE, moveOutType);
    if (moveOutType != configEnum.MOVEOUTTYPE.企业注销 ) {
        //选择了 非企业注销时 moveOutTrace 和 moveOutCause  为必选项
        await eccReqParamater({moveOutTrace:"Number", moveOutCause:"[Number]" }, {moveOutTrace, moveOutCause} );
        /**校验moveOutCause 和 moveOutTrace  是否符合规则*/
        verificationEnumTools.eccEnumValue('修改企业孵化状态', '修改为迁出', configEnum.MOVEOUTTRACE, moveOutTrace);
        verificationEnumTools.eccEnumValue('修改企业孵化状态', '修改为迁出', configEnum.MOVEOUTCAUSE, moveOutCause);
        /**根据 不同的迁出类型 校验不同的迁出原因枚举 */
        if (moveOutType == configEnum.MOVEOUTTYPE.毕业迁出) {
            moveOutCause = [moveOutCause[0]];//非毕业迁出是单选
            verificationEnumTools.eccEnumValue('修改企业孵化状态', '修改为迁出', configEnum.MOVEOUTCAUSECLIENT, moveOutCause);
        }
        if (moveOutType == configEnum.MOVEOUTTYPE.非毕业迁出) {
            verificationEnumTools.eccEnumValue('修改企业孵化状态', '修改为迁出', configEnum.MOVEOUTCAUSENOTCLIENT, moveOutCause);
        }
    } else {
        /**如果是选择了企业注销 这里的两个参数要为空 */
        moveOutTrace = 0;
        moveOutCause = [];
    }
    

    let enterpriseInfo = await enterpriseData.findEnterpriseByUscc(uscc);
    if (!enterpriseInfo) throw new BizError(ERRORENUM.该企业不存在, "修改企业孵化状态 修改为实体",`孵化器 ${fuHuaQiUscc} -> 企业${uscc}`);

    if (enterpriseInfo.fuHuaQiUscc != fuHuaQiUscc) throw new BizError(ERRORENUM.无法操作其他孵化器的企业, "修改企业孵化状态 修改为实体",`孵化器 ${fuHuaQiUscc} -> 企业${uscc}`);

    enterpriseInfo.moveOutType = moveOutType;
    enterpriseInfo.moveOutCause = moveOutCause;
    enterpriseInfo.moveOutTrace = moveOutTrace;
    enterpriseInfo.moveOutTime = new Date().valueOf();

    enterpriseInfo.state = configEnum.FUHUASTATE.迁出;

    /**修改为迁出时，需要把实体的和虚拟的字段清空 */
    enterpriseInfo.virtualCause = null;//虚拟孵化模式
    enterpriseInfo.virtualCauseDes = "";//虚拟孵化原因
    enterpriseInfo.leasedArea = 0;//租赁面积

    await enterpriseInfo.save();

    return {isUsccess:true};
}



/**
 * 企业基本信息 回显
 * 小程序端 2.0
 * @param fuHuaQiUscc 孵化器统一信用代码
 * @param uscc 企业统一信用代码
 */
export async function getMyEnterpriseBaseInfo(fuHuaQiUscc:string, uscc:string) {
    
    let enterpriseInfo = await enterpriseData.findEnterpriseByUscc(uscc);

    if (!enterpriseInfo) throw new BizError(ERRORENUM.该企业不存在, `我的企业 回显企业信息 ${uscc}`);
    if ( enterpriseInfo.fuHuaQiUscc != fuHuaQiUscc) throw new BizError(ERRORENUM.无法操作其他孵化器的企业, '企业基本信息回显', `孵化器:${fuHuaQiUscc} 企业:${uscc}`);

    let changeData = extractData(splitResultConfig.MyEnterpriseBaseDataConfig, enterpriseInfo, false);

    return {enterpriseInfo:changeData};
}


/**
 * 修改我的企业基本信息
 * 小程序端 2.0
 * @param fuHuaQiUscc 孵化器统一信用代码 
 * @param param 表单
 */
export async function updateMyEnterpriseBaseInfo(fuHuaQiUscc:string, param) {
    
    eccFormParam("修改我的企业基本信息", eccFormParamConfig.UpdateMyEnterpriseBaseDataConfig, param );
    verificationEnumTools.eccEnumValue('修改新注册企业', 'industry', configEnum.INDUSTRY, param.industry);
    if ( !sysTools.eccUscc(param.uscc) ) throw new BizError(ERRORENUM.统一社会信用代码不合法);

    const Uscc = param.uscc;
    let enterpriseInfo = await enterpriseData.findEnterpriseByUscc(Uscc);

    if (!enterpriseInfo) throw new BizError(ERRORENUM.该企业不存在, `我的企业 修改我的企业基本信息 ${Uscc}`);
    if ( enterpriseInfo.fuHuaQiUscc != fuHuaQiUscc) throw new BizError(ERRORENUM.无法操作其他孵化器的企业, '修改我的企业基本信息', `孵化器:${fuHuaQiUscc} 企业:${Uscc}`);

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

    await enterpriseInfo.save();

    /**更新分数 */
    await scoreBiz.updateScore(fuHuaQiUscc, configEnum.SCOREWAYS.我的企业数据, false);

    return {isSuccess:true};
}



/**
 * 补录新迁入企业信息
 * 小程序端 2.0
 * @param fuHuaQiUscc 孵化器统一信用代码 
 * @param param 表单
 */
export async function replenishMyEnterpriseInPutInfo(fuHuaQiUscc:string, param) {
    eccFormParam("补录新迁入企业信息", eccFormParamConfig.ReplenishMyEnterpriseInPutDataConfig, param );
    verificationEnumTools.eccEnumValue('补录新迁入企业信息', 'industry', configEnum.INDUSTRY, param.industry);
    if ( !sysTools.eccUscc(param.uscc) ) throw new BizError(ERRORENUM.统一社会信用代码不合法);

    /**不能出现重复的统一社会信用代码 草稿的也不行 */
    let dataBaseInfo = await enterpriseData.findEnterpriseByUscc(param.uscc);
    if ( dataBaseInfo&& dataBaseInfo.uscc)  throw new BizError(ERRORENUM.该企业已存在, `${param.uscc}已经在库中存在`);

    /**添加新注册企业标识 */
    param.isCreate = false;//标识此次操作是否是迁入企业并不是新注册企业
    param.state = configEnum.FUHUASTATE.实体孵化;

    await enterpriseData.replenishEnterpriseData(fuHuaQiUscc, param);

    return {isSuccess:true};
}


/**
 * 补录新注册企业信息
 * 小程序端 2.0
 * @param fuHuaQiUscc 孵化器统一信用代码 
 * @param param 表单
 */
export async function replenishMyEnterpriseCreateInfo(fuHuaQiUscc:string, param) {
    
    eccFormParam("补录新迁入企业信息", eccFormParamConfig.ReplenishMyEnterpriseCreateDataConfig, param );
    verificationEnumTools.eccEnumValue('补录新迁入企业信息', 'industry', configEnum.INDUSTRY, param.industry);
    if ( !sysTools.eccUscc(param.uscc) ) throw new BizError(ERRORENUM.统一社会信用代码不合法);

    /**不能出现重复的统一社会信用代码 草稿的也不行 */
    let dataBaseInfo = await enterpriseData.findEnterpriseByUscc(param.uscc);
    if ( dataBaseInfo&& dataBaseInfo.uscc)  throw new BizError(ERRORENUM.该企业已存在, `${param.uscc}已经在库中存在`);

    /**添加新注册企业标识 */
    param.isCreate = false;//标识此次操作是否是迁入企业并不是新注册企业
    param.state = configEnum.FUHUASTATE.实体孵化;

    await enterpriseData.replenishEnterpriseData(fuHuaQiUscc, param);

    return {isSuccess:true};
}
