import { Application, BackendSession, ChannelService, HandlerService } from "pinus";
import { CHANNEL_PREFIX, GUILD_AUTH, GVG_APPLY_TYPE, GVG_PERIOD, GVG_SERVER_TYPE, LEAGUE_AUTH, LEAGUE_MANAGE_TYPE, MAIL_TYPE, MSG_SOURCE, MSG_TYPE, PUSH_ROUTE, REDIS_KEY, STATUS } from "../../../consts";
import { resResult } from "../../../pubUtils/util";
import { GuildModel, GuildType } from "../../../db/Guild";
import { GVGLeagueModel, GVGLeagueType } from "../../../db/GVGLeague";
import { GVGLeagueApplyModel } from "../../../db/GVGLeagueApply";
import { calLeagueCe, getGroupIdOfServer, getGroupKey, getGVGConfig, getGVGPeriodData, getGVGServerType, getServersOfSameGroup } from "../../../services/gvg/gvgService";
import { checkCanManage, checkGuildLeader, checkLeagueAuth, createLeague, getLeagueApplyData, getLeagueInviteData, getMyAuth, joinGuildToLeague, updateGVGBattleLeagueInfo } from "../../../services/gvg/gvgTeamService";
import { LeagueGuildInfo, LeagueListInfo, LeagueMemberListInfo, LeagueSimpleInfo } from "../../../domain/gvgField/returnData";
import { getAllServerName, getServerName, isRoleOnline, updateUserInfo } from "../../../services/redisService";
import { GVG } from "../../../pubUtils/dicParam";
import { RoleModel, RoleType } from "../../../db/Role";
import { GVGUserDataModel } from "../../../db/GVGUserData";
import { sendMessageToGuildWithSuc, sendMessageToUserWithSuc } from "../../../services/pushService";
import { GVGLeaguePrepareModel } from "../../../db/GVGLeaguePrepare";
import { createGroupMsg, pushGroupMsgToRoom } from "../../../services/chatService";
import { sendMailByContent, sendMailToGuildByContent, sendMailToLeagueByContent } from "../../../services/mailService";
import { getGVGCities } from "../../../services/gvg/gvgBattleService";
import { addLeagueRenameRecord, changeNoticeMessage, guildQuitLeagueRecord } from "../../../services/gvg/gvgRecService";
import { LeagueLeader } from "../../../domain/rank";
import GVGCity from "../../../db/GVGCity";

export default function (app: Application) {
    new HandlerService(app, {});
    return new GVGManageHandler(app);
}

export class GVGManageHandler {
    channelService: ChannelService;
    constructor(private app: Application) {
        this.channelService = app.get('channelService');
    }

    // 创建新联军
    async createLeague(msg: { name: string, icon: number, notice: string }, session: BackendSession) {
        const roleId = session.get('roleId');
        const guildCode = session.get('guildCode');
        const { name, icon, notice = '' } = msg;

        const checkNameResult = await GVGLeagueModel.checkName(name);
        if (checkNameResult) return resResult(STATUS.LEAGUE_NAME_DUP);

        let { period } = getGVGPeriodData();
        if(period != GVG_PERIOD.TEAM) return resResult(STATUS.GVG_NOT_TEAM_PERIOD);

        const guild = await GuildModel.findByCode(guildCode, null, '+members +serverId');
        const checkGuildResult = await checkGuildLeader(guildCode, roleId, guild);
        if(checkGuildResult.code != 0) return checkGuildResult;

        const league = await GVGLeagueModel.findLeagueByGuild(guildCode);
        if(league) return resResult(STATUS.GVG_LEAGUE_HAS_EXIST);

        const newLeague = await createLeague(guild, { name, icon, notice });
        await GVGLeagueApplyModel.deleteByGuild(guildCode);

        return resResult(STATUS.SUCCESS, {
            leagueCode: newLeague.leagueCode,
            hasLeague: true
        } );
    }

