import { RoleModel, RoleType } from '../../db/Role';
import { pinus, FrontendOrBackendSession } from 'pinus';
import { resResult, shouldRefresh } from '../../pubUtils/util';
import { STATUS, TASK_TYPE, TASK_FUN_TYPE, SHOP_REFRESH_TYPE, WAR_TYPE, PUSH_ROUTE, POP_UP_SHOP_CONDITION_TYPE } from '../../consts';
import { TaskParamInter, TaskListReturn } from '../../domain/roleField/task';
import { Connect, EPlace, HeroType } from '../../db/Hero';
import { HeroScores } from '../../db/PvpHistoryOpp';
import { ItemInter, RewardInter } from '../../pubUtils/interface';
import { UserTaskModel, UserTaskType } from '../../db/UserTask';
import { UserTaskRecModel } from '../../db/UserTaskRec';
import { UserTaskHistoryModel } from '../../db/UserTaskHistory';
import { gameData } from '../../pubUtils/data';
import { getSeconds, getZeroPointD } from '../../pubUtils/timeUtil';
import { RoleStatus } from '../../db/ComBattleTeam';
import { getActivities } from '../activity/activityService';
import { CheckTask } from './taskObj';
import { getEquipById } from '../equipService';
import { JewelType } from '../../db/Jewel';
import { checkPopUpCondition, checkPopUpConditionInCreateHero, checkPopUpConditionInEntry } from '../activity/popUpShopService';
import { sendMessageToUserWithSuc } from '../pushService';
import { getGoldId } from '../role/rewardService';
import { GachaResultIndb } from '../../domain/activityField/gachaField';

export async function checkTaskWithRoles(roleId: string, sid: string, taskType: TASK_TYPE, roles: RoleType[]) {
    for (let role of roles) {
        if (role) {
            await checkTaskWithRole(role.serverId, role.roleId, role.roleId == roleId ? sid : null, taskType, role);
        }
    }
}

export async function checkTaskWithRole(serverId: number, roleId: string, sid: string, taskType: TASK_TYPE, role: RoleType, args?: TaskParamInter) {
    let task = new CheckTask(serverId, roleId);
    task.setRole(role);
    task.setParam(taskType, args);
    await task.saveAndPush(sid);
}

export async function checkTask(serverId: number, roleId: string, sid: string, taskType: TASK_TYPE, args?: TaskParamInter) {
    let task = new CheckTask(serverId, roleId);
    task.setParam(taskType, args);
    await task.saveAndPush(sid);
}

export async function checkGVGTask(serverId: number, roleId: string, sid: string, configId: number, leagueCode: string, taskType: TASK_TYPE, args?: TaskParamInter) {
    let task = new CheckTask(serverId, roleId);
    task.setParam(taskType, args);
    task.setLeague(configId, leagueCode);
    await task.saveAndPush(sid);
}

export async function checkTaskInEntry(serverId: number, roleId: string, sid: string, role: RoleType) {
    let task = new CheckTask(serverId, roleId);
    task.setRole(role);
    task.setParam(TASK_TYPE.LOGIN_SUM, {});
    task.setParam(TASK_TYPE.LOGIN_SERIES, {});
    await task.saveAndPush(sid);
    checkPopUpConditionInEntry(serverId, roleId, sid);
}

export async function checkTaskInCreateHero(serverId: number, roleId: string, sid: string, heroNum: number, heroes: HeroType[]) {
    let task = new CheckTask(serverId, roleId);
    task.setParam(TASK_TYPE.HERO_NUM, { heroNum });
    task.setParam(TASK_TYPE.HERO_QUALITY, { heroes });
    task.setParam(TASK_TYPE.HERO_QUALITY_STAR_UP, { heroes });
    task.setParam(TASK_TYPE.HERO_LV, { heroes });
    await task.saveAndPush(sid);
}

export async function checkTaskInHeroStarUp(serverId: number, roleId: string, sid: string, hero: HeroType, oldStar: number) {
    let task = new CheckTask(serverId, roleId);
    task.setParam(TASK_TYPE.HERO_STAR_UP, { hero });
    task.setParam(TASK_TYPE.HERO_QUALITY_STAR_UP, { hero, oldStar, oldColorStar: 0 });
    task.setParam(TASK_TYPE.STAR_UP_SUM, { count: hero.star - oldStar });
    await task.saveAndPush(sid);
}

