import { Application, BackendSession } from 'pinus';
import { STATUS } from '../../../consts/statusCode';
import { resResult, shouldRefresh } from '../../../pubUtils/util';
import { RoleModel } from '../../../db/Role';
import { getGoldObject, handleCost } from '../../../services/role/rewardService';
import { getDungeonData, getDungeonBuyCountCost } from '../../../services/dungeonService';
import * as dicParam from '../../../pubUtils/dicParam';
import { DungeonFirstModel } from '../../../db/DungeonFirst';
import { DungeonResultParam } from '../../../domain/battleField/dungeon';
import { DEBUG_MAGIC_WORD, ITEM_CHANGE_REASON } from '../../../consts';
import { getVipDungeonCnt } from '../../../services/activity/monthlyTicketService';

export default function(app: Application) {
    return new DungeonBattleHandler(app);
}

export class DungeonBattleHandler {
    constructor(private app: Application) {
    }

    // 获取关卡列表
    async getData(msg: { }, session: BackendSession) {
        let roleId = session.get('roleId');
        let role = await RoleModel.findByRoleId(roleId);
        let res = await getDungeonData(role);
        return resResult(STATUS.SUCCESS, res);
    }

    // 购买每日次数
    async buyNum(msg: { count: number }, session: BackendSession) {
        let { count } = msg;
        const roleId = session.get('roleId');
        const sid = session.get('sid');

        let { dungeonCnt = 0, dungeonBuyCnt = 0, dungeonRefTime } = await RoleModel.findByRoleId(roleId);
        let curTime = new Date();
        let needRefresh = shouldRefresh(dungeonRefTime, curTime);
        if(needRefresh) {
            dungeonCnt = 0; dungeonBuyCnt = 0;
        }

        let timesCanBuy = dicParam.DUNGEON_CONST.DUNGEON_CONST_BUY;
        if(dungeonBuyCnt + count > timesCanBuy ) {
            return resResult(STATUS.DUNGEON_REFRESH_TIMES_LACK)
        }
        let buyCost = 0;
        for(let i = 1; i <= count; i++) {
            buyCost += getDungeonBuyCountCost(dungeonBuyCnt + i);
        }
        let {gold} = await RoleModel.findByRoleId(roleId);
        if(buyCost > gold) {
            return resResult(STATUS.DAILY_REFRESH_GOLD_LACK);
        }
        await handleCost(roleId, sid, [getGoldObject(buyCost)], ITEM_CHANGE_REASON.DUNGEON_BATTLE_BUY_CNT);
        await RoleModel.buyCnt(roleId, needRefresh, count, curTime);

        let nextCostGold = getDungeonBuyCountCost(dungeonBuyCnt + count + 1);
        let freeCount = getVipDungeonCnt(session.get('vipStartTime'));
        return resResult(STATUS.SUCCESS, { 
            costGold: buyCost,
            nextCostGold,
            battleCount: freeCount + dungeonBuyCnt + count - dungeonCnt, 
            buyCount: dicParam.DUNGEON_CONST.DUNGEON_CONST_BUY - dungeonBuyCnt - count
        });
    }

    // 购买每日次数
    async getFirstInfo(msg: { movePoint: number }, session: BackendSession) {
        const { movePoint } = msg;
        const serverId: number = session.get('serverId');
        const firstInfos = await DungeonFirstModel.findByMovePoint(serverId, movePoint);
        let result: DungeonResultParam[] = firstInfos.map(firstInfo => {
            return new DungeonResultParam(firstInfo);
        });
        return resResult(STATUS.SUCCESS, { infos: result });
    }

    async debugResetRefTime(msg: { magicWord: string }, session: BackendSession) {
        const { magicWord } = msg;
        if (magicWord !== DEBUG_MAGIC_WORD) {
            return resResult(STATUS.TOKEN_ERR);
        }
        let roleId = session.get('roleId');
        await RoleModel.updateRoleInfo(roleId, { dungeonRefTime: new Date(Date.now() - 86400000) });
        return resResult(STATUS.SUCCESS);
    }
}