    // 获取联军列表
    async getLeagues(msg: { page: number, name: string }, session: BackendSession) {
        const roleId = session.get('roleId');
        const guildCode = session.get('guildCode');
        const serverId = session.get('serverId');
        const { page = 1, name } = msg;

        let serverType = await getGVGServerType(serverId);
        if(serverType == GVG_SERVER_TYPE.NO) return resResult(STATUS.GVG_NO_SERVER_TYPE);

        const serverNames = await getAllServerName();
        let serverIds = await getServersOfSameGroup(serverType, serverId);
        const leagues = await GVGLeagueModel.findByCondition(serverType, serverIds, page, name);
        const applies = await GVGLeagueApplyModel.findApplyFromGuild(guildCode);
        let result: LeagueListInfo[] = [];
        for(let league of leagues) {
            let data = new LeagueListInfo(league, serverNames);
            let hasApply = !!applies.find(cur => cur.leagueCode == league.leagueCode);
            data.setHasApply(hasApply);
            data.setLeagueCe(await calLeagueCe(league));
            result.push(data);
        }
        return resResult(STATUS.SUCCESS, {
            leagues: result
        } );
    }

    // 未加入成员查看联军信息
    async getLeagueInfo(msg: { leagueCode: string }, session: BackendSession) {
        const { leagueCode } = msg;
        const guildCode = session.get('guildCode');

        const serverNames = await getAllServerName();
        const league = await GVGLeagueModel.findByCode(leagueCode);
        let result = new LeagueSimpleInfo(league, serverNames)
        let hasApply = await GVGLeagueApplyModel.checkApply(leagueCode, guildCode, GVG_APPLY_TYPE.APPLY);
        result.setHasApply(hasApply);

        let { configId } = getGVGConfig();
        // TODO 占领城池
        const cities = await getGVGCities(league);
        result.setCities(cities);
        result.setLeagueCe(await calLeagueCe(league));

        const leaguePrepare = await GVGLeaguePrepareModel.findByLeague(configId, leagueCode);
        if(leaguePrepare) result.setLv(leaguePrepare.lv);
        
        return resResult(STATUS.SUCCESS, {
            league: result
        } );
    }

    // 申请加入联军
    async applyLeague(msg: { leagueCodes: string[] }, session: BackendSession) {
        const roleId = session.get('roleId');
        const guildCode = session.get('guildCode');
        const serverId = session.get('serverId');
        const { leagueCodes } = msg;

        // 检查时间
        const checkResult = await checkCanManage(serverId);
        if(checkResult.code != 0) return checkResult;

        const guild = await GuildModel.findByCode(guildCode, null, '+members +serverId');
        const checkGuildResult = await checkGuildLeader(guildCode, roleId, guild);
        if(checkGuildResult.code != 0) return checkGuildResult;

        const myLeague = await GVGLeagueModel.findLeagueByGuild(guildCode);
        if(myLeague) return resResult(STATUS.GVG_LEAGUE_HAS_EXIST);

        const serverNames = await getAllServerName();
        const leagues = await GVGLeagueModel.findByCodes(leagueCodes);

        let result: LeagueListInfo[] = [];
        for(let league of leagues) {
            if(league.guildCnt > GVG.GVG_LEAGUE_COMPOSE) continue;

            await GVGLeagueApplyModel.createApply(league, guild, GVG_APPLY_TYPE.APPLY);
            let data = new LeagueListInfo(league, serverNames);
            data.setHasApply(true);
            data.setLeagueCe(await calLeagueCe(league));
            result.push(data);
            let leader = <RoleType>league.leader;
            await sendMessageToUserWithSuc(leader.roleId, PUSH_ROUTE.LEAGUE_APPLY, { guildCode });
        }

        // 返回
        return resResult(STATUS.SUCCESS, { leagues: result });
    }