export async function checkTaskInHeroWakeUp(serverId: number, roleId: string, sid: string, hero: HeroType, oldColorStar: number) {
    let task = new CheckTask(serverId, roleId);
    task.setParam(TASK_TYPE.HERO_STAR_UP, { hero });
    task.setParam(TASK_TYPE.HERO_WAKE_UP, { hero, oldColorStar });
    task.setParam(TASK_TYPE.HERO_QUALITY_WAKE_UP_COUNT, { hero, oldColorStar });
    task.setParam(TASK_TYPE.HERO_WAKE_UP_COUNT, { hero, oldColorStar });
    task.setParam(TASK_TYPE.HERO_WAKE_UP_STAR_UP_COUNT, { hero, oldColorStar });
    task.setParam(TASK_TYPE.HERO_QUALITY_STAR_UP, { hero, oldStar: 6, oldColorStar });
    task.setParam(TASK_TYPE.STAR_UP_SUM, { count: hero.colorStar - oldColorStar });
    await task.saveAndPush(sid);
}

export async function checkTaskInHeroQUalityUp(serverId: number, roleId: string, sid: string, hero: HeroType) {
    let task = new CheckTask(serverId, roleId);
    task.setParam(TASK_TYPE.HERO_QUALITY_UP, { hero });
    task.setParam(TASK_TYPE.HERO_QUALITY_TO_QUALITY_COUNT, { hero });
    await task.saveAndPush(sid);
}

export async function checkTaskInHeroTrain(serverId: number, roleId: string, sid: string, hero: HeroType, trainCount: number) {
    let task = new CheckTask(serverId, roleId);
    task.setParam(TASK_TYPE.HERO_TRAIN, { hero, trainCount });
    task.setParam(TASK_TYPE.HERO_TRAIN_SUM, { hero, trainCount });
    await task.saveAndPush(sid);
}

export async function checkTaskInActiveScroll(serverId: number, roleId: string, sid: string, scrollActive: boolean, hero: HeroType) {
    if (!scrollActive) {
        let task = new CheckTask(serverId, roleId);
        task.setParam(TASK_TYPE.HERO_UNLOCK, { hero });
        task.setParam(TASK_TYPE.ROLE_SCROLL_ACTIVE, { scrollActive });
        await task.saveAndPush(sid);
    }
}

export async function checkTaskInGuildTrain(serverId: number, roleId: string, sid: string, warId: number, isSuccess: boolean, isComplete: boolean) {
    let task = new CheckTask(serverId, roleId);
    task.setParam(TASK_TYPE.GUILD_TRAIN_SUCESS, { isSuccess });
    task.setParam(TASK_TYPE.GUILD_TRAIN, {});
    task.setParam(TASK_TYPE.GUILD_TRAIN_COUNT, { isComplete, warId });
    await task.saveAndPush(sid);
}

export async function checkTaskInBattleStart(serverId: number, roleId: string, sid: string, warId: number) {
    let task = new CheckTask(serverId, roleId);
    task.setParam(TASK_TYPE.BATTLE_MAIN_START, { warId, count: 1 });
    task.setParam(TASK_TYPE.BATTLE_TOWER_START, { warId, count: 1 });
    task.setParam(TASK_TYPE.BATTLE_VESTIGE_START, { warId, count: 1 });
    task.setParam(TASK_TYPE.BATTLE_DAILY_START, { warId, count: 1 });
    task.setParam(TASK_TYPE.BATTLE_EXPEDITION_START, { warId, count: 1 });
    task.setParam(TASK_TYPE.BATTLE_DUNGEON_START, { warId, count: 1 });
    await task.saveAndPush(sid);
}

