
// 动态
import { CHANNEL_PREFIX, GVG_REC_ID, GVG_REC_TYPE, GVG_RESOURCE_TYPE, MSG_SOURCE, MSG_TYPE } from "../../consts";
import { GVGBattleRecType } from "../../db/GVGBattleRec";
import { GVGLeagueModel, GVGLeagueType } from "../../db/GVGLeague";
import { GVGRecModel, GVGRecUpdate } from "../../db/GVGRec";
import { GVGVestigeRecType } from "../../db/GVGVestigeRec";
import { gameData } from "../../pubUtils/data";
import { nowSeconds } from "../../pubUtils/timeUtil";
import { createGroupMsg, pushGroupMsgToRoom } from "../chatService";
import { getGVGConfig } from "./gvgService";

// 加入军团
export async function guildJoinLeagueRecord(leagueCode: string, guildName: string) {
    await leagueJoinOrQuitGuild(leagueCode, guildName, GVG_REC_ID.LEAGUE_JOIN_GUILD);
}

// 退出军团
export async function guildQuitLeagueRecord(leagueCode: string, guildName: string) {
    await leagueJoinOrQuitGuild(leagueCode, guildName, GVG_REC_ID.LEAGUE_QUIT_GUILD);
}

async function leagueJoinOrQuitGuild(leagueCode: string, guildName: string, recId: GVG_REC_ID.LEAGUE_JOIN_GUILD|GVG_REC_ID.LEAGUE_QUIT_GUILD) {
    let { configId } = getGVGConfig();
    let params = [guildName];
    await GVGRecModel.addRec({ leagueCode, configId, type: GVG_REC_TYPE.PREPARE, recId, createTime: nowSeconds(), params })
}

export async function addLeagueRenameRecord(leagueCode: string, leagueName: string) {
    let { configId } = getGVGConfig();
    let params = [leagueName];
    await GVGRecModel.addRec({ leagueCode, configId, type: GVG_REC_TYPE.PREPARE, recId: GVG_REC_ID.LEAGUE_RENAME, createTime: nowSeconds(), params })
}

// 获得资源
export async function addResourceRecord(roleId: string, roleName: string, leagueCode: string, resourceType: GVG_RESOURCE_TYPE, output: number) {
    let { configId } = getGVGConfig();
    let params = [roleName, getResourceNameByType(resourceType), `${output}`];
    await GVGRecModel.addRec({ roleId, leagueCode, configId, type: GVG_REC_TYPE.PREPARE, recId: GVG_REC_ID.ADD_RESOURCE, createTime: nowSeconds(), params })
}

function getResourceNameByType(resourceType: GVG_RESOURCE_TYPE) {
    switch(resourceType) {
        case GVG_RESOURCE_TYPE.FOOD: return '粮食';
        case GVG_RESOURCE_TYPE.MINERAL: return '矿物';
        case GVG_RESOURCE_TYPE.WOOD: return '木堆';
    }
}

export async function addVestigeBattleEndRec(rec: GVGVestigeRecType) {
    if(!rec) return;
    let { configId, vestigeId, groupKey } = rec;
    let vestigeName = gameData.gvgVestigeName.get(vestigeId);
    if(rec.defenseInfo && rec.defenseInfo.isRobot) { // 对手是机器人，驻扎动态
        let { roleId, roleName, leagueCode, newRank, isSuccess } = rec.attackInfo;
        if(isSuccess) {
            let params = [ roleName, vestigeName, `第${newRank}名`];
            await GVGRecModel.addRec({ roleId, leagueCode, configId, groupKey, type: GVG_REC_TYPE.PREPARE, recId: GVG_REC_ID.SETTLE_POINT, createTime: nowSeconds(), params });
        }
    }
    if(rec.defenseInfo && !rec.defenseInfo.isRobot && rec.attackInfo.leagueCode != rec.defenseInfo.leagueCode) {
        let { leagueName, newRank, isSuccess } = rec.attackInfo;
        let { roleId, leagueCode, roleName } = rec.defenseInfo;
        if(isSuccess) {
            let params = [ roleName, vestigeName, `第${newRank}名`, leagueName];
            await GVGRecModel.addRec({ roleId, leagueCode, configId, groupKey, type: GVG_REC_TYPE.PREPARE, recId: GVG_REC_ID.POINT_BE_GRAB, createTime: nowSeconds(), params });
        }
    }
}

