/**
 * 企业信息表
 * draftLock 草稿锁 当任务提交的时候，将此字段改为true
 */

import {Schema} from 'mongoose';
import { baseDB } from '../../db/mongo/dbInit';
import { FUHUASTATE } from '../../config/enum';

const enterpriseSchema = new Schema({
    name: {type:String, index: true},//企业名称
    taskId:{type:String, index:true},//绑定的任务id
    uscc:{type:String, index: true},//统一信用代码
    fuHuaQiUscc:{type:String, index:true},//孵化器统一信用代码
    industry:[Number],//领域
    logonTime:Number,//注册时间
    firstIncubationTime:Number,//首次入孵时间
    timeOfImmigration:Number,//迁入时间
    isNaturalPersonHolding:{type:Boolean, default:true},//是否自然人控股企业
    oldLogonAdd:String,//迁入前注册地址
    logonAdd:String,//注册地址
    operatingAdd:String,//经营地址
    isCreate:{type:Boolean, default:false},//是否新建
    // isPhysicalPresence:{type:Boolean, default:true},//是否实地孵化 暂时弃用
    leasedArea:Number,//租赁面积（平方米）
    mainBusiness:{type:String, default:""},//主营业务
    createTime:Number,//录入时间
    draftLock:{type:Boolean, default:false},//草稿锁，true为提交之后，false为草稿
    enterpriseIsInPut:{type:Boolean, default:false},//是否是初始数据  todo 后续要弃用 兼容原始数据无法判断是否是迁入企业这个问题加的字段
    draftId:{type:String, index:true},//草稿id 编辑的时候使用这个id 保存之后就不认这个id了
    /**孵化状态相关 */
    state:{type:Number, default: FUHUASTATE.实体孵化 },//孵化状态 遵循枚举 FUHUASTATE 值 默认实体孵化   ----2.0
    virtualCause:Number,//虚拟孵化原因 遵循 VIRTUALCAUSE 的值   ----2.0
    virtualCauseDes:String,//虚拟孵化描述    ----2.0
    moveOutType:Number,// 迁出类型  遵循 MOVEOUTTYPE 的值   ----2.0
    moveOutCause:[Number],//迁出原因 遵循 MOVEOUTCAUSE  的值   ----2.0
    moveOutTime:Number,//迁出时间
});

var enterpriseModel;
export function initModel(){
    enterpriseModel = baseDB.model('enterprise', enterpriseSchema);
    enterpriseModel.selectOnceData = async function (paramater:object) {
        let selectInfo = await enterpriseModel.findOne(paramater).exec();
        if (selectInfo) {
            if (!selectInfo.runSave) {
                selectInfo.runSave = selectInfo.save;
                selectInfo.save = save.bind(selectInfo)
            }
        }
        return selectInfo;
    }
}
export async function save(throwError=false) {
    if (!this.isModified()) return;
    await this.runSave({validateBeforeSave:false}).catch(err=>{
        console.log(err);
    });
}


/**
 * 通过企业统一信用代码获取企业信息
 * 支持.save方法保存对象修改
 * @param uscc 企业统一信用代码
 * @returns {}
 */
export async function findEnterpriseByUscc(uscc:string) {
    return await enterpriseModel.selectOnceData({uscc});
}


/**
 * 通过草稿箱id获取企业信息
 * 支持.save方法保存对象修改
 * @param uscc 企业统一信用代码
 * @returns {}
 */
export async function findEnterpriseByDraftId(draftId:string) {
    return await enterpriseModel.selectOnceData({draftId});
}


/**
 * 根据参数查询单个企业信息
 * @param param 
 * @returns 
 */
export async function selectOneEnterpriseByParam(param:object) {
    return await enterpriseModel.findOne(param);
}



/**
 * 通过taskId 获取此次任务添加的企业列表
 * @param taskId 任务id 格式遵循tool中getTaskId
 * 限制返回 draftId name isCreate uscc 字段
 * @returns [{draftId}] 
 */
export async function findEnterpriseListByTaskId(taskId:string, draftLock:boolean) {
    return await enterpriseModel.find({taskId, draftLock, enterpriseIsInPut:false}, 'draftId name isCreate uscc');
}


