import { Application, BackendSession } from 'pinus';
import { getRandEelmWithWeight, resResult } from '../../../pubUtils/util';
import { STATUS } from '../../../consts';
import { getPlayerNewHeroGachaData } from '../../../services/activity/newHeroGachaService';
import { RoleModel } from '../../../db/Role';
import { HeroModel } from '../../../db/Hero';
import { RewardInter } from '../../../pubUtils/interface';
import { CreateHeroParam } from '../../../domain/roleField/hero';
import { GachaResult } from '../../../domain/activityField/gachaField';
import { getResultFromContentIdNewHeroActivity } from '../../../services/activity/gachaService';
import { transPiece } from '../../../pubUtils/itemUtils';
import { addItems, createHeroes, handleCost } from '../../../services/rewardService';
import { ActivityNewHeroGachaModel } from '../../../db/ActivityNewHeroGacha';
import { addReward, stringToRewardParam } from '../../../services/activity/giftPackageService';
import { RewardParam } from '../../../domain/activityField/rewardField';
import { ActivityModel, ActivityModelType } from '../../../db/Activity';
import { NewHeroGachaData } from '../../../domain/activityField/newHeroGachaField';


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

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

    /************************新将擢迁, 新武将抽卡****************************/

    /**
    * @description 获取新武将抽卡活动数据
    * @param {{ activityId: number}} msg
    * @param {BackendSession} session
    * @memberof NewHeroGachaHandler
    */
    async getNewHeroGachaActivity(msg: { activityId: number }, session: BackendSession) {
        const { activityId } = msg;
        const roleId = session.get('roleId');
        const serverId = session.get('serverId');

        let playerData = await getPlayerNewHeroGachaData(activityId, serverId, roleId)

        if (!playerData) return resResult(STATUS.ACTIVITY_MISSING);

        return resResult(STATUS.SUCCESS, playerData);
    }

    /**
  * @description 选中武将
  * @param {{ activityId: number, hid:number}} msg
  * @param {BackendSession} session
  * @memberof NewHeroGachaHandler
  */
    async selectedHero(msg: { activityId: number, hid: number }, session: BackendSession) {
        const { activityId, hid } = msg;
        const roleId = session.get('roleId');
        const serverId = session.get('serverId');

        let activityData: ActivityModelType = await ActivityModel.findActivity(activityId);
        let { createTime } = await RoleModel.findByRoleId(roleId);
        let playerData = new NewHeroGachaData(activityData, createTime);
        for (let pageData of playerData.list) {
            await ActivityNewHeroGachaModel.selectedHero(serverId, activityId, roleId, pageData.hid, pageData.hid == hid);
        }
        return resResult(STATUS.SUCCESS);
    }

    /**
        * @description 抽卡
        * @param {{ activityId: number, hid: number, count: number}} msg
        * @param {BackendSession} session
        * @memberof NewHeroGachaHandler
        */
    async pull(msg: { activityId: number, hid: number, count: number }, session: BackendSession) {
        const { activityId, hid, count } = msg;
        const roleId = session.get('roleId');
        const serverId = session.get('serverId');
        const sid = session.get('sid');
        const roleName = session.get('roleName');
        const funcs = session.get('funcs');

        let playerData = await getPlayerNewHeroGachaData(activityId, serverId, roleId)
        if (!playerData) return resResult(STATUS.ACTIVITY_MISSING);

        let item = playerData.findItem(hid);
        if (!item) {
            return resResult(STATUS.ACTIVITY_DATA_ERROR);
        }

        let { lv } = await RoleModel.findByRoleId(roleId);

        let userHeroes = await HeroModel.findByRole(roleId);

        let items: RewardInter[] = [], heroInfo: CreateHeroParam[] = [], resultList: GachaResult[] = [];

        let floorReward = false;//是否中保底奖励
        let activityData = [];//活动需要统计抽中的英雄、碎片品质
        for (let i = 0; i < count; i++) {
            let base = 0;
            let goodId = 0;
            if (floorReward! && (item.count + i >= item.floorCount)) {//保底奖励
                let reward = item.percent[item.floorReward];//{"id":1,"weight":59,"goodId":1}
                base = reward.id;
                goodId = reward.goodId;
            } else {//按照一般概率抽出
                let randomObj = getRandEelmWithWeight(item.percent);//{"dic":{"id":1,"weight":59,"goodId":1},"index":0}
                base = randomObj.dic.id;
                goodId = randomObj.dic.goodId;
            }

            if (base == item.floorReward) {//中了保底
                floorReward = true;
            }
            let result = getResultFromContentIdNewHeroActivity(base, goodId, lv);
            if (result.hid > 0) {
                let hasHero = userHeroes.find(cur => cur.hid == result.hid);
                if (hasHero) { // 已有转换为碎片
                    activityData.push({ hid: hasHero.hid, quality: hasHero.quality });
                    let { pieceId, count } = transPiece(result.hid);
                    result.transferToPiece(pieceId, count);
                    items.push({ id: pieceId, count });
                } else {
                    heroInfo.push({ hid: result.hid, count: 1 })//默认1个英雄
                }
            } else {
                items.push({ id: result.id, count: result.count });
            }
            resultList.push(result);
        }

        // 消耗东西
        let cost = item.cost.map(cur => { return { id: cur.id, count: cur.count * count } });
        let costResult = await handleCost(roleId, sid, cost);
        if (!costResult) return resResult(STATUS.ACTIVITY_RES_NOT_ENOUGH);

        //记录数据
        await ActivityNewHeroGachaModel.addRecord(serverId, activityId, roleId, hid, count, JSON.stringify(resultList));
        if (floorReward) {//抽中保底奖励，重置统计次数
            await ActivityNewHeroGachaModel.resetCount(serverId, activityId, roleId, hid, 0);
        }

        // 给东西
        let { heroes } = await createHeroes(roleId, roleName, sid, serverId, funcs, heroInfo);
        await addItems(roleId, roleName, sid, items);
        //固定奖励
        let rewardParamArr: Array<RewardParam> = stringToRewardParam(item.commonReward);
        let newRewardParamArr: Array<RewardParam> = rewardParamArr.map(obj => { return { id: obj.id, type: obj.type, count: obj.count * count } });
        let commonResult = await addReward(roleId, roleName, sid, serverId, funcs, newRewardParamArr)

        return resResult(STATUS.SUCCESS, {
            hid, activityId, count, randomReward: { heroes, result: resultList }, commonReward: commonResult

        });
    }

}