    // 获取申请列表
    async getApplies(msg: {}, session: BackendSession) {
        const guildCode = session.get('guildCode');

        const myLeague = await GVGLeagueModel.findLeagueByGuild(guildCode);
        if(!myLeague) return resResult(STATUS.GVG_LEAGUE_NOT_EXIST);

        const serverNames = await getAllServerName();
        const applies = await GVGLeagueApplyModel.findApplyFromLeague(myLeague.leagueCode);
        const invitations = await GVGLeagueApplyModel.findInviteFromLeague(myLeague.leagueCode);

        let result = applies.map(apply => getLeagueApplyData(apply, serverNames, invitations));

        // 返回
        return resResult(STATUS.SUCCESS, { guilds: result });
    }

    // 处理申请
    async handleApply(msg: { guildCode: string, isReceive: boolean }, session: BackendSession) {
        const roleId = session.get('roleId');
        const serverId = session.get('serverId');
        const guildCode = session.get('guildCode');

        const { guildCode: targetGuildCode, isReceive } = msg;

        // 检查时间
        const checkResult = await checkCanManage(serverId);
        if(checkResult.code != 0) return checkResult;

        let myLeague = await GVGLeagueModel.findLeagueByGuild(guildCode);
        if(!myLeague) return resResult(STATUS.GVG_LEAGUE_NOT_EXIST);
        // 权限
        const checkAuth = await checkLeagueAuth(roleId, myLeague, LEAGUE_MANAGE_TYPE.HANDLE_APPLY);
        if(!checkAuth) return resResult(STATUS.GVG_HAS_NO_AUTH);

        if(isReceive) {
            let result = await joinGuildToLeague(myLeague, targetGuildCode);
            if(result.code == 0) {
                myLeague = <GVGLeagueType>result.data;
                await GVGLeagueApplyModel.deleteByGuild(targetGuildCode);
            } else {
                await GVGLeagueApplyModel.deleteApply(targetGuildCode, myLeague.leagueCode);
                return result;
            }
        } else { // 不同意，删除申请
            await GVGLeagueApplyModel.deleteApply(targetGuildCode, myLeague.leagueCode);
        }

        // 返回
        return resResult(STATUS.SUCCESS, { 
            guildCnt: myLeague.guildCnt,
            memberCnt: myLeague.memberCnt,
            leagueCe: await calLeagueCe(myLeague),
        });
    }

    // 获取可以邀请的军团
    async getInviteGuilds(msg: { page: number, name: string }, session: BackendSession) {
        const guildCode = session.get('guildCode');
        const serverId = session.get('serverId');
        const { page, name } = msg;

        // 检查时间
        const serverType = await getGVGServerType(serverId);
        const checkResult = await checkCanManage(serverId, serverType);
        if(checkResult.code != 0) return checkResult;

        let myLeague = await GVGLeagueModel.findLeagueByGuild(guildCode);
        if(!myLeague) return resResult(STATUS.GVG_LEAGUE_NOT_EXIST);

        const invitations = await GVGLeagueApplyModel.findInviteFromLeague(myLeague.leagueCode);
        const serverIds = await getServersOfSameGroup(serverType, serverId);
        const serverNames = await getAllServerName();
        const guilds = await GuildModel.findGuildsForGVG(page, name, serverIds);
        let result = guilds.map(guild => {
            let data = new LeagueGuildInfo(guild, serverNames);
            let hasInvited = !!invitations.find(cur => cur.guildCode == guild.code);
            data.setHasInvited(hasInvited);
            return data
        });

        // 返回
        return resResult(STATUS.SUCCESS, { 
            guilds: result
        });
    }

