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

import {Schema} from 'mongoose';
import { baseDB } from '../../db/mongo/dbInit';
import { CYCXFX, FUHUASTATE, INDUSTRY } from '../../config/enum';
import { changeEnumValue } from '../../util/verificationEnum';

/**
 * 创始团队
 */
const initialTeamSchema = new Schema({
    type:Number,//创始团队人才类型
    memberName:String,//成员姓名
    memberSex:Number,//成员性别
    memberAge:Number,//成员年龄  出生年月时间戳
    memberDEGREE:Number,//成员最高学历
    memberSchool:String,//毕业学校
    des:String,//履历描述
},{_id:false});

/**企业资质 */
const qualificationSchema = new Schema({
    isHighTech:Boolean,
    highTechMs:Number,//高新技术
    isZjtx:Boolean,
    zjtxMs:Number,//专精特新
    isXjrpy:Boolean,
    xjrpyMs:Number,//小巨人培育
    isXjr:Boolean,
    xjrMs:Number,//小巨人
    beOnTheMarket:[Number],//上市情况
    isBeOnTheMarket:{type:Boolean, default:false}//是否上市
}, {_id:false});


const intellectualPropertySchema = new Schema({
    alienPatent:Number,//海外专利
    classIPatent:Number,//一类专利
    secondClassPatent:Number,//二类专利
}, {_id:false});

/**标签 */
const enterpriseLabelSchema = new Schema({
    labelId:String,
    state:{type:Boolean, default:true},//状态 false表示标签失效
},{_id:false});

const leaseScheme = new Schema({
    contractStartTime:Number,//合同开始时间
    contractEndTime:Number,//合同结束时间
    rentStartTime:Number,//租金开始时间
    rentEndTime:Number,//租金结束时间
})

//科创分
const kcfScheme = new Schema({
    industry:String,//
    subIndustry:String,//
    industryRanking:String,//
    score:String,//
}) 

/**股权结构 */
const guQuanJieGouItemScheme = new Schema({
    name:String,//名称
    finalBenefitPercent:String,//最终受益股份
    stockPercent:String,//持股比例
    stockType:String,//投资人类型
    realCapi:String,//实缴出资额
    paidUpCapitalUnit:String,//实缴出资额单位
    subscribedCapital:String,//认缴出资额数额
    subscribedCapitalUnit:String//认缴出资额单位
})

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},//孵化器统一信用代码[-p]
    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了
    /** 用户相关 */
    pwd:String,//登录密码
    token:{type:String, index:true},
    tokenMs:Number,
    firstLoginIsChangePwd:{type:Boolean, default:false},//首次登录是否修改密码
    /**孵化状态相关 */
    state:{type:Number, default: FUHUASTATE.实体孵化, index:true },//孵化状态 遵循枚举 FUHUASTATE 值 默认实体孵化   ----2.0
    virtualCause:Number,//虚拟孵化原因 遵循 VIRTUALCAUSE 的值   ----2.0
    virtualCauseDes:String,//虚拟孵化描述    ----2.0
    moveOutType:Number,// 迁出类型  遵循 MOVEOUTTYPE 的值   ----2.0
    moveOutTrace:Number,//迁出去向  遵循 MOVEOUTTRACE 的值   ----2.3
    moveOutCause:[Number],//迁出原因 遵循 MOVEOUTCAUSE  的值   ----2.0
    moveOutTime:Number,//迁出时间
    /**2.0  后改的地址 */
    logonAddress:{type:[String], default:[]},//注册地址
    operatingAddress:{type:[String], default:[]},//经营地址
    oldLogonAddress:{type:[String], default:[]},//迁入前注册地址
    /**3.0新加字段 */
    initialTeam:{type:[initialTeamSchema], default:[]},//创始团队  弃用
    qualification:{type:qualificationSchema},//企业资质
    intellectualProperty:{type:intellectualPropertySchema},//知识产权
    firstClassTalent:{type:Boolean, default:false},//是否拥有国际一流人才 默认没有  舍弃
    haveFirstClassTalent:{type:Number, default:1},//是否拥有国际一流人才
    tipsQualification:{type:Boolean, default:false},//标识-企业资质
    tipsIntellectualProperty:{type:Boolean, default:false},//标识-知识产权
    tipsFinancingInfo:{type:Boolean, default:false},//标识-企业融资
    /**3.3增加 */
    graduation:{type:Boolean, default:false},//拟毕业情况
    /**4.2增加*/
    cycxfx:{type:[Number], default:[]},//创业创新方向
    cycsrbj:{type:[Number], default:[]},//创业创始人背景
    securePhon:String,//安全手机号，用于做修改密码用
    /**标签系统 */
    labels:{type:[enterpriseLabelSchema], default:[]},
    /**导入的补充数据 */
    RAS:{type:Number},//登记状态
    logOffMS:{type:Number},//注销时间
    legalPerson:String,//法人
    zhuceziben:{type:String, default:'-'},//注册资本
    shijiaoziben:{type:String, default:'-'},//实缴资本
    dianHua:String,//电话
    gengDuoDianHua:{type:String},//更多电话
    mail:{type:String, default:'-'},//邮箱
    moreMail:{type:String, default:'-'},//更多邮箱
    enterpriseType:{type:String, index:true},//企业（机构）类型
    zhuCeHao:String,//注册号
    zuZhiJiGouDaiMa:String,//组织机构代码
    canBaoRenShu:Number,//参保人数
    canBaoRenShuNianBao:Number,//参保人数所属年报
    yingYeQiXian:String,//营业期限
    qiYeGuiMo:{type:Number, index:true},//企业规模
    guanWang:String,//官网
    tongXinDiZhi:String,//通信地址
    jianJie:String,//企业简介
    dengJiJiGuan:String,//登记机关
    naShuiRenZiZhi:Number,//纳税人资质
    zuiXinNianBaoNianFen:Number,//最新年报年份
    jingYingFanWei:String,//经营范围
    //经纬度
    lng:String,//经度
    lat:String,//纬度
    //迁入前经纬度
    oldLng:String,//经度
    oldLat:String,//纬度
    follow:Boolean,//是否关注
    leaseInfo:{type:leaseScheme, default:{}},//租赁信息
    jiaSu:{type:Boolean, default:false},//是否是加速企业
    jiaSuZiZhi:{type:[Number], default:[]},//加速资质
    jiaSuZiZhiDesc:String,//选其他时
    leaseAddress:String,//租赁地址

    guQuanJieGou:{type:[guQuanJieGouItemScheme], default:[]},//股权结构
    kcf:{type:kcfScheme, default:{}},//科创分

    keynote:{type:[Number], default:[]},//ZHONGDIANQIYE

    // gbej:{type:String, default:""},//国标二级行业  
});

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 uscc 
 * @param pwd 
 * @returns 
 */