export async function addVestigeLeagueRankRec(configId: number, groupKey: string, ranks: { rank: number, field: string }[]) {
    await GVGRecModel.addRecs(ranks.map(({ rank, field: leagueCode }) => {
        let params = [ `第${rank}名`];
        return { leagueCode, configId, groupKey, type: GVG_REC_TYPE.PREPARE, recId: GVG_REC_ID.VESTIGE_RANK, createTime: nowSeconds(), params };
    }));
}

export async function addBattleEndRec(rec: GVGBattleRecType) {
    let { isSuccess, attackTeamAfter: attackTeam, defenseTeamAfter: defenseTeam, configId, groupKey } = rec;
    let { roleId: defenseRoleId, leagueCode: defenseLeague, cityId, index: defenseIndex, curTeamBreak: defenseBreak, originPointId: defenseOriginPoint, roleName: defenseName } = defenseTeam;
    let { roleId: attackRoleId, leagueCode: attackLeague, index: attackIndex, roleName: attackName} = attackTeam;

    let params = new GVGRecUpArr(configId, cityId, groupKey, nowSeconds());
    if(isSuccess) {
        if(!defenseTeam.isRobot) params.pushRec(defenseRoleId, defenseLeague, GVG_REC_TYPE.BATTLE_BY_ROLE, GVG_REC_ID.TEAM_BE_ATTACKED_FAIL, [attackName, `队伍${defenseIndex}`]);
        params.pushRec(attackRoleId, attackLeague, GVG_REC_TYPE.BATTLE_BY_ROLE, GVG_REC_ID.TEAM_ATTACK_SUCCESS, [`队伍${attackIndex}`, defenseName]);
        if(defenseBreak && defenseOriginPoint > 0 ) {
            if(!defenseTeam.isRobot) {
                params.pushRec(defenseRoleId, defenseLeague, GVG_REC_TYPE.BATTLE_BY_ROLE, GVG_REC_ID.TEAM_LOST_POINT, [attackName, `队伍${defenseIndex}`, getPointName(defenseOriginPoint)]);
            }
            params.pushRec(attackRoleId, attackLeague, GVG_REC_TYPE.BATTLE_BY_ROLE, GVG_REC_ID.TEAM_GET_POINT, [`队伍${attackIndex}`, defenseName, getPointName(defenseOriginPoint)]);
        }
    } else {
        if(!defenseTeam.isRobot) params.pushRec(defenseRoleId, defenseLeague, GVG_REC_TYPE.BATTLE_BY_ROLE, GVG_REC_ID.TEAM_BE_ATTACKED_SUCCESS, [attackName, `队伍${defenseIndex}`]);
        params.pushRec(attackRoleId, attackLeague, GVG_REC_TYPE.BATTLE_BY_ROLE, GVG_REC_ID.TEAM_ATTACK_FAIL, [`队伍${attackIndex}`, defenseName]);
    }

    await GVGRecModel.addRecs(params.getUpdateParam());
}

class GVGRecUpArr {
    private arr: GVGRecUpdate[] = [];
    private configId: number;
    private cityId: number;
    private groupKey: string;
    private createTime: number;

    constructor(configId: number, cityId: number, groupKey: string, createTime: number) {
        this.configId = configId;
        this.cityId = cityId;
        this.groupKey = groupKey;
        this.createTime = createTime;
    }

    public pushRec(roleId: string, leagueCode: string, type: GVG_REC_TYPE, recId: GVG_REC_ID, params: string[]) {
        this.arr.push({ 
            configId: this.configId, cityId: this.cityId, groupKey: this.groupKey, createTime: this.createTime,
            roleId, leagueCode, type, recId, params
         })
    }

    public getUpdateParam() {
        return this.arr;
    }
}

function getPointName(pointId: number) {
    let dicAreaPoint = gameData.gvgAreaPoint.get(pointId);
    let dicArea = gameData.gvgArea.get(dicAreaPoint?.areaId);
    if(!dicArea) return '';
    return dicArea.areaName||'';
}

// function getCityName(cityId: number) {
//     let dicCity = gameData.gvgCity.get(cityId);
//     return dicCity?.cityName||'';
// }

// export async function addTeamSettleRec(team: GVGTeamType) {
//     let { roleId, roleName, leagueCode, configId, cityId, pointId, groupKey } = team;
//     await GVGRecModel.addRec({ roleId, leagueCode, configId, cityId, groupKey, type: GVG_REC_TYPE.BATTLE_BY_CITY, recId: GVG_REC_ID.CITY_TEAM_SETTLE, createTime: nowSeconds(), params: [`${roleName}`, getPointName(pointId)] });
//     await GVGRecModel.addRec({ roleId, leagueCode, configId, cityId, groupKey, type: GVG_REC_TYPE.BATTLE_BY_LEAGUE, recId: GVG_REC_ID.LEAGUE_TEAM_SETTLE, createTime: nowSeconds(), params: [`${roleName}`, getPointName(pointId)] });
// }