    // 邀请加入联军
    async inviteGuild(msg: { guildCodes: string[] }, session: BackendSession) {
        const roleId = session.get('roleId');
        const guildCode = session.get('guildCode');
        const serverId = session.get('serverId');
        const { guildCodes } = msg;

        // 必须跨服玩法
        const checkResult = await checkCanManage(serverId);
        if(checkResult.code != 0) return checkResult;

        const myLeague = await GVGLeagueModel.findLeagueByGuild(guildCode);
        if(!myLeague) return resResult(STATUS.GVG_LEAGUE_NOT_EXIST);

        // 权限
        const checkAuth = await checkLeagueAuth(roleId, myLeague, LEAGUE_MANAGE_TYPE.INVITE);
        if(!checkAuth) return resResult(STATUS.GVG_HAS_NO_AUTH);

        const guilds = await GuildModel.findByCodes(guildCodes);
        const serverNames = await getAllServerName();

        let result: LeagueGuildInfo[] = [];
        for(let guild of guilds) {
            await GVGLeagueApplyModel.createApply(myLeague, guild, GVG_APPLY_TYPE.INVITE);
            let data = new LeagueGuildInfo(guild, serverNames);
            data.setHasInvited(true);
            result.push(data);
            const leader = <RoleType>guild.leader;
            await sendMessageToUserWithSuc(leader.roleId, PUSH_ROUTE.LEAGUE_INVITE, { leagueCode: myLeague.leagueCode });
        }

        // 返回
        return resResult(STATUS.SUCCESS, { guilds: result });
    }

    // 获取邀请我们军团的联军
    async getLeagueInvitations(msg: {}, session: BackendSession) {
        const guildCode = session.get('guildCode');

        const serverNames = await getAllServerName();
        const invitations = await GVGLeagueApplyModel.findInviteFromGuild(guildCode);
        const applies = await GVGLeagueApplyModel.findApplyFromGuild(guildCode);

        let result: LeagueListInfo[] = [];
        for(let invitation of invitations) {
            let obj = await getLeagueInviteData(invitation, serverNames, applies);
            result.push(obj);
        }

        // 返回
        return resResult(STATUS.SUCCESS, { leagues: result });
    }

    // 处理邀请
    async handleInvitation(msg: { leagueCode: string, isReceive: boolean }, session: BackendSession) {
        const roleId = session.get('roleId');
        const serverId = session.get('serverId');
        const guildCode = session.get('guildCode');

        const { leagueCode: targetLeagueCode, isReceive } = msg;
        
        const checkResult = await checkCanManage(serverId);
        if(checkResult.code != 0) return checkResult;

        // 军团权限
        const checkGuildResult = await checkGuildLeader(guildCode, roleId);
        if(checkGuildResult.code != 0) return checkGuildResult;

        let myLeague = await GVGLeagueModel.findLeagueByGuild(guildCode);
        if(myLeague) return resResult(STATUS.GVG_LEAGUE_HAS_EXIST);

        const league = await GVGLeagueModel.findByCode(targetLeagueCode);
        if(!league) return resResult(STATUS.GVG_LEAGUE_NOT_EXIST);

        let hasLeague = false;
        if(isReceive) {
            let result = await joinGuildToLeague(league, guildCode);
            if(result.code == 0) {
                hasLeague = true;
                await GVGLeagueApplyModel.deleteByGuild(guildCode);
            } else {
                await GVGLeagueApplyModel.deleteInvite(guildCode, league.leagueCode);
                return result;
            }
        } else { // 不同意，删除申请
            await GVGLeagueApplyModel.deleteInvite(guildCode, league.leagueCode);
        }

        // 返回
        return resResult(STATUS.SUCCESS, {
            leagueCode: targetLeagueCode,
            isReceive,
            hasLeague
        });
    }

    // 获取组成的所有军团列表
    async getGuilds(msg: { leagueCode: string }, session: BackendSession) {

        const { leagueCode: targetLeagueCode } = msg;
        const league = await GVGLeagueModel.findByCode(targetLeagueCode);
        if(!league) return resResult(STATUS.GVG_LEAGUE_NOT_EXIST);

        let { configId } = getGVGConfig();
        const guilds = await GuildModel.findByCodes(league.guildCodes);
        const members = league.members||[];
        let roleIds = members.map(member => member.roleId);
        const serverNames = await getAllServerName();
        const userdatas = await GVGUserDataModel.findByRoles(configId, targetLeagueCode, roleIds);
        const result = guilds.map(guild => {
            let obj = new LeagueGuildInfo(guild, serverNames);
            let active = userdatas.reduce((pre, userdata) => {
                let member = members.find(cur => cur.roleId == userdata.roleId);
                if(member && member.guildCode == guild.code) {
                    return pre + (userdata.active||0);
                }
                return pre;
            }, 0);
            obj.setActive(active);
            return obj;
        });

        // 返回
        return resResult(STATUS.SUCCESS, {
            guilds: result
        });
    }

