import { UserGuildModel, UserGuildType } from '../db/UserGuild';
import { getArmyTrainJuDian, getGuildTrainGkInfo, getTrainBaseByLv } from '../pubUtils/data';
import { nowSeconds, getZeroPoint, isToday, getSeconds } from '../pubUtils/timeUtil';
import { GUILD_STRUCTURE, PUSH_ROUTE, SHOP_REFRESH_TYPE } from '../consts';
import { GuildTrainType, GuildTrainModel, TrainInstance } from '../db/GuildTrain';
import { GuildModel, GuildType } from '../db/Guild';
import { findWhere } from 'underscore';
import { ARMY } from '../pubUtils/dicParam';
import { lockData } from './redLockService';
import { pinus } from 'pinus';
import { MailModel, MailType } from '../db/Mail';
import { resResult, getRandSingleEelm, shouldRefresh } from '../pubUtils/util';
import { STATUS } from '../consts/statusCode';
import { GuildTrainReportModel } from '../db/GuildTrainReport';
import { DATA_NAME } from '../consts/dataName';
import { sendMailByContent } from './mailService';
import { MAIL_TYPE } from '../consts';
import { getGuildChannelSid } from './chatChannelService';
import { sendMessageToGuildWithSuc } from './pushService';
/**
 * 获得userGuild，并检查，是否需要每日重置购买挑战次数和今日挑战次数，已经检查是否需要每周重置练兵场
 * @param roleId 
 * @param serverId 
 */
export async function refreshTrain(userGuild: UserGuildType, roleId: string, serverId: number) {
    let { trainCount, trainTime, buyTrainCount, guildCode} = userGuild;
    await resetTrain(guildCode, serverId);//检查重置练兵场
    if (trainTime < getZeroPoint()) {//重置挑战次数和购买次数
        trainCount = ARMY.ARMY_TRAIN_BUYTIMES;

        buyTrainCount = 0;
        userGuild = await UserGuildModel.updateInfo(roleId, {trainCount, trainTime: nowSeconds(), buyTrainCount}, {});
    }

    return userGuild;
}

export async function getTrainBoxRewardsResult(guildCode: string) {

    let guildTrains = await GuildTrainModel.findGuildTrain(guildCode);//获得未失效的宝箱奖励
    let resTrainBoxs = [];
    guildTrains.forEach(({ trainInstances, trainId }) => {
        let { trainInstances: instances } = getArmyTrainJuDian(trainId);
        let flag = false;
        let boxRewards = [];
        trainInstances.map(({ hid, progress, endTime, trainBoxs }) => {
            let isComplete = false;
            let instance = findWhere(instances, { hid });
            if (progress >= instance.progress) {
                isComplete = true;
                if (endTime > nowSeconds())
                    flag = true;
            }
            boxRewards.push({ hid, recordBoxs: trainBoxs, trainId, endTime, isComplete });
        });
        if (flag) {
            resTrainBoxs.push({ trainId, boxRewards });
        }
    })
    return resTrainBoxs
}

/**
 * 领过的试炼宝箱不允许再领
 *
 * @export
 * @param {string} guildCode
 * @param {number[]} receivedTrainBox: {[英雄id]:[军团id]} 表示已经领取过该英雄奖励的军团
 * @return {*} 
 */
export async function getTrainBoxRewardsResultWithoutAlreadyGeted(guildCode: string, receivedTrainBox: { [hid: number]: string[] }) {

    let guildTrains = await GuildTrainModel.findGuildTrain(guildCode);//获得未失效的宝箱奖励
    let resTrainBoxs = [];
    guildTrains.forEach(({ trainInstances, trainId }) => {
        let { trainInstances: instances } = getArmyTrainJuDian(trainId);
        let flag = false;
        let boxRewards = [];
        trainInstances.map(({ hid, progress, endTime, trainBoxs }) => {
            let isComplete = false;
            let instance = findWhere(instances, { hid });
            if (progress >= instance.progress) {
                isComplete = true;
                if (endTime > nowSeconds())
                    flag = true;
            }
            // 在任何军团都未领取过 || 在本军团领取过  ==>   全部正常展示
            if (!receivedTrainBox[hid] || (receivedTrainBox[hid] && receivedTrainBox[hid].length > 0 && receivedTrainBox[hid].indexOf(guildCode) != -1)) {
                boxRewards.push({ hid, recordBoxs: trainBoxs, trainId, endTime, isComplete });
            } else {
                // 领取过，且不是在本军团领取的  ==> 置灰、奖励不可领取
                isComplete = false;
                endTime = 0;
                boxRewards.push({ hid, recordBoxs: trainBoxs, trainId, endTime, isComplete });
            }
            
        });
        if (flag) {
            resTrainBoxs.push({ trainId, boxRewards });
        }
    })
    return resTrainBoxs
}