// export async function addTeamLeaveRec(team: GVGTeamType, pointId: number) {
//     let { roleId, roleName, leagueCode, configId, cityId, groupKey } = team;
//     await GVGRecModel.addRec({ roleId, leagueCode, configId, cityId, groupKey, type: GVG_REC_TYPE.BATTLE_BY_LEAGUE, recId: GVG_REC_ID.LEAGUE_TEAM_LEAVE, createTime: nowSeconds(), params: [`${roleName}`, getPointName(pointId)] });
// }


// —————— 频道消息 ——————
export async function addLeagueLvUpMessage(roleId: string, roleName: string, myLeague: GVGLeagueType, lv: number) {
    const msgData = await createGroupMsg(roleId, roleName, CHANNEL_PREFIX.LEAGUE, myLeague.leagueCode, MSG_TYPE.RICH_TEXT, MSG_SOURCE.GVG_LV_UP, JSON.stringify({ leagueCode: myLeague.leagueCode, name: myLeague.name, lv }), '', '', getGuildCodeString(myLeague));
    await pushGroupMsgToRoom(msgData);
}

export async function changeNoticeMessage(roleId: string, roleName: string, myLeague: GVGLeagueType, notice: string) {
    const msgData = await createGroupMsg(roleId, roleName, CHANNEL_PREFIX.GVG, myLeague.leagueCode, MSG_TYPE.RICH_TEXT, MSG_SOURCE.GVG_NOTICE, JSON.stringify({ leagueCode: myLeague.leagueCode, name: myLeague.name, notice }), '', '', getGuildCodeString(myLeague));
    await pushGroupMsgToRoom(msgData);
}

export function getGuildCodeString(myLeague: GVGLeagueType) {
    let guildCodes = myLeague?.guildCodes||[];
    return guildCodes.join('|')
}

export async function addTechActivateMessage(roleId: string, roleName: string, myLeague: GVGLeagueType, techId: number) {
    const msgData = await createGroupMsg(roleId, roleName, CHANNEL_PREFIX.LEAGUE, myLeague.leagueCode, MSG_TYPE.RICH_TEXT, MSG_SOURCE.GVG_TECH_ACTIVATE, JSON.stringify({ leagueCode: myLeague.leagueCode, name: myLeague.name, techId }), '', '', getGuildCodeString(myLeague));
    await pushGroupMsgToRoom(msgData);
}

export async function addTechUnlockMessage(roleId: string, roleName: string, myLeague: GVGLeagueType, techId: number) {
    const msgData = await createGroupMsg(roleId, roleName, CHANNEL_PREFIX.LEAGUE, myLeague.leagueCode, MSG_TYPE.RICH_TEXT, MSG_SOURCE.GVG_TECH_UNLOCK, JSON.stringify({ leagueCode: myLeague.leagueCode, leaderName: roleName, techId }), '', '', getGuildCodeString(myLeague));
    await pushGroupMsgToRoom(msgData);
}

export async function addVestigeRankMessage(ranks: { rank: number, field: string }[]) {
    let leagueCodes = ranks.map(cur => cur.field);
    let leagues = await GVGLeagueModel.findByCodesWithoutPopulate(leagueCodes, 'leagueCode name guildCodes');
    for(let { rank, field: leagueCode } of ranks) {
        let league = leagues.find(cur => cur.leagueCode == leagueCode);
        if(!league) continue;
        const msgData = await createGroupMsg('', '', CHANNEL_PREFIX.LEAGUE, leagueCode, MSG_TYPE.RICH_TEXT, MSG_SOURCE.GVG_VESTIGE_ACCOUNT, JSON.stringify({ leagueCode: league.leagueCode, name: league.name, rank }), '', '', getGuildCodeString(league));
        await pushGroupMsgToRoom(msgData);    
    }
}

export async function addCityGuardMessage(myLeague: GVGLeagueType, cityId: number) {
    const msgData = await createGroupMsg('', '', CHANNEL_PREFIX.LEAGUE, myLeague.leagueCode, MSG_TYPE.RICH_TEXT, MSG_SOURCE.GVG_OCCUPY_CITY, JSON.stringify({ leagueCode: myLeague.leagueCode, name: myLeague.name, cityId }), '', '', getGuildCodeString(myLeague));
    await pushGroupMsgToRoom(msgData);
}