    // 获取组成的所有玩家列表
    async getMembers(msg: { leagueCode: string }, session: BackendSession) {

        const { leagueCode: targetLeagueCode } = msg;
        const league = await GVGLeagueModel.findByCode(targetLeagueCode);
        if(!league) return resResult(STATUS.GVG_LEAGUE_NOT_EXIST);

        let { configId } = getGVGConfig();

        const members = league.members||[];
        let roleIds = members.map(member => member.roleId);
        const roles = await RoleModel.findByRoleIds(roleIds);
        const serverNames = await getAllServerName();
        const userdatas = await GVGUserDataModel.findByRoles(configId, targetLeagueCode, roleIds);
        const result: LeagueMemberListInfo[] = [];
        for(let role of roles) {
            let obj = new LeagueMemberListInfo(role, serverNames);
            let userdata = userdatas.find(userdata => userdata.roleId == role.roleId);
            if(userdata) obj.setByUserData(userdata);
            let member = members.find(cur => cur.roleId == role.roleId);
            if(member) obj.setAuth(member.auth);
            let isOnline = await isRoleOnline(role.roleId);
            obj.setOnline(!!isOnline);
            result.push(obj);
        }

        // 返回
        return resResult(STATUS.SUCCESS, {
            members: result
        });
    }

    // 踢掉某个军团
    async kick(msg: { guildCode: string }, session: BackendSession) {
        const roleId = session.get('roleId');
        const serverId = session.get('serverId');
        const guildCode = session.get('guildCode');

        const { guildCode: targetGuildCode } = msg;

        // 不能踢自己的军团
        if(guildCode == targetGuildCode) return resResult(STATUS.GVG_CANNOUT_KICK_SELF_GUILD);

        const checkResult = await checkCanManage(serverId);
        if(checkResult.code != 0) return checkResult;
        
        // 权限
        let myLeague = await GVGLeagueModel.findLeagueByGuild(guildCode);
        if(!myLeague) return resResult(STATUS.GVG_LEAGUE_NOT_EXIST);
        const checkAuth = await checkLeagueAuth(roleId, myLeague, LEAGUE_MANAGE_TYPE.KICK);
        if(!checkAuth) return resResult(STATUS.GVG_HAS_NO_AUTH);

        // 更新对方军团信息
        const guild = await GuildModel.quitFromLeague(targetGuildCode, myLeague.leagueCode, '+members');
        if(!guild) return resResult(STATUS.GUILD_HAS_QUIT);
        // 更新联军信息
        myLeague = await GVGLeagueModel.quitGuild(myLeague.leagueCode, guild);

        // 发送消息
        await sendMessageToGuildWithSuc(targetGuildCode, PUSH_ROUTE.LEAGUE_KICK, { leagueCode: myLeague.leagueCode });
        guildQuitLeagueRecord(myLeague.leagueCode, guild.name);
        await sendMailToGuildByContent(MAIL_TYPE.LEAGUE_KICK, targetGuildCode, { params: [ myLeague.name ] });

        // 返回
        return resResult(STATUS.SUCCESS, {
            guildCnt: myLeague.guildCnt,
            memberCnt: myLeague.memberCnt,
            leagueCe: await calLeagueCe(myLeague),
        });
    }

