/**
 * 新的任务系统(自定义任务) 
 * 6.0版本
 */

import moment = require("moment");
import { changeEnumValue, eccEnumValue } from "../../../util/verificationEnum";
import { FUHUAQICUSTOMTASKTYPE, TASKTYPEENUM } from "../../../config/enum";
import * as customTaskData from "../../../data/fuHuaQi/customTask";
import { BizError } from "../../../util/bizError";
import { ERRORENUM } from "../../../config/errorEnum";
import * as taskData from "../../../data/fuHuaQi/monthTask/task";
import * as dangJianTaskData from "../../../data/fuHuaQi/monthTask/dangJian";
import * as monthTableData from "../../../data/fuHuaQi/monthTask/monthTable";
import { findAllNotDisabledFuHuaQi } from "../../../data/fuHuaQi/fuhuaqi";
import { generateMonthTaskId } from "../../../tools/taskTool";


/**
 * 创建自定义任务
 * @param fuHuaQiTaskType 
 * @param dataCycle 数据周期
 * @param startMs 
 * @param endMs 
 */
export async function createTask(fuHuaQiTaskType:number, dataCycle:number, startMs:number, endMs:number) {
    eccEnumValue("创建自定义任务", "", FUHUAQICUSTOMTASKTYPE, fuHuaQiTaskType);
    if (fuHuaQiTaskType == FUHUAQICUSTOMTASKTYPE.月度任务) {
        await createCustomMonthTask(dataCycle, startMs, endMs);
    } else if (fuHuaQiTaskType == FUHUAQICUSTOMTASKTYPE.党建任务) {
        await createCustomYearTask(dataCycle, startMs, endMs);
    }
    
    return {isSuccess:true};
}


/**
 * 创建自定义月度任务
 */
async function createCustomMonthTask(dataCycle:number, startMs:number, endMs:number) {
    //计算周期
    let dataCycleTime = moment(dataCycle);
    let cycleNum = dataCycleTime.format("YYYYMM");//数据周期格式化 数据月
    const DataMonth = dataCycleTime.month() + 1;
    const DataYear = dataCycleTime.year();

    //限制  不能创建未来数据月的任务
    if (parseInt(cycleNum) >= parseInt(moment().startOf('month').format('YYYYMM'))) throw new BizError(ERRORENUM.不可以创建未来数据月的任务);
    if (parseInt(cycleNum) >= parseInt(moment(startMs).format('YYYYMM')) ) throw new BizError(ERRORENUM.填报周期不能小于数据周期);


    let customTaskId = `${FUHUAQICUSTOMTASKTYPE.月度任务}_${cycleNum}`;//id规则是  任务类型_周期月

    let taskInfo = await customTaskData.findCustomTaskByTaskId(customTaskId);
    if (taskInfo && taskInfo.customTaskId) throw new BizError(ERRORENUM.该数据周期已存在此类型任务);

    await customTaskData.addTask(customTaskId, FUHUAQICUSTOMTASKTYPE.月度任务, parseInt(cycleNum), startMs, endMs);
    
    //创建的时候要创建对应的任务
    //确保数据月数据唯一
    //说明  原本任务系统的key为数据填报月与数据月就差一个月
    //后来改了之后 填报月与数据月可能差很多个月 为了保证数据与以前的兼容性 以及key的唯一性
    //这里的key取数据月后一个月
    let taskKey = dataCycleTime.add(1, 'months').format("YYYYM");
    
    let taskCount = await taskData.findTaskCountByParamCount({key:taskKey});
    if (taskCount) {
        new BizError(ERRORENUM.该数据周期已存在此类型任务, `task表重复创建了${taskKey}的任务`);
        return;
    }
    let addList = [];//任务列表
    let monthList = [];//月度填报列表

    const MonthTableName = `${ dataCycleTime.month()+1}月孵化器月度填报`;

    let fuHuaQiList = await findAllNotDisabledFuHuaQi();
    fuHuaQiList.forEach(info => {
        let { uscc } = info;
        let taskId = generateMonthTaskId(uscc);
        addList.push( 
            { key:taskKey, customTaskId:customTaskId, startTime:startMs, endTime:endMs, type:TASKTYPEENUM.孵化器月度填报, month:DataMonth, taskId, fuHuaQiUscc:uscc, isSubmit:false, year:DataYear},
            { key:taskKey, customTaskId:customTaskId, startTime:startMs, endTime:endMs, type:TASKTYPEENUM.新注册或迁入企业登记, month:DataMonth, taskId, fuHuaQiUscc:uscc, isSubmit:false , year:DataYear},
            { key:taskKey, customTaskId:customTaskId, startTime:startMs, endTime:endMs, type:TASKTYPEENUM.融资企业填报, taskId, month:DataMonth, fuHuaQiUscc:uscc, isSubmit:false, year:DataYear});
        /**任务报表的初始状态为 草稿(draftLock=fals) 未被编辑(isUpdate=false)  */
        monthList.push({ taskId, name:MonthTableName, fuHuaQiUscc:uscc, month:DataMonth, year:DataYear, draftLock:false, isUpdate:false });
    });

    try {
        //初始化 任务列表
        await taskData.createTaskToList(addList);
        //初始化月度报表
        await monthTableData.createMonthTableToList(monthList);
    } catch(err) {
        new BizError(ERRORENUM.系统错误, '添加任务和月度报表的时候 出现了异常 请检查数据库  ', err);
    }
}