export async function updateEnterprisePwd(uscc:string, pwd:string) {
    return await enterpriseModel.updateMany({uscc}, {$set:{pwd}});
}


/**
 * 创建新的企业数据
 * @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 }}).countDocuments();
}

/**
 * 查找孵化器累计企业数量
 * @param fuHuaQiUscc 孵化器统一信用代码
 * @returns number  孵化器拥有的企业数量
 */
export async function findEnterpriseTotalByFuHuaQiUscc(fuHuaQiUscc:string) {
    return await enterpriseModel.find({fuHuaQiUscc}).countDocuments();
}


/**
 * 聚合查询 孵化器所拥有的企业数量
 * @returns {} key=孵化器统一信用 value=企业数量
 */
export async function groupFindEnterpriseCountByParam(param) {
    let dataList = await enterpriseModel.aggregate([{$match:param},{$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);
}


/**
 * 分页获取所有企业分页数量未5
 * @param selectParam 
 * @param skipCount 
 * @returns 
 */
export async function findEnterpriseListToPage5(selectParam, skipCount) {
    return await enterpriseModel.find(selectParam).skip(skipCount).limit(5);
}


/**
 * 获取符合条件的所有企业
 * @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).countDocuments();
}


/**
 * 通过企业名称获取企业信息
 * @param selectParam 查询参数
 * @returns number 数据数量
 */
export async function findEnterpriseInfoByName(name:string) {
    let selectParam = {
        state : {"$ne":FUHUASTATE.迁出},
        name,
        "$or":[{"$and":[{"draftLock":true}, {"taskId":{"$ne":null}}]}, {"$and":[{"draftLock":false}, {"taskId":null}]}]
    };
    return await enterpriseModel.findOne(selectParam);
}


/**
 * 获取孵化器下的所有已经提交的企业信息
 * 限制返回     name
                logonAdd
                operatingAdd
 * @param fuHuaQiUscc 孵化器统一信用代码
 * @returns []
 */
export async function findSubmittedEnterpriseListByFuHuaQiUscc(fuHuaQiUscc:string) {
    let selectParam = {
        state : {"$ne":FUHUASTATE.迁出},
        fuHuaQiUscc,
        "$or":[{"$and":[{"draftLock":true}, {"taskId":{"$ne":null}}]}, {"$and":[{"draftLock":false}, {"taskId":null}]}]
    };
    return await enterpriseModel.find(selectParam, 'name logonAddress operatingAddress state uscc');
}


export async function findSubmittedEnterpriseAllList() {
    let selectParam = {
        state : {"$ne":FUHUASTATE.迁出},
        "$or":[{"$and":[{"draftLock":true}, {"taskId":{"$ne":null}}]}, {"$and":[{"draftLock":false}, {"taskId":null}]}]
    };
    return await enterpriseModel.find(selectParam, 'name logonAddress operatingAddress state uscc');
}


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


/**
 * 批量创建企业
 * @param fuHuaQiList 
 */
export async function createEnterpriseToList(fuHuaQiList:object) {
    await enterpriseModel.insertMany(fuHuaQiList);
}


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


/**
 * 补录企业
 * @param fuHuaQiUscc 
 * @param param 
 */
export async function replenishEnterpriseData(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});
}