    // 军团退出
    async quit(msg: { guildCode: string }, session: BackendSession) {
        const roleId = session.get('roleId');
        const serverId = session.get('serverId');
        const guildCode = session.get('guildCode');

        const { guildCode: targetGuildCode } = msg;
        // 检查是否是自己军团
        if(guildCode != targetGuildCode) return resResult(STATUS.GVG_CANNOUT_KICK_SELF_GUILD);

        const checkResult = await checkCanManage(serverId);
        if(checkResult.code != 0) return checkResult;
        
        // 只能团长退出
        let guild = await GuildModel.findByCode(guildCode, null, '+members +serverId');
        const checkGuildResult = await checkGuildLeader(guildCode, roleId, guild);
        if(checkGuildResult.code != 0) return checkGuildResult;

        // 联军盟主不能退出
        let myLeague = await GVGLeagueModel.findLeagueByGuild(guildCode);
        if(!myLeague) return resResult(STATUS.GVG_LEAGUE_NOT_EXIST);
        const checkAuth = await checkLeagueAuth(roleId, myLeague, LEAGUE_MANAGE_TYPE.QUIT);
        if(!checkAuth) return resResult(STATUS.GVG_HAS_NO_AUTH);

        // 更新对方军团信息
        guild = await GuildModel.quitFromLeague(guild.code, myLeague.leagueCode, '+members');
        // 更新联军信息
        myLeague = await GVGLeagueModel.quitGuild(myLeague.leagueCode, guild);
        // 发送消息
        await sendMessageToGuildWithSuc(targetGuildCode, PUSH_ROUTE.LEAGUE_KICK, { leagueCode: myLeague.leagueCode });
        guildQuitLeagueRecord(myLeague.leagueCode, guild.name);

        // 返回
        return resResult(STATUS.SUCCESS, {
            hasLeague: !!guild.leagueCode
        });
    }

    // 解散联军
    async dismiss(msg: { leagueCode: string }, session: BackendSession) {
        const roleId = session.get('roleId');
        const serverId = session.get('serverId');
        const guildCode = session.get('guildCode');

        const { leagueCode: targetLeagueCode } = msg;
        const { configId, period } = getGVGPeriodData();
        if(period != GVG_PERIOD.TEAM) return resResult(STATUS.GVG_NOT_TEAM_PERIOD);
        const groupKey = await getGroupKey(serverId);

        const checkResult = await checkCanManage(serverId);
        if(checkResult.code != 0) return checkResult;
        
        // 权限
        let myLeague = await GVGLeagueModel.findLeagueByGuild(guildCode);
        if(!myLeague) return resResult(STATUS.GVG_LEAGUE_NOT_EXIST);
        if(myLeague.leagueCode != targetLeagueCode) return resResult(STATUS.LEAGUE_CODE_ERR);

        const checkAuth = await checkLeagueAuth(roleId, myLeague, LEAGUE_MANAGE_TYPE.DISSMISS);
        if(!checkAuth) return resResult(STATUS.GVG_HAS_NO_AUTH);

        // 更新对方军团信息
        await GuildModel.dissmissLeague(targetLeagueCode);
        // 更新联军信息
        await GVGLeagueModel.dismiss(myLeague.leagueCode);
        await GVGLeagueApplyModel.deleteByLeague(myLeague.leagueCode);
        // 发送消息
        for(let guildCode of myLeague.guildCodes) {
            await sendMessageToGuildWithSuc(guildCode, PUSH_ROUTE.LEAGUE_DISSMISS, { leagueCode: myLeague.leagueCode });
            await sendMailToGuildByContent(MAIL_TYPE.LEAGUE_DISSMISS, guildCode, { params: [ myLeague.name ]});
        }
        await GVGCity.leagueDismiss(configId, groupKey, targetLeagueCode);
        
        // 返回
        return resResult(STATUS.SUCCESS, {
            hasLeague: false
        });
    }

