/**
 * 管理后台 数字看板  孵化器看板 运营分析 主要逻辑
 * 作者:lxm
 */

import moment = require("moment");
import { FUHUASTATE, INDUSTRY, MOVEOUTTYPE, STATEENUM, TASKTYPEENUM } from "../../../../config/enum";
import { ENTERPRISENODEENUM, FUHUAQINODEENUM, POINTTYPEENUM } from "../../../../config/pointConfig";
import { findEnterpriseCount, findEnterpriseList } from "../../../../data/enterprise/enterprise";
import { findMonthTableList } from "../../../../data/fuHuaQi/monthTask/monthTable";
import { getPointDataByParam } from "../../../point";
import { findBusinessDataByParam } from "../../../../data/fuHuaQi/quarterTask/businessData";
import { changeEnumValue } from "../../../../util/verificationEnum";
import { findTaskListByParam } from "../../../../data/fuHuaQi/monthTask/task";


/**
 * 孵化器运营分析
 * @param uscc 
 */
export async function fuHuaQiOperateStats(uscc:string, year:number) {
    
    let selectParam = {
        state : {"$ne":FUHUASTATE.迁出},
        fuHuaQiUscc: uscc,
        "$or":[{"$and":[{"draftLock":true}, {"taskId":{"$ne":null}}]}, {"$and":[{"draftLock":false}, {"taskId":null}]}]//未提交的企业不能查看
    };
    let enterpriseTotal = await findEnterpriseCount(selectParam); //非迁出企业总数
    let xuniSelectParam = {
        state : FUHUASTATE.虚拟孵化,
        fuHuaQiUscc : uscc,
        "$or":[{"$and":[{"draftLock":true}, {"taskId":{"$ne":null}}]}, {"$and":[{"draftLock":false}, {"taskId":null}]}]//未提交的企业不能查看
    };
    let virtualEnterpriseNum = await findEnterpriseCount(xuniSelectParam); //虚拟孵化

    let monthTableDataList = await findMonthTableList({fuHuaQiUscc:uscc, year});
    monthTableDataList.sort((a, b) => {return a.month - b.month});

    let czlbhqs = {monthList:[], dataList:[]};
    monthTableDataList.forEach(info => {
        let {month, occupancyRate, draftLock} = info;
        czlbhqs.monthList.push(`${month}月`);
        if (!draftLock) occupancyRate = "未填报";
        czlbhqs.dataList.push(occupancyRate);
    });

    let zfqyqs = await getFuHuaQiOwnEnterpriseCountStats(uscc, year);
    // let zfqyqs = await newGetFuHuaQiEnterpriseCountStats(uscc, year); //todo 测试代码

    let byqyslbhqs = await getFuHuaQiOwnEnterpriseGraduateCountStats(uscc, year);
    // let byqyslbhqs = await newGetFuHuaQiEnterpriseGraduateCountStats(uscc, year);//todo 测试代码

    let enterpriseIndustryList = await getEnterpriseIndustry(uscc, year);

    let businessDbList = await findBusinessDataByParam({fuHuaQiUscc:uscc, draftLock:true, year});
    let businessMap = {
        TR:{key:"综合收入", count:0}, 
        ROR:{key:"投资收入", count:0}, 
        RR:{key:"租金收入", count:0}, 
        FS:{key:"财政补贴", count:0}, 
        MIS:{key:"其他", count:0}
    };
    businessDbList.forEach(info => { 
        let {TR, ROR, RR, FS, MIS } = info;
        if ( TR ) businessMap["TR"].count = Math.ceil((TR + businessMap["TR"].count) * 100 )/100;
        if ( ROR ) businessMap["ROR"].count = Math.ceil((ROR + businessMap["ROR"].count) * 100 )/100;
        if ( RR ) businessMap["RR"].count = Math.ceil((RR + businessMap["RR"].count) * 100 )/100;
        if ( FS ) businessMap["FS"].count = Math.ceil((FS + businessMap["FS"].count) * 100 )/100;
        if ( MIS ) businessMap["MIS"].count = Math.ceil((MIS + businessMap["MIS"].count) * 100 )/100;
    });
    let businessList = Object.values(businessMap);

    return {enterpriseTotal, virtualEnterpriseNum, zfqyqs, byqyslbhqs, businessList, czlbhqs, enterpriseIndustryList};
}


/**
 * 在孵企业数量趋势
 * @param uscc 
 */
