import { ACTIVITY_TYPE, ITEM_CHANGE_REASON, POP_UP_SHOP_CONDITION_TYPE, PUSH_BATCH, PUSH_INTERVAL, STATUS } from '../../consts';
import { ActivityModel, ActivityModelType } from '../../db/Activity';
import { PopShopItem, PopUpConditionParamInter, PopUpShopData, PopUpShopPackage, PopUpShopItemShow, } from '../../domain/activityField/popUpShopField';
import { RewardParam } from '../../domain/activityField/rewardField';
import { addReward, stringToRewardParam } from './giftPackageService';
import { ActivityPopUpShopModel, ActivityPopUpShopModelType, PopUpShopItem } from '../../db/ActivityPopUpShop';
import { ServerlistModel } from '../../db/Serverlist';
import moment = require('moment');
import { getActivitiesByType, getActivityById, pushActivities, pushActivityInter, pushSingleActivity } from './activityService';
import { RoleModel, RoleType } from '../../db/Role';
import { HeroType } from '../../db/Hero';
import { pinus } from 'pinus';
import { getRandEelm, getRandSingleEelm } from '../../pubUtils/util';
import { getAllOnlineRoles } from '../redisService';
import { GachaResultIndb } from '../../domain/activityField/gachaField';
import { gameData } from '../../pubUtils/data';
import { ActivityPopUpShopRecModel } from '../../db/ActivityPopUpShopRec';

/**
   * 玩家活动数据
   *
   * @param {number} serverId 区Id
   * @param {number} activityId 活动Id
   * @param {string} roleId 角色Id
   *
   */
export async function getPopUpShopData(activityId: number, serverId: number, roleId: string, role?: RoleType) {
    if(!role) role = await RoleModel.findByRoleId(roleId, 'roleId totalPay lv');

    let activityData = await getActivityById(activityId);
    let playerRecords = await ActivityPopUpShopModel.findAllEffectData(serverId, activityId, roleId);
    let latestRecords = await ActivityPopUpShopModel.findAllLastData(serverId, activityId, roleId);

    let playerData = new PopUpShopData(activityData);
    playerData.setPlayerRecords(playerRecords, latestRecords, role.totalPay, role.lv);

    return playerData;
}

export async function getPopUpShopDataShow(activityId: number, serverId: number, roleId: string, role?: RoleType) {
    let playerData = await getPopUpShopData(activityId, serverId, roleId, role);
    if(playerData && playerData.canShow && playerData.canShow()) {
        return playerData.getShowResult();
    }
    return null
}

export async function checkPopUpConditionInCreateHero(serverId: number, roleId: string, result: GachaResultIndb[]) {
    let conditions = result.map(gachaResult => { 
        let dicHero = gameData.hero.get(gachaResult?.hid);
        return { conditionType: POP_UP_SHOP_CONDITION_TYPE.GET_HERO_BY_QUALITY, param: { quality: dicHero?.quality } };
    });
    return await checkPopUpConditions(serverId, roleId, conditions);
}

export async function checkPopUpCondition(serverId: number, roleId: string, conditionType: POP_UP_SHOP_CONDITION_TYPE, param: PopUpConditionParamInter, sid?: string) {
    return await checkPopUpConditions(serverId, roleId, [{ conditionType, param }], sid);
}

export async function checkPopUpConditionInEntry(serverId: number, roleId: string, sid: string) {
    let guilds = pinus.app.getServersByType('guild');
    let guild = getRandSingleEelm(guilds);
    let isAuctionPopUpShow = await pinus.app.rpc.guild.guildActivityRemote.getAuctionPopUpShow.toServer(guild.id);
    if(isAuctionPopUpShow) {
        await checkPopUpCondition(serverId, roleId, POP_UP_SHOP_CONDITION_TYPE.AUCTION, {}, sid);
    }
}

export async function checkPopUpConditionWhenGuildActivityEnd() {
    let allOnlineUsers = await getAllOnlineRoles();
    let n = Math.ceil(allOnlineUsers.length / PUSH_BATCH); // 一共多少批

    let i = -1;
    let interval = setInterval(async () => {
        if (++i < n) {
            // console.log('****', i)
            let users = allOnlineUsers.slice(i * PUSH_BATCH, (i + 1) * PUSH_BATCH - 1);
            // console.log('****', users)
            for(let { serverId, roleId, sid } of users) {
                await checkPopUpCondition(serverId, roleId, POP_UP_SHOP_CONDITION_TYPE.AUCTION, {}, sid);
            }
        } else {
            clearInterval(interval);
        }
    }, PUSH_INTERVAL);
}