    // 获取可转让的人的列表
    async getCandidate(msg: { leagueCode: string }, session: BackendSession) {
        const roleId = session.get('roleId');
        const serverId = session.get('serverId');
        const guildCode = session.get('guildCode');

        const { leagueCode: targetLeagueCode } = msg;
        // 权限
        let myLeague = await GVGLeagueModel.findLeagueByGuild(guildCode);
        if(!myLeague) return resResult(STATUS.GVG_LEAGUE_NOT_EXIST);
        if(myLeague.leagueCode != targetLeagueCode) return resResult(STATUS.LEAGUE_CODE_ERR);

        const checkAuth = await checkLeagueAuth(roleId, myLeague, LEAGUE_MANAGE_TYPE.ABDICATE);
        if(!checkAuth) return resResult(STATUS.GVG_HAS_NO_AUTH);

        let { configId } = getGVGConfig();

        const members = myLeague.members||[];
        const candidates = members.filter(cur => cur.auth == LEAGUE_AUTH.SUB_LEADER);
        let roleIds = candidates.map(member => member.roleId);
        const roles = await RoleModel.findByRoleIds(roleIds);
        const serverNames = await getAllServerName();
        const userdatas = await GVGUserDataModel.findByRoles(configId, targetLeagueCode, roleIds);
        const result = roles.map(role => {
            let obj = new LeagueMemberListInfo(role, serverNames);
            let userdata = userdatas.find(userdata => userdata.roleId == role.roleId);
            if(userdata) obj.setByUserData(userdata);
            let member = members.find(cur => cur.roleId == role.roleId);
            if(member) obj.setAuth(member.auth);
            return obj;
        });

        const leaguePrepare = await GVGLeaguePrepareModel.findByLeague(configId, targetLeagueCode);
        const { producerCnt, fighterCnt } = leaguePrepare||{ producerCnt: 0, fighterCnt: 0 }

        // 返回
        return resResult(STATUS.SUCCESS, {
            producerCnt, fighterCnt,
            members: result
        });
    }

    // 获取可转让的人的列表
    async abdicate(msg: { roleId: string }, session: BackendSession) {
        const roleId = session.get('roleId');
        const serverId = session.get('serverId');
        const guildCode = session.get('guildCode');

        const { roleId: targetRoleId } = msg;
        // 权限
        let myLeague = await GVGLeagueModel.findLeagueByGuild(guildCode);
        if(!myLeague) return resResult(STATUS.GVG_LEAGUE_NOT_EXIST);
        const checkAuth = await checkLeagueAuth(roleId, myLeague, LEAGUE_MANAGE_TYPE.ABDICATE);
        if(!checkAuth) return resResult(STATUS.GVG_HAS_NO_AUTH);

        const checkHisAuth = await checkLeagueAuth(targetRoleId, myLeague, LEAGUE_MANAGE_TYPE.BE_ABDICATED);
        if(!checkHisAuth) return resResult(STATUS.GVG_HE_HAS_NO_AUTH);

        const targetRole = await RoleModel.findByRoleId(targetRoleId, '_id roleName serverId guildName roleId');
        let targetRoleServerName = await getServerName(targetRole.serverId);

        // 修改联军数据 members，leader
        myLeague = await GVGLeagueModel.abdicate(myLeague.leagueCode, roleId, targetRoleId, targetRole._id);
        // 推送
        await sendMessageToUserWithSuc(targetRoleId, PUSH_ROUTE.LEAGUE_ABDICATE, { leagueCode: myLeague.leagueCode });
        await sendMailByContent(MAIL_TYPE.LEAGUE_ABDICATE, roleId, { params: [ myLeague.name ] });
        await updateUserInfo(REDIS_KEY.LEAGUE_INFO, myLeague.leagueCode, [{ field: 'leader', value: new LeagueLeader(targetRole) }]);

        let myAuth = getMyAuth(myLeague, roleId);
        // 返回
        return resResult(STATUS.SUCCESS, {
            auth: myAuth,
            leader: {
                name: targetRole.roleName,
                serverId: targetRole.serverId,
                serverName: targetRoleServerName
            },
        });
    }