/**
 * 创建自定义年度任务
 */
async function createCustomYearTask(dataCycle:number, startMs:number, endMs:number) {
    //自定义任务id
    let cycleNum = new Date().getFullYear();
    let customTaskId = `${FUHUAQICUSTOMTASKTYPE.党建任务}_${cycleNum}`;

    let taskInfo = await customTaskData.findCustomTaskByTaskId(customTaskId);
    if (taskInfo && taskInfo.customTaskId) throw new BizError(ERRORENUM.该数据周期已存在此类型任务);

    await customTaskData.addTask(customTaskId, FUHUAQICUSTOMTASKTYPE.党建任务, cycleNum, startMs, endMs);

    //创建的时候要创建对应的任务
    //确保数据月数据唯一
    //说明  原本任务系统的key为数据填报月与数据月就差一个月
    //后来改了之后 填报月与数据月可能差很多个月 为了保证数据与以前的兼容性 以及key的唯一性
    //这里的key取数据月后一个月
    
    let taskCount = await dangJianTaskData.findCountByParam({key:cycleNum});
    if (taskCount) {
        new BizError(ERRORENUM.该数据周期已存在此类型任务, `task表重复创建了${cycleNum}的任务`);
        return;
    }

    let addList = [];//任务列表
    let fuHuaQiList = await findAllNotDisabledFuHuaQi();
    fuHuaQiList.forEach(info => {
        let { uscc } = info;
        let taskId = `${uscc}${cycleNum}`;
        addList.push({
            taskId,
            key:cycleNum,
            draftLock:false,
            fuHuaQiUscc:uscc
        });
    });

    try {
        //初始化 任务列表
        await dangJianTaskData.createTaskToList(addList);
    } catch(err) {
        new BizError(ERRORENUM.系统错误, '添加党建任务的时候 出现了异常 请检查数据库  ', err);
    }

}


/**
 * 任务列表
 * @param fuHuaQiTaskType 
 * @param dataCycle 
 */
export async function taskList(fuHuaQiTaskType:number, dataCycle:number, pageNumber:number) {
    let param:any = {};
    if (fuHuaQiTaskType) param.customTaskType = fuHuaQiTaskType;
    if (dataCycle) param.dataCycle = dataCycle;

    let dbList = await customTaskData.findCustomTaskListByPage(param, (pageNumber-1)*10);
    let dataCount = await customTaskData.findCustomTaskCount(param);
    let nowMs = new Date().valueOf();
    let dataList = [];
    dbList.forEach(info => {
        let {customTaskId, customTaskType, dataCycle, startMs, endMs, isExtension} = info;
        let stateStr = "";
        let state = 0;
        if (nowMs < startMs) {
            stateStr = "即将开始";
            state = 1;
        }
        else if (nowMs > startMs && nowMs < endMs) {
            stateStr = "进行中";
            state = 2;
            if (isExtension) {
                stateStr = "补录中";
                state = 3;
            }
        } else if (endMs< nowMs) {
            stateStr = "已完成";
            state = 4;
        }
        
        let dataCycleStr = "";
        if (customTaskType == FUHUAQICUSTOMTASKTYPE.月度任务) dataCycleStr = moment(`${dataCycle}01`).format("YYYY-MM");
        else if (customTaskType == FUHUAQICUSTOMTASKTYPE.党建任务) dataCycleStr = `${dataCycle}年度`;
        dataList.push({
            id:customTaskId,
            stateStr,
            state,
            rate:100,
            customTaskType:changeEnumValue(FUHUAQICUSTOMTASKTYPE, customTaskType),
            dataCycle:dataCycleStr,
            fillingInCycle:`${moment(startMs).format("YYYY.MM.DD")}-${moment(endMs).format("YYYY.MM.DD")}`
        });
    });
    return {dataCount, dataList};
}


/**
 * 数据下载
 * @param id 
 */
export async function dataDw(id:string) {

}


/**
 * 修改周期
*/
export async function changeCycle(id:string, startMs:number, endMs:number) {
    let taskInfo = await customTaskData.findCustomTaskByTaskId(id);
    if (!taskInfo || !taskInfo.customTaskId) {
        throw new BizError(ERRORENUM.任务不存在);
    }
    if (startMs< taskInfo.startMs) throw new BizError(ERRORENUM.任务延期不可将开始时间提前);
    if (endMs <= startMs) throw new BizError(ERRORENUM.任务延期结束时间要大于开始时间);

    taskInfo.startMs = startMs;
    taskInfo.endMs = endMs;
    taskInfo.isExtension = true;
    
    await taskInfo.save();

    //修改对应任务的开始结束时间
    await taskData.upodateTaskStartAdnEndTime({customTaskId:id}, {startTime:startMs, endTime:endMs});

    return {isSuccess:true};
}


/**
 * 提前回收
 * @param id 
 */
export async function recovery(id:string) {
    let taskInfo = await customTaskData.findCustomTaskByTaskId(id);
    if (!taskInfo || !taskInfo.customTaskId) {
        throw new BizError(ERRORENUM.任务不存在);
    }
    let nowMs = new Date().valueOf();

    if (taskInfo.endMs < nowMs) throw new BizError(ERRORENUM.不可提前回收已完成任务);

    taskInfo.endMs = nowMs;
    await taskInfo.save();

    //修改对应任务的开始结束时间
    await taskData.upodateTaskStartAdnEndTime({customTaskId:id}, { endTime:nowMs});


    return {isSuccess:true};
}