// 弹出礼包任务
export async function checkPopUpConditions(serverId: number, roleId: string, conditions: { conditionType: POP_UP_SHOP_CONDITION_TYPE, param: PopUpConditionParamInter }[], sid?: string) {
    let activities = await getActivitiesByType(serverId, ACTIVITY_TYPE.POP_UP_SHOP);
    let pushData: pushActivityInter[] = [];
    for(let { activityId, type: activityType } of activities) {

        let playerData = await getPopUpShopData(activityId, serverId, roleId);
        let pushItems: PopUpShopItemShow[] = [];
        for(let { conditionType, param } of conditions) {
            for(let pkg of playerData.packages) {
                // console.log('##### 3', pkg.id, pkg.checkPackageCanPush(conditionType))
                if( !pkg.checkPackageCanPush(conditionType)) { // 筛选推送
                    continue;
                }
                let effectTimes = await pkg.getEffectTime();
                if(conditionType == POP_UP_SHOP_CONDITION_TYPE.EQUIP_STAR) {
                    let result = await ActivityPopUpShopRecModel.addRecord(serverId, activityId, roleId, pkg.id, effectTimes.effectBeginTime, effectTimes.effectEndTime, conditionType, param.equipStar);
                    param.equipStarSum = result.num;
                }

                let items = pkg.getItemsByCondition(param);
                if(items.length > 0) {

                    let map = new Map<string, PopShopItem[]>();
                    for(let item of items) {
                        if(!map.has(item.param)) {
                            map.set(item.param, []);
                        }
                        map.get(item.param).push(item);
                    }
                    for(let [_, items] of map) {
                        let popUpShopRec = await ActivityPopUpShopModel.createRecord({ 
                            serverId, activityId, roleId, id: pkg.id, 
                            ...effectTimes,
                            items: items.map(item => new PopUpShopItem(item))
                        });
                        let result = pkg.pushPackage(popUpShopRec);
                        pushItems.push(...result);
                    }
                }
            }
        }
        // console.log('##### 5', pushItems.length)
        if(pushItems.length > 0) {
            pushData.push({ activityId, activityType, param: { popUpShopItems: pushItems } });
        }
    }
    // console.log('##### 6', pushData.length)
    return await pushActivities(pushData, roleId, sid);

}


/**
   * 结算购买礼包的奖励
   *
   * @param {number} serverId 区Id
   * @param {number} activityId 活动Id
   * @param {string} roleId 角色Id
   * @param {string} productID 商品ID
   *
   */
export async function makePopUpShopReward(roleId: string, roleName: string, sid: string, serverId: number, 
    activityId: number, productID: string, paramStr: string, roleInfo: RoleType) {
    if (!paramStr) {
        return STATUS.ORDER_PARAM_ERROR;
    }
    let paramObj = JSON.parse(paramStr);
    let code = paramObj.code;

    let playerData = await getPopUpShopData(activityId, serverId, roleId, roleInfo);
    if (!playerData) {
        return STATUS.ACTIVITY_MISSING;
    }
    if (playerData.type !== ACTIVITY_TYPE.POP_UP_SHOP) {
        return STATUS.ACTIVITY_TYPE_ERROR;
    }

    let playerRecord: ActivityPopUpShopModelType = await ActivityPopUpShopModel.addRecord(serverId, activityId, roleId, code, productID);
    if (!playerRecord) {
        return STATUS.APPLY_ORDER_ERROR;
    }
    let item = playerData.updateRecord(playerRecord, productID);

    let rewardParamArr: Array<RewardParam> = stringToRewardParam(item.reward);
    let result = await addReward(roleId, roleName, sid, serverId, rewardParamArr, ITEM_CHANGE_REASON.POP_UP_BUY_GIFT)

    return {
        code: 0,
        data: Object.assign(result, { item: item, activityId })
    }
}

export async function checkPopUpShopCanBuy(roleId: string, serverId: number, activityId: number, productID: string, paramStr: string) {
        if (!paramStr) {
            return false;
        }
        let paramObj = JSON.parse(paramStr);
        let code = paramObj.code;
    
        let playerData = await getPopUpShopData(activityId, serverId, roleId);
        if (!playerData) {
            return false;
        }
    
        let playerRecord: ActivityPopUpShopModelType = await ActivityPopUpShopModel.findByCode(serverId, activityId, roleId, code);
        if (!playerRecord) {
            return false;
        }

        let item = playerData.checkItem(playerRecord, productID);
        if(!item) return false;
        
        return true
}