/**
 * 统计非迁出企业的专利信息数据
 * @returns 
 */
export async function statsIntellectualPropertyData() {
    let statsList = await enterpriseModel.aggregate([
        {"$match":{state:{"$ne":FUHUASTATE.迁出}}},
        {"$group":{_id:"stats", 
            alienPatent:{"$sum":"$intellectualProperty.alienPatent"},//海外专利
            classIPatent:{"$sum":"$intellectualProperty.classIPatent"},//一类专利
            secondClassPatent:{"$sum":"$intellectualProperty.secondClassPatent"},//二类专利
        }}
    ]);

    return statsList[0] ? statsList[0] : {alienPatent:0, classIPatent:0, secondClassPatent:0};
} 


/**
 * 统计非迁出企业的 按孵化器分组的数量  即孵化器拥有的企业数
 * @returns 
 */
export async function statsFHQHaveEnterpriseCount() {
    let statsList = await enterpriseModel.aggregate([
        {"$match":{state:{"$ne":FUHUASTATE.迁出}}},
        {"$group":{
            _id:"$fuHuaQiUscc", 
            count:{"$sum":1}
        }}
    ]);
    let map = {};
    statsList.forEach(info => {
        map[info._id] = info.count;
    });
    return map;
}


/**
 * 统计非迁出企业的 行业领域
 */
export async function statsEnterpriseIndustry() {
    let statsList = await enterpriseModel.aggregate([
        {"$match":{
            state:{"$ne":FUHUASTATE.迁出},
            "$or":[{"$and":[{"draftLock":true}, {"taskId":{"$ne":null}}]}, {"$and":[{"draftLock":false}, {"taskId":null}]}]
        }},
        {"$group":{
            _id:"$industry", 
            count:{"$sum":1}
        }}
    ]);
    
    let distinctMap = {};
    statsList.forEach(info => {
        info._id.forEach(item => {
            let itemStr = changeEnumValue(INDUSTRY, item);
            if (!distinctMap[itemStr]) distinctMap[itemStr] = 0;
            distinctMap[itemStr] += 1;
        })
    });
    return distinctMap;
}


/**
 * 统计非迁出企业的 创新创业
 */
export async function statsEnterpriseCycxfx() {
    let statsList = await enterpriseModel.aggregate([
        {"$match":{
            state:{"$ne":FUHUASTATE.迁出},
            "$or":[{"$and":[{"draftLock":true}, {"taskId":{"$ne":null}}]}, {"$and":[{"draftLock":false}, {"taskId":null}]}]
        }},
        {"$group":{
            _id:"$cycxfx", 
            count:{"$sum":1}
        }}
    ]);
    
    let distinctMap = {};
    statsList.forEach(info => {
        let {_id} = info;
        if (!_id) return;
        _id.forEach(item => {
            let itemStr = changeEnumValue(CYCXFX, item);
            if (!distinctMap[itemStr]) distinctMap[itemStr] = 0;
            distinctMap[itemStr] += 1;
        })
    });
    return distinctMap;
}