async function getFuHuaQiOwnEnterpriseCountStats(uscc:string, year:number) {
    let dataStartMs = new Date().valueOf();
    let dataEndMs = new Date().valueOf();
    if (year!= new Date().getFullYear()) {
        dataStartMs = new Date(year+"-01-01 00:00:00").valueOf();
        dataEndMs = new Date((year+1)+"-01-01 00:00:00").valueOf();
    } else {
        dataStartMs = new Date(moment().subtract(12, 'months').format("YYYY-MM")+"-01 00:00:00").valueOf();
    }
    
    let param = {
        uid:uscc,
        ct:{"$gt":dataStartMs, "$lt":dataEndMs},
    }; 

    let pointDataList = await getPointDataByParam(POINTTYPEENUM.孵化器, FUHUAQINODEENUM.企业状态变化, param);

    let distinctMap = {}; //{ month:{ct:xxx, pointInfo:{} } }
    for (let i = 1; i <= 12; i++) {
        let key = i;
        let defCt = new Date(`${year}-${i}-1 00:00:00`).valueOf();
        distinctMap[key]={ct:defCt,pointInfo:{}};
    }
    

    /**获取每个月的最后一次改动 */
    pointDataList.forEach(info => {
        let {p1, ct } = info;
        let pointInfo = JSON.parse(p1);
        let dataMonth = moment(ct).month() + 1;

        if (!distinctMap[dataMonth])  console.log("数据异常 不符合范围之内的值 检查点1003");
        else if(distinctMap[dataMonth].ct < ct) distinctMap[dataMonth] = {ct, pointInfo};
    });
    
    let dataList = [];
    for (let monthStr in distinctMap) {
        let {ct, pointInfo} = distinctMap[monthStr];
        dataList.push({month:monthStr, ct, xn:pointInfo.xn||0, st:pointInfo.st||0 });
    }
    /**按时间从小到大 */
    dataList.sort((a,b) => {return a.ct - b.ct});

    
    let xnData = [];
    let stData = [];
    let monthData = [];
    dataList.forEach(info => {
        let {month, xn, st} = info;
        monthData.push(month);
        xnData.push(xn);
        stData.push(st);
    });
    return {xnData, stData, monthData}
}

async function newGetFuHuaQiEnterpriseCountStats(uscc:string, year:number) {
    let selectParam = {
        state : {"$ne":FUHUASTATE.迁出},
        fuHuaQiUscc: uscc,
        "$or":[{"$and":[{"draftLock":true}, {"taskId":{"$ne":null}}]}, {"$and":[{"draftLock":false}, {"taskId":null}]}]//未提交的企业不能查看
    };
    let enterpriseTotal = await findEnterpriseCount(selectParam); //非迁出企业总数
    let xuniSelectParam = {
        state : FUHUASTATE.虚拟孵化,
        fuHuaQiUscc : uscc,
        "$or":[{"$and":[{"draftLock":true}, {"taskId":{"$ne":null}}]}, {"$and":[{"draftLock":false}, {"taskId":null}]}]//未提交的企业不能查看
    };
    let virtualEnterpriseNum = await findEnterpriseCount(xuniSelectParam); //虚拟孵化
    
    let thisMonth = new Date().getMonth() + 1;
    /**获取迁出企业 */
    let outList = await findEnterpriseList({fuHuaQiUscc:uscc, state:FUHUASTATE.迁出 });
    let inOrOutMap = {};
    outList.forEach(info => {
        let {moveOutTime} = info;
        let month = new Date(moveOutTime).getMonth() + 1;
        if (!inOrOutMap[month]) inOrOutMap[month] = {inNum:0, outNum:0};
        inOrOutMap[month].outNum += 1;
    });

    /**获取入孵任务 */
    let subTasklist = await findTaskListByParam({fuHuaQiUscc:uscc, isSubmit:true, type:TASKTYPEENUM.新注册或迁入企业登记, year});
    subTasklist.forEach(info => {
        let {submitCount, month} = info;
        if (!inOrOutMap[month]) inOrOutMap[month] = {inNum:0, outNum:0};
        inOrOutMap[month].inNum = submitCount || 0;
    });

    let dataList = [];
    let lastNumber = enterpriseTotal;
    for (let i = 12; i >=1; i--) {
        let st = 0;
        let xn = 0;
        if (i>=thisMonth) {
            continue;
            dataList.push({ st, xn, month:i });
            continue;
        }
        let {outNum, inNum} = inOrOutMap[i] ||  {outNum:0, inNum:0};

        lastNumber = lastNumber + outNum - inNum;
        if (lastNumber <= 0) lastNumber = 0;
        dataList.push({
            st:lastNumber,
            month:i,
            xn:i ==thisMonth-1 ? virtualEnterpriseNum : 0
        });
    }

    dataList.sort( (a, b) => {return a.month - b.month})

    let xnData = []; 
    let stData = [];
    let monthData = [];
    dataList.forEach(info => {
        xnData.push(info.xn);
        stData.push(info.st);
        monthData.push(info.month);
    });
    return {xnData, stData, monthData};
}