/**
 * 将taskId的所有数据的draftLock字段为true
 * @param taskId 任务id 格式遵循tool中getTaskId
 */
export async function updateEnterpriseDraftLock(taskId:string) {
    return await enterpriseModel.updateMany({taskId}, {$set:{draftLock:true}});
}


/**
 * 创建新的企业数据
 * @param fuHuaQiUscc 企业所属孵化器的统一信用代码
 * @param taskId 任务id 格式遵循tool中getTaskId
 * @param param 添加的字段对象
 */
export async function createEnterprise(fuHuaQiUscc:string, taskId:string, param) {
    let addInfo = Object.assign({fuHuaQiUscc, taskId, createTime:new Date().valueOf()}, param);
    await enterpriseModel.create(addInfo);
}


/**
 * 查找孵化器所拥有的企业数量
 * @param fuHuaQiUscc 孵化器统一信用代码
 * @returns number  孵化器拥有的企业数量
 */
export async function findEnterpriseCountByFuHuaQiUscc(fuHuaQiUscc:string) {
    return await enterpriseModel.find({fuHuaQiUscc, state:{"$ne":4 }}).count();
}


/**
 * 聚合查询 孵化器所拥有的企业数量
 * @returns {} key=孵化器统一信用 value=企业数量
 */
export async function groupFindEnterpriseCount() {
    let match = {draftLock:true};//前置条件
    let dataList = await enterpriseModel.aggregate([{$match:match},{$group:{_id:"$fuHuaQiUscc",count:{$sum:1}}}]).exec();
    let result = {};
    dataList.forEach(info => {
        let {_id, count} = info;
        result[_id] = count;
    });
    return result;
}


/**
 * 删除创建企业的草稿报表
 * @param uscc 企业统一信用代码
 */
export async function deleteEnterprise(draftId:string) {
    return await enterpriseModel.deleteOne({draftId}).exec();
}


/**
 * 分页获取所有企业
 * @param selectParam 查询参数
 * @param skipCount 跳过数量
 * @returns [] 孵化器列表
 */
 export async function findEnterpriseListToPage(selectParam, skipCount) {
    return await enterpriseModel.find(selectParam).skip(skipCount).limit(10);
}


/**
 * 获取符合条件的所有企业
 * @param selectParam 查询参数
 * @returns [] 孵化器列表
 */
export async function findEnterpriseList(selectParam) {
    return await enterpriseModel.find(selectParam);
}


/**
 * 获取符合条件的企业数量
 * @param selectParam 查询参数
 * @returns number 数据数量
 */
 export async function findEnterpriseCount(selectParam) {
    return await enterpriseModel.find(selectParam).count();
}


/**
 * 通过企业名称获取企业信息
 * @param selectParam 查询参数
 * @returns number 数据数量
 */
export async function findEnterpriseInfoByName(name:string) {
    return await enterpriseModel.findOne({name, draftLock:true});
}


/**
 * 获取孵化器下的所有已经提交的企业信息
 * 限制返回     name
                logonAdd
                operatingAdd
 * @param fuHuaQiUscc 孵化器统一信用代码
 * @returns []
 */
export async function findSubmittedEnterpriseListByFuHuaQiUscc(fuHuaQiUscc:string) {
    return await enterpriseModel.find({fuHuaQiUscc, draftLock:true }, 'name logonAdd operatingAdd state');
}


/**
 * 查询所有已绑定过的孵化器id
 * @returns [孵化器id]
 */
export async function findAllBindFuHuaQiUsccList() {
    return await enterpriseModel.distinct('fuHuaQiUscc');
}

export async function createEnterpriseToList(fuHuaQiList:object) {
    await enterpriseModel.insertMany(fuHuaQiList);
}


/**
 * 将所有企业数据的孵化状态改变
 * @param state 孵化状态
 */
export async function updateEnterpriseState(state:number) {
    return await enterpriseModel.updateMany({}, {$set:{state}});
}


export async function replenishData(fuHuaQiUscc:string, param) {
    let addInfo = Object.assign({fuHuaQiUscc, createTime:new Date().valueOf()}, param);
    await enterpriseModel.create(addInfo);
}


export async function findStats() {
    return await enterpriseModel.find({enterpriseIsInPut:false});
}