/**
 * battle.normalBattleHandler.battleEnd 中会触发的任务，因为有点多提出来了
 */
 export async function checkTaskInBattleEnd(serverId: number, roleId: string, sid: string, warId: number, battleHeroes: number[], battleStar: number, isSuccess: boolean) {
    if(isSuccess) {
        let task = new CheckTask(serverId, roleId);
        task.setParam(TASK_TYPE.BATTLE_WITH_HERO, { warId, battleHeroes });
        task.setParam(TASK_TYPE.BATTLE_MAIN, { warId, count: 1 });
        task.setParam(TASK_TYPE.BATTLE_DAILY_STAR, { warId, battleStar });
        task.setParam(TASK_TYPE.BATTLE_DAILY, { warId, count: 1 });
        task.setParam(TASK_TYPE.BATTLE_DUNGEON, { warId, count: 1 });
        task.setParam(TASK_TYPE.BATTLE_DUNGEON_WAR, { warId, count: 1 });
        task.setParam(TASK_TYPE.BATTLE_TOWER, { warId, count: 1 });
        task.setParam(TASK_TYPE.BATTLE_VESTIGE, { warId, count: 1 });
        task.setParam(TASK_TYPE.BATTLE_EXPEDITION, { warId, count: 1 });
        task.setParam(TASK_TYPE.BATTLE_MAIN_ELITE, { warId, count: 1 });
        task.setParam(TASK_TYPE.BATTLE_BRANCH_ELITE, { warId, count: 1 });
        await task.saveAndPush(sid);
        let dicWar = gameData.war.get(warId);
        if(dicWar && dicWar.warType == WAR_TYPE.NORMAL) {
            checkPopUpCondition(serverId, roleId, POP_UP_SHOP_CONDITION_TYPE.MAIN_BATTLE, { warId }, sid);
        }
    }
}

export async function checkTaskInSkipExpedition(serverId: number, roleId: string, sid: string, warId: number) {
    let task = new CheckTask(serverId, roleId);
    task.setParam(TASK_TYPE.BATTLE_EXPEDITION_START, { warId, count: 1 });
    task.setParam(TASK_TYPE.BATTLE_EXPEDITION, { warId, count: 1 });
    await task.saveAndPush(sid);
}

export async function checkTaskInSkipTower(serverId: number, roleId: string, sid: string, towerLv: number) {
    let task = new CheckTask(serverId, roleId);
    task.setParam(TASK_TYPE.BATTLE_TOWER_LV, { towerLv: towerLv - 1 });
    task.setParam(TASK_TYPE.BATTLE_TOWER_START, { skipTower: true });
    task.setParam(TASK_TYPE.BATTLE_TOWER, { skipTower: true });
    await task.saveAndPush(sid);
}


export async function checkTaskInBattleSweep(serverId: number, roleId: string, sid: string, warId: number, count: number) {
    let task = new CheckTask(serverId, roleId);
    task.setParam(TASK_TYPE.BATTLE_MAIN_SWEEP, { warId, count });
    task.setParam(TASK_TYPE.BATTLE_MAIN, { warId, count });
    task.setParam(TASK_TYPE.BATTLE_DAILY, { warId, count });
    task.setParam(TASK_TYPE.BATTLE_DUNGEON, { warId, count });
    task.setParam(TASK_TYPE.BATTLE_DUNGEON_WAR, { warId, count });
    task.setParam(TASK_TYPE.BATTLE_TOWER, { warId, count });
    task.setParam(TASK_TYPE.BATTLE_VESTIGE, { warId, count });
    task.setParam(TASK_TYPE.BATTLE_EXPEDITION, { warId, count });
    task.setParam(TASK_TYPE.BATTLE_MAIN_START, { warId, count });
    task.setParam(TASK_TYPE.BATTLE_TOWER_START, { warId, count });
    task.setParam(TASK_TYPE.BATTLE_VESTIGE_START, { warId, count });
    task.setParam(TASK_TYPE.BATTLE_DAILY_START, { warId, count });
    task.setParam(TASK_TYPE.BATTLE_EXPEDITION_START, { warId, count });
    task.setParam(TASK_TYPE.BATTLE_DUNGEON_START, { warId, count });
    task.setParam(TASK_TYPE.BATTLE_BRANCH_ELITE, { warId, count });
    await task.saveAndPush(sid);
}


