/**
 * 企业投资详情表 
 * financing 确定好的数据才会到这里来
 */

import {Schema} from 'mongoose';
import { baseDB } from '../../db/mongo/dbInit';
import { changeEnumValue } from '../../util/verificationEnum';
import { FINANCINGROUNDS } from '../../config/enum';

const financingSchema = new Schema({
    id:{type:String, index:true},//唯一标识
    uscc:{type:String, index:true},//融资企业统一信用代码 冗余字段
    name:String,//企业名称
    financingRounds:Number,//融资轮次
    financingAmount:Number,//融资金额(万元)
    investmentInstitutionsName:String,//投资机构名称
    timeToObtainInvestment:Number,//获得投资时间
    fuHuaQiInvestment:{type:Boolean, default:false},//孵化器是否投资
    fuHuaQiInvestmentAmount:Number,//孵化器投资金额(万元)
    fuHuaQiInvestmentStyle:Number,//孵化器投资方式
    createTime:Number,//录入时间
    type:{type:Number, default:1},//1为 孵化器  2为企业自己添加  3为孵化器添加企业修改
    
});

var financingInfoModel;
export function initModel(){
    financingInfoModel = baseDB.model('financinginfo', financingSchema);
    financingInfoModel.selectOnceData = async function (paramater:object) {
        let selectInfo = await financingInfoModel.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);
    });
}



export async function addFinancingInfo(addInfo) {
    await financingInfoModel.create(addInfo);
}


/**
 * 获取企业融资情况列表
 * @param uscc 
 * @returns 
 */
export async function selectFinancingListByUscc(uscc:string) {
    return await financingInfoModel.find({uscc});
}


/**
 * 根据id查询 融资信息  可用save方法保存
 * @param id 
 * @returns 
 */
export async function getFinancingById(id:string) {
    return await financingInfoModel.selectOnceData({id});
}


/**
 * 根据id删除
 * @param id 
 * @returns 
 */
export async function deleteFinancingById(id:string) {
    return await financingInfoModel.deleteOne({id});
}


/**
 * 分页
 * @param param 
 * @param skipNumber 
 * @returns 
 */
export async function selectFinancingListByParamsToPage(param, skipNumber) {
    return await financingInfoModel.find(param).skip(skipNumber).limit(10);
}


/**
 * 获取符合条件的数量
 * @param param 
 * @returns 
 */
export async function selectFinancingCountByParams(param) {
    return await financingInfoModel.find(param).countDocuments();
}


/**
 * 获取符合条件的列表
 * @param param 
 * @returns 
 */
export async function selectFinancingListByParams(param) {
    return await financingInfoModel.find(param);
}


/**
 * 获取两年内的融资金额
 */
export async function selectEnterpriseTwoYeasFinancing(uscc:string, startTime:number, endTime:number) {
    let param = { uscc, timeToObtainInvestment:{"$gt":startTime, "$lt":endTime } };
    let data = await financingInfoModel.find(param);
    let distinctMap = {};
    data.forEach(info => {
        let { timeToObtainInvestment, investmentInstitutionsName, financingAmount } = info;
        let distinctKey = `${timeToObtainInvestment}_${investmentInstitutionsName}`;
        if (!distinctMap[distinctKey]) distinctMap[distinctKey] = 0;
        distinctMap[distinctKey] += financingAmount;
    });

    let count = 0;
    Object.values(distinctMap).forEach((num:number) => {count += num});

    return count;
}


/**
 * 统计融资各轮次数量
 * @returns 
 */
export async function statsEnterpriseFinancing() {
    let statsList = await financingInfoModel.aggregate([
        {"$group":{_id:"$financingRounds", count:{"$sum":1} }}
    ]);
    return statsList;
}


/**
 * 统计大于某时间节点的按月份分的融资金额
 * @param startTimeMs 
 * @returns {"月份":{ms:融资时间, count:金额, month:"月份"} }
 */
export async function statsEnterpriseFinancingByTime(startTimeMs:number) {
    let param = { timeToObtainInvestment:{"$gt":startTimeMs} };
    let data = await financingInfoModel.find(param);

    let dataMap = {};
    data.forEach(info => {
        let {timeToObtainInvestment, financingAmount} = info; 
        let month = new Date(timeToObtainInvestment).getMonth() + 1;
        if (!dataMap[month]) dataMap[month] = {ms:timeToObtainInvestment, count:0, month};
        dataMap[month].count += financingAmount;
    });

    return Object.values(dataMap);
}


/**
 * 统计融资金额
 * @returns 
 */
export async function statsEnterpriseFinancingAmount() {
    let statsList = await financingInfoModel.aggregate([
        {"$group":{_id:"$financingRounds", count:{"$sum":"$financingAmount"}, dis:{"$sum":0}}},
        {"$group":{_id:"$dis", count:{"$sum":"$count"}}}
    ]);
    return statsList[0] ? statsList[0].count : 0;
}


/**
 * 统计最大融资金额
 * @returns 
 */
export async function statsEnterpriseFinancingMaxAmount() {
    let statsList = await financingInfoModel.aggregate([
        {"$group":{_id:"$uscc", count:{"$sum":"$financingAmount"}, dis:{"$sum":0} }},
        {"$sort":{"count":-1 }},
        {"$group":{_id:"$dis", firstDoc:{"$first":"$$ROOT"} }}
    ]);
    let statsInfo = statsList[0] ? statsList[0].firstDoc : {count:0};
    return statsInfo.count;
}


/**
 * 统计融资轮次
 * @returns 
 */
export async function statsEnterpriseFinancingRounds() {
    let statsList = await financingInfoModel.aggregate([
        {"$group":{_id:"$financingRounds", count:{"$sum":1}}}
    ]);
    let map = {};
    statsList.forEach(info => {
        let {_id, count} = info;
        let str = changeEnumValue(FINANCINGROUNDS, _id);
        map[str] = count;
    });
    return map;
}


/**
 * 统计融资企业
 * @returns
 */
export async function statsFinancingEnterprise() {
    let statsList = await financingInfoModel.aggregate([
        {"$group":{_id:"$uscc", count:{"$sum":"$financingAmount"}} }
    ]);
    let list = []
    statsList.forEach(info => {
        let {_id, count} = info;
        list.push({uscc:_id, count});
    });
    return list;
}

export async function selectEnterpriseFinancingAmount(uscc:string) {
    //financingAmount  timeToObtainInvestment
    let financingList = await financingInfoModel.find({uscc});
    financingList.sort( (a, b) => {return a.timeToObtainInvestment - b.timeToObtainInvestment})
    let state = false;
    for (let i= 0; i < financingList.length; i++) {
        let {financingAmount, timeToObtainInvestment} = financingList[i];
        let count = financingAmount;
        for (let j = (i+1); j < financingList.length; j++) {
            count += financingList[j].financingAmount;
            if ((financingList[j].timeToObtainInvestment - timeToObtainInvestment) > (365 * 24 * 3600 * 1000)) {
                break;
            }
        }
        if (count >= 500) {
            state = true;
            break;
        }
    }
    return state;
}