/**
 * 获得未失效的试炼宝箱奖励
 * @param guildTrain 
 */
export function getGuildTrainRewards (guildTrain) {        
    let { trainInstances: instances } = getArmyTrainJuDian(guildTrain.trainId);
    let trainBoxs = guildTrain.trainInstances.map(({hid, trainBoxs, endTime})=>{
        let instance = findWhere(instances, { hid });
        let isComplete = false;
        if ( guildTrain.progress >= instance.progress)
            isComplete = true;
        return {hid, recordBoxs: trainBoxs, trainId: guildTrain.trainId, endTime, isComplete};
    }) 
    return { trainBoxs };
}
/**
 * 获得练兵场封装信息 练兵场关卡进度，排行榜，挑战次数，和练兵场升级奖励
 * @param guildTrain 
 * @param roleId 
 * @param trainCount 
 * @param trainRewards 
 */
export  function getGuildTrainInfo (guildTrain: GuildTrainType, roleId: string, trainCount:number, trainRewards: Array<number>) {
    let { trainId, isComplete, trainInstances, ranks } = guildTrain;
    
    // ranks.sort(function(a, b) {
    //     return b.score - a.score;
    // });
    // let myRank = {};
    // let resRanks = ranks.map(({roleId: rankRoleId, score}, index)=>{
    //     if (roleId == rankRoleId)
    //         myRank = {roleId: rankRoleId, score, rankLv: index+1};
    //     return {roleId: rankRoleId, score, rankLv: index+1};
    // });
    let { trainInstances: instances } = getArmyTrainJuDian(trainId);
    let resTrainInstances = trainInstances.map(({hid, progress, endTime})=>{
        let instance = findWhere(instances, { hid });
        let isComplete = false;
        if ( progress >= instance.progress)
            isComplete = true;
        return {hid, progress, endTime, isComplete};
    });
    let resGuildTrain = {trainId, isComplete, trainInstances: resTrainInstances, myRank: 0, ranks: [] };

    return { guildTrain: resGuildTrain, trainCount, trainRewards};
}
/**
 * 解锁试炼trainId
 * @param code 
 * @param trainId 
 */
export async function unlockTrain(code: string, trainId: number) {
    let guildTrain = await GuildTrainModel.findTrainByTrainIdNotLock(code, trainId);
    if (!!guildTrain) {
        return guildTrain;
    }
    let { trainInstances } = getArmyTrainJuDian(trainId);
    // 初始化
   
    let instances:Array<TrainInstance> = trainInstances.map(trainInstance => {
        let t = new TrainInstance();
        t.hid = trainInstance.hid;
        t.progress = 0;
        t.endTime = 0;
        t.trainBoxs = [];
        return t;
    });
    guildTrain = await GuildTrainModel.openGuildTrain(code, trainId, instances);
    await GuildTrainReportModel.resetGuildTrainReport(code, trainId);
    await GuildModel.updateInfo(code, { trainId }, {});

    return guildTrain;
}
/**
 * 重置练兵场
 * @param code 
 * @param serverId 
 */