export async function checkTaskInComBattleStart(roleStatus: RoleStatus[], capId: string, blueprtId: number) {
    console.log('********', JSON.stringify(roleStatus), capId, blueprtId)
    for (let { roleId, isRobot } of roleStatus) {
        if (!isRobot) {
            let role = await RoleModel.findByRoleId(roleId);
            let task = new CheckTask(role.serverId, roleId);
            task.setRole(role);
            if (roleId == capId && roleStatus.length > 1) {  // 招募队友
                task.setParam(TASK_TYPE.COM_BATTLE_CREATE_TEAM, {});
            } else if (roleId !== capId) { // 协助寻宝
                task.setParam(TASK_TYPE.COM_BATTLE_ASSIST_TEAM, {});
            }
            task.setParam(TASK_TYPE.COM_BATTLE, {});
            task.setParam(TASK_TYPE.COM_BATTLE_LV, { gid: blueprtId });
            await task.saveAndPush();
        }
    }
}

export async function checkTaskInComBattleEnd(roleStatus: RoleStatus[], capId: string) {
    for (let { roleId, isRobot } of roleStatus) {
        if (!isRobot) {
            let role = await RoleModel.findByRoleId(roleId);
            let task = new CheckTask(role.serverId, roleId);
            task.setRole(role);
            if (roleId == capId && roleStatus.length > 1) {  // 招募队友
                task.setParam(TASK_TYPE.COM_BATTLE_CREATE_TEAM_WIN, {});
            } else if (roleId !== capId) { // 协助寻宝
                task.setParam(TASK_TYPE.COM_BATTLE_ASSIST_TEAM_WIN, {});
            }
            task.setParam(TASK_TYPE.COM_BATTLE_WIN, {});
            await task.saveAndPush();
        }
    }
}

export async function checkTaskInPvpEnd(serverId: number, roleId: string, sid: string, isSuccess: boolean, heroScores: HeroScores[], seasonWinNum: number) {
    let task = new CheckTask(serverId, roleId);
    task.setParam(TASK_TYPE.PVP_WIN, { isSuccess });
    task.setParam(TASK_TYPE.PVP_WIN_SERIES, { isSuccess });
    task.setParam(TASK_TYPE.PVP_HERO_SCORE, { heroScores });
    await task.saveAndPush(sid);
    if(seasonWinNum) {
        checkPopUpCondition(serverId, roleId, POP_UP_SHOP_CONDITION_TYPE.PVP, { seasonWinNum }, sid);
    }
}

export async function checkTaskInGacha(serverId: number, roleId: string, sid: string, count: number, heroes: HeroType[], result: GachaResultIndb[], isGuide: boolean) {
    let task = new CheckTask(serverId, roleId);
    task.setParam(TASK_TYPE.GACHA, { count });
    task.setParam(TASK_TYPE.GACHA_QUALITY_COUNT, { heroes });
    await task.saveAndPush(sid);
    if(!isGuide) checkPopUpConditionInCreateHero(serverId, roleId, result);
}


export async function checkTaskInComposeEquip(serverId: number, roleId: string, sid: string, oldEplace: EPlace[], newEplace: EPlace[]) {
    let task = new CheckTask(serverId, roleId);
    task.setParam(TASK_TYPE.EQUIP_COMPOSE, { count: newEplace.length - oldEplace.length });
    task.setParam(TASK_TYPE.EQUIP_COMPOSE_CNT, { oldEplace, newEplace });
    await task.saveAndPush(sid);
}

export async function checkTaskInEquipLvUp(serverId: number, roleId: string, sid: string, oldEplace: EPlace[], newEplace: EPlace[], ePlaceIds: number[]) {
    let task = new CheckTask(serverId, roleId);
    task.setParam(TASK_TYPE.EQUIP_LV_TO, { oldEplace, newEplace, ePlaceIds });
    task.setParam(TASK_TYPE.EQUIP_LV_UP, { count: ePlaceIds.length });
    await task.saveAndPush(sid);
}