export async function statsEnterpriseQualification() {
    let resultMap = {isHighTech:0, isZjtx:0, isXjrpy:0, isXjr:0 };
    let keyList = ["isHighTech", "isZjtx", "isXjrpy", "isXjr"];
    for (let i = 0; i < keyList.length; i++) {
        let key = keyList[i];
        let subList = await enterpriseModel.aggregate([
            {"$match":{
                state:{"$ne":4},
                "$or":[{"$and":[{"draftLock":true}, {"taskId":{"$ne":null}}]}, {"$and":[{"draftLock":false}, {"taskId":null}]}]
            }},
            {
                "$group":{ _id:`$qualification.${key}`, count:{"$sum":1} }
            },
            {"$match":{
                "_id":true
            }}
        ]);
        resultMap[key] = subList[0] ? subList[0].count : 0;
    }
    return resultMap;
}


export async function statsEnterpriseIntellectualPropertyInfo() {
    let subList = await enterpriseModel.aggregate([
        {"$match":{
            state:{"$ne":4},
            "$or":[{"$and":[{"draftLock":true}, {"taskId":{"$ne":null}}]}, {"$and":[{"draftLock":false}, {"taskId":null}]}]
        }},
        {
            "$group":{
                _id:"$null",
                alienPatent:{"$sum":"$intellectualProperty.alienPatent"},
                classIPatent:{"$sum":"$intellectualProperty.classIPatent"},
                secondClassPatent:{"$sum":"$intellectualProperty.secondClassPatent"}
            }
        }
    ]);
    let reuslt = subList[0];
    if (!reuslt) return {"海外专利":0, "一类专利":0, "二类专利":0};
    return {
        "海外专利":reuslt.alienPatent,
        "一类专利":reuslt.classIPatent,
        "二类专利":reuslt.secondClassPatent
    };
}


export async function newEnterpriseIndustry(year:number, month:number) {
    let subList = await enterpriseModel.aggregate([
        {
            "$match":{
                taskId:{"$regex":`${year}${month}$`}, draftLock:true
            }
        },
        {
            "$project":{
                _id:"$uscc",
                firstIndustry:{"$arrayElemAt":["$industry", 0]}
            }
        },
        {
            "$group":{
                _id:"$firstIndustry",
                count:{"$sum":1}
            }
        }
    ]);

    return subList;
}


export async function findUsccList() {
    return await enterpriseModel.find({}, {uscc:1});
}


export async function fuHuaQiEnterpairseCount(taskKey:string) {
    let subList = await enterpriseModel.aggregate([
        {
            "$match":{
                taskId:{"$regex":`${taskKey}$`}, draftLock:true
            }
        },
        {
            "$group":{
                _id:"$fuHuaQiUscc",
                "isCreateSum": {  
                    "$sum":{"$cond": [  { "$eq":["$isCreate", true] },1, 0 ]}
                },
                 "isNotCreateSum": {
                    "$sum":{"$cond": [  { "$eq":["$isCreate", false ]},1, 0 ]}
                }  
            }
        }
    ]);

    return subList;
}


export async function statsEnterpriseLabels() {
    let subList = await enterpriseModel.aggregate([  
        {    
            $unwind: "$labels"    
         },    
         {    
             $group: {  
                 _id: "$labels.labelId",  
                 "count": {  
                     "$sum": {  
                         "$cond": [  
                             { "$eq": ["$labels.state", true] },  // 假设 specificValue 是您想要检查的值  
                             1,  
                             0  
                         ]  
                     }  
                 }  
             }  
         }  
    ]);
    return subList;
}


export async function statsFuHuaQiEnterpriseArea(fuHuaQiUscc:string) {
    let result = await enterpriseModel.aggregate([  
        {
            "$match":{
                fuHuaQiUscc,
                state:{"$ne":4} 
            }
        },   
        {    
            $group: {  
                _id:"$fuHuaQiUscc",
                "count": {  
                    "$sum":1
                },
                "areaCount": {  
                    "$sum":"$leasedArea"
                },
            }  
        }  
    ]);
    return result[0];
}


export async function repeatEnterprise() {
    let result = await enterpriseModel.aggregate([  
        {  
            $group: {  
                _id: "$uscc", // 按照email字段进行分组  
                count: { $sum: 1 }, // 计算每个email出现的次数  
            }  
        },  
        {  
            $match: {  
                count: { $gt: 1 } // 筛选出那些email出现次数大于1的分组  
            }  
        },  
        {  
            $project: {  
                _id: 0, // 不需要_id字段  
                uscc: "$_id", // 将_id字段重命名为email  
                count: 1, // 显示count字段  
            }  
        }  
    ]);
    let usccList = [];
    result.forEach(info => {
        usccList.push(info.uscc);
    });

    return usccList;
}