    // 设置联军信息
    async setLeagueInfo(msg: { leagueCode: string, name: string, notice: string, icon: number }, session: BackendSession) {
        const roleId = session.get('roleId');
        const roleName = session.get('roleName');
        const guildCode = session.get('guildCode');
        const serverId = session.get('serverId');

        const { leagueCode: targetLeagueCode, name, notice, icon } = msg;

        // 检查名字是否重
        if(name != undefined) {
            const checkNameResult = await GVGLeagueModel.checkName(name);
            if (checkNameResult) return resResult(STATUS.LEAGUE_NAME_DUP);
        }
        // 权限
        let myLeague = await GVGLeagueModel.findLeagueByGuild(guildCode);
        if(!myLeague) return resResult(STATUS.GVG_LEAGUE_NOT_EXIST);
        if(myLeague.leagueCode != targetLeagueCode) return resResult(STATUS.WRONG_PARMS);
        const checkAuth = await checkLeagueAuth(roleId, myLeague, LEAGUE_MANAGE_TYPE.SET_INFO);
        if(!checkAuth) return resResult(STATUS.GVG_HAS_NO_AUTH);

        // 修改联军数据
        myLeague = await GVGLeagueModel.setInfo(targetLeagueCode, name, notice, icon);
        if(name != undefined) {
            await updateUserInfo(REDIS_KEY.LEAGUE_INFO, myLeague.leagueCode, [{ field: 'name', value: name }]);
            addLeagueRenameRecord(myLeague.leagueCode, name);
        }
        if(icon != undefined) {
            await updateUserInfo(REDIS_KEY.LEAGUE_INFO, myLeague.leagueCode, [{ field: 'icon', value: name }]);
        }
        if(notice != undefined) {
            await changeNoticeMessage(roleId, roleName, myLeague, notice);
        }
        await updateGVGBattleLeagueInfo(serverId, myLeague.leagueCode, { leagueName: name, icon })

        // 返回
        return resResult(STATUS.SUCCESS, {
            leagueCode: myLeague.leagueCode,
            name: myLeague.name,
            notice: myLeague.notice,
            icon: myLeague.icon,
        });
    }

    // 团长发送消息给军团内所有成员的邮箱
    async sendMail(msg: { content: string }, session: BackendSession) {

        const roleId = session.get('roleId');
        const roleName = session.get('roleName');
        const guildCode = session.get('guildCode');
        const { content } = msg;
        // 权限
        let myLeague = await GVGLeagueModel.findLeagueByGuild(guildCode);
        if(!myLeague) return resResult(STATUS.GVG_LEAGUE_NOT_EXIST);
        const checkAuth = await checkLeagueAuth(roleId, myLeague, LEAGUE_MANAGE_TYPE.SEND_MAIL);
        if(!checkAuth) return resResult(STATUS.GVG_HAS_NO_AUTH);

        let auth = getMyAuth(myLeague, roleId);

        //下发邮件
        await sendMailToLeagueByContent(MAIL_TYPE.LEAGUE_MAIL, myLeague.leagueCode, { sendName: `${auth == 1? "盟主": "副盟主"}：${roleName}`, params: [content] }, myLeague);

        return resResult(STATUS.SUCCESS, { isSuccess: true });
    }

    // 团长发送世界频道
    async recruit(msg: { content: string }, session: BackendSession) {

        const roleId = session.get('roleId');
        const roleName = session.get('roleName');
        const serverId = session.get('serverId');
        const guildCode = session.get('guildCode');
        
        const { content } = msg;
        // 检查时间
        const checkResult = await checkCanManage(serverId);
        if(checkResult.code != 0) return checkResult;

        // 权限
        let myLeague = await GVGLeagueModel.findLeagueByGuild(guildCode);
        if(!myLeague) return resResult(STATUS.GVG_LEAGUE_NOT_EXIST);
        const checkAuth = await checkLeagueAuth(roleId, myLeague, LEAGUE_MANAGE_TYPE.RERUIT);
        if(!checkAuth) return resResult(STATUS.GVG_HAS_NO_AUTH);

        // 发送战区频道消息
        const groupId = await getGroupIdOfServer(serverId);
        let channelId = `${groupId}`;
        const msgData = await createGroupMsg(roleId, roleName, CHANNEL_PREFIX.GVG, channelId, MSG_TYPE.RICH_TEXT, MSG_SOURCE.GVG_RECURIT, JSON.stringify({ leagueCode: myLeague.leagueCode, name: myLeague.name, info: content }), '', '');
        if (!msgData) return resResult(STATUS.WRONG_PARMS);
        await pushGroupMsgToRoom(msgData);

        return resResult(STATUS.SUCCESS, { isSuccess: true });
    }
}