export async function checkTaskInPutJewel(serverId: number, roleId: string, sid: string, hid: number, oldEplace: EPlace[], newEplace: EPlace[], ePlaceId: number, originJewel: JewelType, curJewel: JewelType) {
    let { oldEquip, newEquip } = getEquipById(oldEplace, newEplace, ePlaceId);
    let task = new CheckTask(serverId, roleId);
    task.setParam(TASK_TYPE.EQUIP_PUT_JEWEL, { hid, newEquip, jewels: [originJewel, curJewel ] });
    task.setParam(TASK_TYPE.EQUIP_PUT_JEWEL_CNT, { newEquip });
    task.setParam(TASK_TYPE.EQUIP_JEWEL_RANDSE_CNT, { newEquip, jewels: [originJewel, curJewel ] });
    await task.saveAndPush(sid);
}

export async function checkTaskInPutStone(serverId: number, roleId: string, sid: string, hid: number, oldEplace: EPlace[], newEplace: EPlace[], ePlaceId: number, jewel: JewelType) {
    let { oldEquip, newEquip } = getEquipById(oldEplace, newEplace, ePlaceId);
    let task = new CheckTask(serverId, roleId);
    task.setParam(TASK_TYPE.EQUIP_PUT_STONE, { hid, newEquip });
    task.setParam(TASK_TYPE.EQUIP_PUT_STONE_CNT, { hid, newEquip });
    task.setParam(TASK_TYPE.EQUIP_STONE_CNT, { oldEquip, newEquip });
    task.setParam(TASK_TYPE.EQUIP_STONE_CNT_LV, { hid, newEquip });
    task.setParam(TASK_TYPE.EQUIP_JEWEL_RANDSE_CNT, { newEquip, jewels: [jewel ] });
    await task.saveAndPush(sid);
}

export async function checkTaskInEquipStarUp(serverId: number, roleId: string, sid: string, oldEplace: EPlace[], newEplace: EPlace[], ePlaceId: number, hid: number, isUpStar: boolean, count: number, skinId: number) {
    let task = new CheckTask(serverId, roleId);
    if(isUpStar) {
        let { oldEquip, newEquip } = getEquipById(oldEplace, newEplace, ePlaceId);
        task.setParam(TASK_TYPE.EQUIP_STAR_UP_TO, { oldEquip, newEquip });
        task.setParam(TASK_TYPE.EQUIP_SUIT_SEID_NUM, { oldEplace, newEplace, ePlaceId, skinId });
    }
    task.setParam(TASK_TYPE.EQUIP_STAR_UP_CNT, { hid, ePlaceId, count });
    task.setParam(TASK_TYPE.EQUIP_STAR_UP_CNT_SUM, { count });
    await task.saveAndPush(sid);
    if(isUpStar) {
        checkPopUpCondition(serverId, roleId, POP_UP_SHOP_CONDITION_TYPE.EQUIP_STAR, { equipStar: count }, sid);
    }
}

export async function checkTaskInEquipQualityUp(serverId: number, roleId: string, sid: string, oldEplace: EPlace[], newEplace: EPlace[], ePlaceId: number, hid: number, isUpQuality: boolean, count: number) {
    let task = new CheckTask(serverId, roleId);
    if(isUpQuality) {
        let { oldEquip, newEquip } = getEquipById(oldEplace, newEplace, ePlaceId);
        task.setParam(TASK_TYPE.EQUIP_QUALITY_UP, { hid, ePlaceId });
        task.setParam(TASK_TYPE.EQUIP_QUALITY_UP_TO, { oldEquip, newEquip })
    }
    task.setParam(TASK_TYPE.EQUIP_QUALITY_UP_CNT, { count });
    await task.saveAndPush(sid);
}

export async function checkTaskInEquipReset(serverId: number, roleId: string, sid: string) {
    await checkTask(serverId, roleId, sid, TASK_TYPE.JEWEL_RESET);
}

export async function checkTaskInEquipQuench(serverId: number, roleId: string, sid: string, isSuccess: boolean) {
    let task = new CheckTask(serverId, roleId);
    task.setParam(TASK_TYPE.JEWEL_QUENCH, {});
    if(isSuccess) {
        task.setParam(TASK_TYPE.JEWEL_QUENCH_SUCCESS, { isSuccess });
    }
    await task.saveAndPush(sid);
}