async function newGetFuHuaQiEnterpriseGraduateCountStats(uscc:string, year:number) {
    let thisMonth = new Date().getMonth() + 1;
    /**获取迁出企业 */
    let outList = await findEnterpriseList({fuHuaQiUscc:uscc, state:FUHUASTATE.迁出 });
    let outMap = {};
    outList.forEach(info => {
        let {moveOutTime, moveOutType} = info;
        let month = new Date(moveOutTime).getMonth() + 1;
        if (!outMap[month]) outMap[month] = 0;
        if (moveOutType == MOVEOUTTYPE.毕业迁出 ) outMap[month] += 1;
    });

    let dataList = [];
    for (let i = 12; i >=1; i--) {
        if (i>=thisMonth) continue;
        dataList.push({
            nby:0,
            by:outMap[i] || 0,
            month:i
        });
    }
    dataList.sort( (a, b) => {return a.month - b.month});

    let monthData = [];
    let graduateData = [];
    let nbyData = [];
    dataList.forEach(info => {
        nbyData.push(info.nby);
        graduateData.push(info.by);
        monthData.push(info.month);
    });
    return {monthData, graduateData, nbyData};
}

/**
 * 毕业企业数量变化趋势 
 * @param uscc 
 * @param year 
 * @returns 
 */
async function getFuHuaQiOwnEnterpriseGraduateCountStats(uscc:string, year:number) {
    let dataStartMs = new Date().valueOf();
    let dataEndMs = new Date().valueOf();
    if (year!= new Date().getFullYear()) {
        dataStartMs = new Date(year+"-01-01 00:00:00").valueOf();
        dataEndMs = new Date((year+1)+"-01-01 00:00:00").valueOf();
    } else {
        dataStartMs = new Date(moment().subtract(12, 'months').format("YYYY-MM")+"-01 00:00:00").valueOf();
    }

    let param = {
        uid:uscc,
        ct:{"$gt":dataStartMs, "$lt":dataEndMs},
    };
    let pointDataList = await getPointDataByParam(POINTTYPEENUM.孵化器, FUHUAQINODEENUM.我的企业_孵化状态, param);

    let monthDataMap = {};
    for (let i = 1; i <= 12; i++) {
        let key = i;
        monthDataMap[key]={ct:0, month:key, count:0, graduation:0};
    }
    
    pointDataList.forEach(info => {
        let { p2, ct } = info;
        let { state, moveOutType, graduation } = JSON.parse(p2);

        let dataMonth = moment(ct).month()+1;
        if (state == FUHUASTATE.迁出 && moveOutType == MOVEOUTTYPE.毕业迁出) {
            if (!monthDataMap[dataMonth]) {
                console.log("数据异常 不符合范围之内的值 检查点1002");
            } else {
                monthDataMap[dataMonth].count += 1;
                monthDataMap[dataMonth].graduation = Math.max(graduation||0, monthDataMap[dataMonth].graduation);
                monthDataMap[dataMonth].ct = ct;
                monthDataMap[dataMonth].month = dataMonth;
            }
            
        }
    });
    let dataList = Object.values(monthDataMap);

    let monthData = [];
    let graduateData = [];
    let nbyData = [];
    dataList.forEach(info => {
        let {month, count, graduation}:any = info;
        monthData.push(month);
        graduateData.push(count);
        nbyData.push(graduation);
    });

    return {monthData, graduateData, nbyData};
}

async function getEnterpriseIndustry(uscc:string, year:number) {
    /**逻辑：以enterprise数据为基础，如有 基本信息_行业领域 埋点，跟进埋点*/
    let enterpriseList = await findEnterpriseList({fuHuaQiUscc:uscc});
    
    let distinctMap = {};
    enterpriseList.forEach(info => {
        let {uscc, industry} = info;
        distinctMap[uscc] = industry;
    });

    let startTime = new Date(year+'-01-01 00:00:00').valueOf();
    let endTime = new Date((year+1)+'-01-01 00:00:00').valueOf();
    let pointDataList = await getPointDataByParam(POINTTYPEENUM.企业, ENTERPRISENODEENUM.基本信息_行业领域, {p3:uscc, ct:{"$gt":startTime, "$lt":endTime} });

    pointDataList.forEach(info => {
        let {uid, p2} = info;
        distinctMap[uid] = JSON.stringify(p2 || "[]");
    });

    let countMap = {};
    for (let key in distinctMap) {
        distinctMap[key].forEach(industryItem => {
            if (!countMap[industryItem]) countMap[industryItem] = 0;
            countMap[industryItem] += 1;
        })
    }

    let dataList = [];

    for (let key in countMap) {
        let name = changeEnumValue(INDUSTRY, parseInt(key));
        dataList.push({name, value:countMap[key]});
    }

    return dataList;
}