export async function resetTrain(code: string, serverId: number) {
    let res:any = await lockData(serverId, DATA_NAME.GUILD, code);//加锁
    if (!!res.err) 
        return;
    let { structure, trainId, resetTrainTimeDaily } = await GuildModel.findGuild(code, serverId, 'structure trainId resetTrainTimeDaily');
    // if(trainId && shouldRefresh(resetTrainTimeDaily, new Date())) {
    //     let { trainInstances } = getArmyTrainJuDian(trainId);
    //     // 初始化
    //     let instances = trainInstances.map(trainInstance => {
    //         let t = new TrainInstance();
    //         t.hid = trainInstance.hid;
    //         t.progress = 0;
    //         t.endTime = 0;
    //         t.trainBoxs = [];
    //         return t;
    //     });
    //     await GuildTrainModel.updateGuildTrain(code, trainId, { trainInstances: instances });
    //     await GuildModel.updateInfo(code, { resetTrainTimeDaily: new Date() });
    // }


    let { lv } = findWhere(structure, {id: GUILD_STRUCTURE.TRAIN});
    let guild = await GuildModel.resetGuildTrain(code, serverId, lv);
    res.releaseCallback();//解锁
    if (!guild) {//不满足重置条件，结束并解锁
        return trainId;
    }
    const userGuildList = await UserGuildModel.getListByGuild(code, 'trainRewards roleId createdAt', {});
    const guildTrains = await GuildTrainModel.getGuildTrainBoxs(code);

    //结算未领取的宝箱奖励发送到邮件中
    userGuildList.forEach(async function ({roleId, trainRewards, createdAt}) {
        if (getZeroPoint(SHOP_REFRESH_TYPE.WEEKLY) < getSeconds(createdAt)) {
            // 此处发放的奖励是上周该军团的奖励; 如果本周一5AM之后，不发放
            return;
        }
        let goods: { id: number, count: number }[] = [];
        guildTrains.forEach(guildTrain=>{
            guildTrain.trainInstances.forEach(({ trainBoxs, hid })=>{
                if (!findWhere(trainBoxs, {roleId})) {
                    let { heroRewards } = getGuildTrainGkInfo(guildTrain.trainId, hid);
                    let good = getRandSingleEelm(heroRewards);
                    goods.push(good);
                }
            })
        });
        
        for (let trainId = 1; trainId < guild.trainId; trainId++) {
            let { jinjieReward } = getArmyTrainJuDian(trainId);
            if (trainRewards.indexOf(trainId)) {
                goods.push(...jinjieReward);
            }
        }
        if (!!goods.length) {           
            await sendMailByContent(MAIL_TYPE.GUILD_TRAIN_REWARD, roleId, {
                params: [], goods
            });
        }
    });
    
    await sendMessageToGuildWithSuc(code, PUSH_ROUTE.GUILD_TRAIN_RESET, {});

    await GuildTrainModel.resetGuildTrain(code);//将开启的练兵场锁定
    await unlockTrain(code, guild.trainId);//开启练兵场1级
    // 只重置上周加入军团的玩家，本周加入的不重置
    await UserGuildModel.resetTrainUserGuildLastWeekJoinedIn(code);//重置玩家的挑战次数和购买挑战次数
    return trainId
}
/**
 * 检查并重置试炼
 * @param roleId 
 * @param serverId 
 */
export async function checkResetTrain(roleId: string, serverId: number) {
    let userGuild = await UserGuildModel.getMyGuild(roleId,'guildCode');
    if (!userGuild)
        return;
    await resetTrain(userGuild.guildCode, serverId);
}

/**
 * 成员退出删除排行奖励
 * @param guildCode 
 * @param roleId 
 * @param trainId 
 */
export async function removeTrainRank(guildCode: string, roleId: string, trainId: number) {
    await GuildTrainModel.removeTrainRank(guildCode, roleId, trainId);
}

/**
 * 获取军团练兵场
 * @param roleId 
 * @param guild 
 * @param userGuild 
 */
export async function getGuildTrainInstance(roleId: string, guild: GuildType, userGuild: UserGuildType) {
    let { trainId, trainLv, code } = guild;
    let guildTrain = await GuildTrainModel.findTrainByTrainIdNotLock(code, trainId);
    if (!guildTrain) {
        guildTrain = await unlockTrain(code, trainId);
    }
    let { trainCount, trainRewards, buyTrainCount } = userGuild;
    let result: any = getGuildTrainInfo(guildTrain, roleId, trainCount, trainRewards);
    result.buyTrainCount = buyTrainCount || 0;
    result.trainLv = trainLv;
    return result;
}