export async function checkTaskInComposeStone(serverId: number, roleId: string, sid: string, count: number) {
    await checkTask(serverId, roleId, sid, TASK_TYPE.STONE_COMPOSE, { count });
}

export async function checkTaskInDonate(serverId: number, roleId: string, sid: string, cosume: RewardInter) {
    let task = new CheckTask(serverId, roleId);
    task.setParam(TASK_TYPE.GUILD_DONATE, {});
    if(cosume.id == getGoldId()) {
        task.setParam(TASK_TYPE.GUILD_GOLD_DONATE, {});
    }
    await task.saveAndPush(sid);
}

// 名将擂台
export async function checkTaskInLadderStart(serverId: number, roleId: string, sid: string) {
    let task = new CheckTask(serverId, roleId);
    task.setParam(TASK_TYPE.LADDER_CNT, { count: 1 });
    await task.saveAndPush(sid);
}

export async function checkTaskInLadderEnd(serverId: number, roleId: string, sid: string, isSuccess: boolean, oldHistoryRank: number, newHistoryRank: number) {
    let task = new CheckTask(serverId, roleId);
    task.setParam(TASK_TYPE.LADDER_SUCCESS_CNT, { isSuccess, count: 1 });
    task.setParam(TASK_TYPE.LADDER_RANK, { oldLadderRank: oldHistoryRank, ladderRank: newHistoryRank })
    await task.saveAndPush(sid);
}

export async function checkTaskInLadderSweep(serverId: number, roleId: string, sid: string, count: number) {
    let task = new CheckTask(serverId, roleId);
    task.setParam(TASK_TYPE.LADDER_CNT, { count });
    task.setParam(TASK_TYPE.LADDER_SUCCESS_CNT, { isSuccess: true, count });
    await task.saveAndPush(sid);
}

export async function checkTaskInHeroGiveFavor(serverId: number, roleId: string, sid: string, shipId: number, connections: Connect[], oldConnections: Connect[]) {
    let task = new CheckTask(serverId, roleId);
    task.setParam(TASK_TYPE.HERO_CONNECT, { shipId, connections, oldConnections });
    task.setParam(TASK_TYPE.CONNECT_ONE_HERO_MAX_LV, { connections, oldConnections });
    task.setParam(TASK_TYPE.CONNECT_ONE_HERO_SUM_LV, { connections, oldConnections });
    await task.saveAndPush(sid);
}

// 获取task状态
export async function getCurTask(roleId: string, session: FrontendOrBackendSession) {
    let userTask = await UserTaskModel.findByRole(roleId);

    let { dailyTaskRefWeekly, dailyTaskRef } = userTask;
    let curWeekStart = getZeroPointD(SHOP_REFRESH_TYPE.WEEKLY);
    if (dailyTaskRefWeekly < curWeekStart) { // 刷新周宝箱
        dailyTaskRefWeekly = curWeekStart;
    }
    session.set('refWeekly', getSeconds(dailyTaskRefWeekly));
    session.push('refWeekly', () => { });

    if (shouldRefresh(dailyTaskRef, new Date())) {
        dailyTaskRef = new Date();
        userTask = await UserTaskModel.updateInfo(roleId, { dailyTaskRef });
        await removeHistoryTask(roleId, TASK_FUN_TYPE.DAILY);
    }
    session.set('refDaily', getSeconds(dailyTaskRef));
    session.push('refDaily', () => { });

    let mainTask = await getMainTask(roleId, userTask);
    let dailyTask = await getDailyTask(roleId, userTask);
    let achievement = await getAchievement(roleId, userTask);
    return { mainTask, dailyTask, achievement };
}

export async function getMainTask(roleId: string, userTask: UserTaskType) {
    let type = TASK_FUN_TYPE.MAIN;
    let { mainTaskStage: stage } = userTask;
    let recMap = await UserTaskRecModel.findByRoleAndType(roleId, type); // group=>userTaskRec

    let taskList: TaskListReturn[] = [];
    for (let [id, dic] of gameData.mainTask) {
        if (dic.taskStage == stage) {
            let dbRec = recMap.get(dic.taskType)?.get(dic.group);
            if (dbRec) {
                taskList.push({ type, id, count: dbRec.count, received: dbRec.received.includes(id) });
            } else {
                taskList.push({ type, id, count: 0, received: false });
            }
        }
    }
    return { stage, taskList }
}

export async function getDailyTask(roleId: string, userTask: UserTaskType) {
    let type = TASK_FUN_TYPE.DAILY;
    let { dailyTaskPoint: point, dailyTaskRefWeekly, dailyTaskPointWeekly: weeklyPoint, dailyTaskBox: box } = userTask;
    let curWeekStart = getZeroPointD(SHOP_REFRESH_TYPE.WEEKLY);
    if (dailyTaskRefWeekly < curWeekStart) { // 刷新
        dailyTaskRefWeekly = curWeekStart;
        weeklyPoint = 0;
        box = [];
    }
    let recMap = await UserTaskRecModel.findByRoleAndType(roleId, type); // group=>userTaskRec

    let taskList: TaskListReturn[] = [];
    for (let [id, dic] of gameData.dailyTask) {
        let dbRec = recMap.get(dic.taskType)?.get(dic.group);
        if (dbRec) {
            taskList.push({ type, id, count: dbRec.count, received: dbRec.received.includes(id) });
        } else {
            taskList.push({ type, id, count: 0, received: false });
        }
    }
    return { point, weeklyPoint, taskList, box }
}

export async function getAchievement(roleId: string, userTask: UserTaskType) {
    let type = TASK_FUN_TYPE.ACHIEVEMENT;
    let { achievementBox: box, achievementPoint: point } = userTask;
    let recMap = await UserTaskRecModel.findByRoleAndType(roleId, type); // group=>userTaskRec

    let taskList: TaskListReturn[] = [];
    for (let [id, dic] of gameData.achievement) {
        let dbRec = recMap.get(dic.taskType)?.get(dic.group);
        if (dbRec) {
            taskList.push({ type, id, count: dbRec.count, received: dbRec.received.includes(id) });
        } else {
            taskList.push({ type, id, count: 0, received: false });
        }
    }
    return { point, taskList, box }
}

export async function getPvpTask(roleId: string) {
    let type = TASK_FUN_TYPE.PVP;
    let recMap = await UserTaskRecModel.findByRoleAndType(roleId, type); // group=>userTaskRec

    let taskList: TaskListReturn[] = [];
    for (let [id, dic] of gameData.pvpDailyTask) {
        let dbRec = recMap.get(dic.taskType)?.get(dic.group);
        if (dbRec) {
            taskList.push({ type, id, count: dbRec.count, received: dbRec.received.includes(id) });
        } else {
            taskList.push({ type, id, count: 0, received: false });
        }
    }
    return { taskList }
}

// 刷新每日任务
export async function refDailyTask(roleId: string, sid: string) {
    let userTask = await UserTaskModel.findByRole(roleId);
    let taskList = await getDailyTask(roleId, userTask);

    // 转移每日任务
    await removeHistoryTask(roleId, TASK_FUN_TYPE.DAILY);
    sendMessageToUserWithSuc(roleId, PUSH_ROUTE.DAILY_TASK_REFRESH, { taskList }, sid);
}

export async function removeHistoryTask(roleId: string, type: number, today?: Date) {

    // 转移每日任务
    let history = await UserTaskRecModel.getHistoryRec(roleId, type, today);
    if (history.length > 0) {
        await UserTaskHistoryModel.pushUserTask(roleId, history);
        await UserTaskRecModel.deleteHistory(history);
    }
}

// 刷新每日宝箱数量
export async function refDailyTaskBox(roleId: string, sid: string, debug = false) {
    let userTask = await UserTaskModel.refreshWeekly(roleId, debug);
    if (userTask) {
        let { dailyTaskPoint: point, dailyTaskPointWeekly: weeklyPoint, dailyTaskBox: box } = userTask;
        sendMessageToUserWithSuc(roleId, PUSH_ROUTE.TASK_BOX_REFRESH, { type: TASK_FUN_TYPE.DAILY, point, weeklyPoint, box }, sid);
    }
}