import { DEFAULT_HERO_LV, FIGURE_UNLOCK_CONDITION, LINEUP_NUM, REDIS_KEY, STATUS, TASK_TYPE } from "../consts";
import { SkinModel } from "../db/Skin";
import { DEFAULT_HEROES, HERO_SYSTEM_TYPE } from "../consts";
import { HeroModel, HeroSkin, HeroType, HeroUpdate } from "../db/Hero";
import { RoleModel, RoleType, RoleUpdate } from "../db/Role";
import { SkinUpdate } from "../db/Skin";
import { Figure, TopHero } from "../domain/dbGeneral";
import { CalHeroCe, CalRoleCe } from "../domain/roleField/calCe";
import { gameData, getHeroExpByLv } from "../pubUtils/data";
import { accomplishTask, checkTask, checkTaskWithHeroes } from './taskUtil';
import { combineFigureInfo, unlockFigureWithoutSave } from './itemUtils';
import { TaskListReturn } from "../domain/roleField/task";
import { nowSeconds } from "./timeUtil";
import { reduceCe, resResult } from "./util";
import { calculatetopLineup, } from "./playerCe";
import { GuildModel, GuildType } from "../db/Guild";
import { PvpDefenseModel } from "../db/PvpDefense";
import { ActivityModelType } from "../db/Activity";
import { EquipModel } from '../db/Equip';
import { ActionPointModel } from '../db/ActionPoint';
import { BattleDropModel } from '../db/BattleDrop';
import { BattleRecordModel } from '../db/BattleRecord';
import { BattleSweepRecordModel } from '../db/BattleSweepRecord';
import { DailyRecordModel } from '../db/DailyRecord';
import { EventRecordModel } from '../db/EventRecord';
import { ExpeditionPointModel } from '../db/ExpeditionPoint';
import { ExpeditionRecordModel } from '../db/ExpeditionRecord';
import { ExpeditionWarRecordModel } from '../db/ExpeditionWarRecord';
import { HangUpRecordModel } from '../db/HangUpRecord';
import { HangUpSpdUpRecModel } from '../db/HangUpSpdUpRec';
import { SearchRecordModel } from '../db/SearchRecord';
import { TowerRecordModel } from '../db/TowerRecord';
import { TowerTaskRecModel } from '../db/TowerTaskRec';
import { ItemModel } from '../db/Item';
import { SchoolModel } from '../db/School';
import { FriendShipModel } from '../db/FriendShip';
import { FriendApplyModel } from '../db/FriendApply';
import { FriendRelationModel } from '../db/FriendRelation';
import { ActivityBuyRecordsModel } from '../db/ActivityBuyRecords';
import { ActivityDailyChallengesModel } from '../db/ActivityDailyChallenges';
import { ActivityDailyCoinModel } from '../db/ActivityDailyCoin';
import { ActivityDailyGiftsModel } from '../db/ActivityDailyGifts';
import { ActivityDailyGKModel } from '../db/ActivityDailyGK';
import { ActivityDailyMealModel } from '../db/ActivityDailyMeal';
import { ActivityDailyRMBGiftsModel } from '../db/ActivityDailyRMBGifts';
import { ActivityFirstGiftModel } from '../db/ActivityFirstGift';
import { ActivityGrowthFundModel } from '../db/ActivityGrowthFund';
import { ActivityGrowthModel } from '../db/ActivityGrowth';
import { ActivityGrowthPointModel } from '../db/ActivityGrowthPoint';
import { ActivityMonopolyModel } from '../db/ActivityMonopoly';
import { ActivityMonopolyLandModel } from '../db/ActivityMonopolyLand';
import { ActivityMonthlyTicketModel } from '../db/ActivityMonthlyTicket';
import { ActivityNewHeroGachaModel } from '../db/ActivityNewHeroGacha';
import { ActivityNewHeroGiftModel } from '../db/ActivityNewHeroGift';
import { ActivityNewHeroGKModel } from '../db/ActivityNewHeroGK';
import { ActivityPopUpShopModel } from '../db/ActivityPopUpShop';
import { ActivityPopUpShopRecordModel } from '../db/ActivityPopUpShopRecord';
import { ActivityRechargeMoneyModel } from '../db/ActivityRechargeMoney';
import { ActivityRefreshShopModel } from '../db/ActivityRefreshShop';
import { ActivityRefreshTaskModel } from '../db/ActivityRefreshTask';
import { ActivityRefreshTaskPointModel } from '../db/ActivityRefreshTaskPoint';
import { ActivitySelfServiceGoodsModel } from '../db/ActivitySelfServiceGoods';
import { ActivitySelfServiceModel } from '../db/ActivitySelfService';
import { ActivitySelfServiceShopModel } from '../db/ActivitySelfServiceShop';
import { ActivityShopModel } from '../db/ActivityShop';
import { ActivitySignInModel } from '../db/ActivitySignIn';
import { ActivityTaskPointModel } from '../db/ActivityTaskPoint';
import { ActivityThirtyDaysModel } from '../db/ActivityThirtyDays';
import { ActivityThirtyDaysPointRewardModel } from '../db/ActivityThirtyDaysPointReward';
import { ActivityTreasureHuntFirstPageModel } from '../db/ActivityTreasureHuntFirstPage';
import { ActivityTreasureHuntShopModel } from '../db/ActivityTreasureHuntShop';
import { ActivityTreasureHuntTaskModel } from '../db/ActivityTreasureHuntTask';
import { ActivityTreasureHuntTreasureShopModel } from '../db/ActivityTreasureHuntTreasureShop';
import { ActivityVipRechargeMoneyModel } from '../db/ActivityVipRechargeMoney';
import { BattleBlueprtDropModel } from '../db/BattleBlueprtDrop';
import { ChatInfoModel } from '../db/ChatInfo';
import { DungeonFirstModel } from '../db/DungeonFirst';
import { EquipPrintDropModel } from '../db/EquipPrintDrop';
import { FriendPointModel } from '../db/FriendPoint';
import { FriendPresentLogModel } from '../db/FriendPresentLog';
import { GroupMailModel } from '../db/GroupMail';
import { UserGuildModel } from '../db/UserGuild';
import { UserGuildApplyModel } from '../db/UserGuildApply';
import { GuildRecModel } from '../db/GuildRec';
import { MailModel } from '../db/Mail';
import { MessageModel } from '../db/Message';
import { PrivateMessageModel } from '../db/PrivateMessage';
import { RScriptRecordModel } from '../db/RScriptRecord';
import { ScriptBarrageModel } from '../db/ScriptBarrage';
import { ServerMailModel } from '../db/ServerMail';
import { UserGachaModel } from '../db/UserGacha';
import { UserGachaRecModel } from '../db/UserGachaRec';
import { UserGiftCodeModel } from '../db/UserGiftCode';
import { UserGuildActivityRecModel } from '../db/UserGuildActivityRec';
import { UserOrderModel } from '../db/UserOrder';
import { UserShopModel } from '../db/UserShop';
import { UserTaskModel } from '../db/UserTask';
import { UserTaskHistoryModel } from '../db/UserTaskHistory';
import { UserTaskRecModel } from '../db/UserTaskRec';
import { WishPoolReportModel } from '../db/WishPoolReport';
import { pick } from "underscore";

// 储存在内存中的初始数据
export function getInitRoleInfo() {
    let topLineup: TopHero[] = [], topLineupCe = 0, allCe = 0, 
        heroes: HeroUpdate[] = [], initHeroes: HeroUpdate[] = [], initSkins: SkinUpdate[] = [], heroNum = 0,
        conditions: {type: FIGURE_UNLOCK_CONDITION, paramHid: number }[] = [];
    let role = new RoleModel();
    let calRoleCe = new CalRoleCe(role);
    let roleAttr = calRoleCe.cal(HERO_SYSTEM_TYPE.INIT);

    for(let { actorId: hid } of gameData.recruit) {
        let { quality, initialStars: star, jobid: job, name: hName, initialSkin } = gameData.hero.get(hid);
        // 皮肤
        let skin = new SkinModel();
        let dicFashion = gameData.fashion.get(initialSkin);
        if(!dicFashion) {
            console.log(`not found skin: ${initialSkin} of ${hid}`);
            continue;
        }
        let skinInfo = { ...skin.toJSON(), id: initialSkin, hid, skinName: dicFashion.name, skinId: dicFashion.heroId };
        initSkins.push(skinInfo);
        // 武将
        let hero = new HeroModel();
        let heroInfo = {...hero.toJSON(), hid, star, quality, hName, job, skins: [{ id: initialSkin, skin: skinInfo._id, enable: true }], skinId: skinInfo.skinId, lv: DEFAULT_HERO_LV, exp: getHeroExpByLv(DEFAULT_HERO_LV - 1) || 0 };
        let calHeroCe = new CalHeroCe(hid, heroInfo);
        let heroAttr = calHeroCe.cal(HERO_SYSTEM_TYPE.INIT);
        let ce = calHeroCe.getCalculatedCe(roleAttr);
        heroes.push({ ...heroInfo, attr: heroAttr, ce, historyCe: ce });
        // 更新role表
        if(DEFAULT_HEROES.includes(hid)) {
            // 头像
            conditions.push({ type: FIGURE_UNLOCK_CONDITION.GET_HERO, paramHid: hid });
            allCe += ce;
            heroNum++;
            initHeroes.push({ ...heroInfo, attr: heroAttr, ce, historyCe: ce });
        }
    }
    let { figureInfo, heads, frames, spines } = unlockFigureWithoutSave(conditions, role);
    // 最强阵容
    initHeroes.sort((a, b) => { return b.ce - a.ce });
    for(let i = 0; i < LINEUP_NUM; i++) {
        if(initHeroes[i]) {
            let { hid, ce, _id } = initHeroes[i];
            topLineup.push({ hid, ce, hero: _id });
            topLineupCe += ce;
        }
    }

    let initRole: RoleUpdate = { topLineupCe, topLineup, attr: roleAttr, ce: allCe, heroNum, heroNumUpdatedAt: Date.now(), heads, frames, spines };
    return {
        role: initRole, heroes, skins: initSkins, figureInfo
    }
}

export class UpdateHeroes {
    roleId: string;
    roleName: string;
    serverId: number;
    incHeroNum: number = 0;
    incRoleCe: number = 0;
    pushHeroes: {hid: number, incHeroCe: number, ce: number, hero: HeroUpdate}[] = [];
    roleUpdate: RoleUpdate;
    role: RoleType;
    guild: GuildType;

    constructor(roleId: string, roleName: string, serverId: number) {
        this.roleId = roleId;
        this.roleName = roleName;
        this.serverId = serverId;
    }

    public setRole(role: RoleType) {
        this.role = role;
    }

    public async getRole() {
        if(!this.role) {
            this.role = await RoleModel.findByRoleId(this.roleId);
        }
        return this.role;
    }

    public addRoleUpdateParam(param: RoleUpdate) {
        this.roleUpdate = {...this.roleUpdate, ...param};
    }

    public async updateDbCe(isCreate: boolean, heroInfo: HeroUpdate, originCe = 0) {
        let role = await this.getRole();
        if(isCreate) this.incHeroNum ++;
        if(heroInfo != originCe) this.incRoleCe += heroInfo.ce - originCe;
        this.addRoleUpdateParam(await calculatetopLineup(role, heroInfo.hid, heroInfo.ce, heroInfo._id ));
        this.pushHeroes.push({ hid: heroInfo.hid, incHeroCe: heroInfo.ce - originCe, ce: heroInfo.ce, hero: heroInfo });
    }

    // 更新战力相关的各个表
    public async saveCeToDb() {
        let role = await this.getRole();
        // 更新role表
        this.role = await RoleModel.updateRoleInfo(this.roleId, { 
            heroNum: this.incHeroNum + role.heroNum, ce: this.incRoleCe + role.ce, heroNumUpdatedAt: nowSeconds(), ...this.roleUpdate
        });

        // 更新guild表
        if(role.hasGuild) {
            this.guild = await GuildModel.updateCe(this.roleId, this.incRoleCe, true); // 公会更新战力
        }
        for(let { hid, incHeroCe } of this.pushHeroes) {
            await PvpDefenseModel.updateCe(this.roleId, hid, incHeroCe); // 更新pvp防守阵战力
        }
    }

    public async updateRedisRank(Rank: any) {
        let role = await this.getRole();
        let { serverId, roleId, pushHeroes } = this;
        // 更新军团信息
        if(this.guild) {
            let r = new Rank(REDIS_KEY.GUILD_INFO, { code: this.guild.code });
            await r.generParamAndSet(REDIS_KEY.GUILD_INFO, { guildCode: this.guild.code }, { guild: this.guild });
        }
        // 武将数量
        if(this.incHeroNum > 0) {
            let r = new Rank(REDIS_KEY.HERO_NUM_RANK, { serverId });
            await r.setRankWithRoleInfo(roleId, role.heroNum, role.heroNumUpdatedAt, role);    
        }

        // 最强阵容
        let r = new Rank(REDIS_KEY.TOP_LINEUP_RANK, { serverId });
        await r.setRankWithRoleInfo(roleId, reduceCe(role.topLineupCe), 0, role);
        
        // 最强武将
        for(let { hid, ce, hero } of pushHeroes) {
            let r2 = new Rank(REDIS_KEY.TOP_HERO_RANK, { serverId });
            await r2.setRankWithHeroInfo(roleId, hid, ce, 0, hero);

            let r4 = new Rank(REDIS_KEY.HERO_RANK, { serverId, hid });
            await r4.setRankWithHeroInfo(roleId, hid, ce, 0, hero);
        }
        // 总战力
        let r3 = new Rank(REDIS_KEY.SUM_CE_RANK, { serverId });
        await r3.setRankWithRoleInfo(roleId, reduceCe(role.ce), 0, role);

        // 更新最强五人阵容信息
        let r5 = new Rank(REDIS_KEY.TOP_LINEUP_INFO, { serverId });
        await r5.generParamAndSet(REDIS_KEY.TOP_LINEUP_INFO, { roleId }, { role });
    }

    public async pushMessage(pinus: any, sid: string) {
        let role = await this.getRole();
        let uids = [{ uid: this.roleId, sid }];
        pinus.app.get('channelService').pushMessageByUids('onPlayerCeUpdate', resResult(STATUS.SUCCESS, { ce: reduceCe(role.ce) , heros: this.pushHeroes.map(cur => { return {...cur, ce: reduceCe(cur.ce), incHeroCe: reduceCe(cur.incHeroCe) }}), topLineupCe:  reduceCe(role.topLineupCe) }), uids);
    }

}

export class CreateHeroes extends UpdateHeroes {
    private resultHeroes: HeroType[] = [];
    private heroNum = 0;
    // 推送信息
    private taskPushMessage: TaskListReturn[] = [];
    private activityTaskPushMessage = [];
    private figureInfos: { heads: Figure[], frames: Figure[], spines: Figure[] }[] = [];
    private skinPushMessages: { heros: {skins: HeroSkin[], hid: number}[], skins: {id: number, hid: number }[]} = { heros: [], skins: [] };
    
    private async getSkinsOfThisHero(hid: number, initSkinInfo: SkinUpdate, isInit: boolean) {
        let allSkins = isInit? []: await SkinModel.findbyRoleAndHid(this.roleId, hid);
        let skin = await SkinModel.insertSkins(this.roleId, this.roleName, [initSkinInfo]);
        this.skinPushMessages.skins.push(...skin);
        if(skin) allSkins.push(...skin);
        let skins: { id: number, skin: string, enable: boolean, skinId: number }[] = [];
        for(let skin of allSkins) {
            skins.push({ id: skin.id, skin: skin._id, enable: skin.id == initSkinInfo.id, skinId: skin.skinId });
        }
        return skins
    }

    // game-server里面创建武将
    public async createWithHeroInfo(infos: Map<number, { heroInfo: HeroUpdate, skinInfo: SkinUpdate }>) {
        let role = await this.getRole();
        // 数据处理
        let conditions = new Array<{ type: number, paramHid?: number, paramFavourLv?: number, paramSkinId?: number }>(); // 解锁头像条件
        let initHeroInfos: HeroUpdate[] = [];
        for (let [ hid, { heroInfo, skinInfo }] of infos) {
            conditions.push({ type: FIGURE_UNLOCK_CONDITION.GET_HERO, paramHid: heroInfo.hid });
            this.updateDbCe(true, heroInfo);
            // 皮肤使用初始加载进内存的数据
            let skins = await this.getSkinsOfThisHero(hid, { ...skinInfo, _id: new SkinModel()._id }, false);
            initHeroInfos.push({ ...heroInfo, skins, _id: new HeroModel()._id });
        }
        // 武将使用初始加载数据插入
        this.resultHeroes = await HeroModel.insertHeroes(this.roleId, this.roleName, this.serverId, initHeroInfos);
        let heroSkins = this.resultHeroes.map(cur => { return pick(cur, ['hid', 'skins']) });

        this.skinPushMessages.heros.push(...heroSkins);
        // 头像解锁
        let { figureInfo, frames, heads, spines } = unlockFigureWithoutSave(conditions, role);
        this.figureInfos.push(figureInfo);
        this.addRoleUpdateParam({ frames, heads, spines });
        // 更新战力
        await this.saveCeToDb();
    }

    // 创建初始账号时候的初始
    public async createWithInitInfo(infos: Map<number, { heroInfo: HeroUpdate, skinInfo: SkinUpdate }>, figureInfo: { heads: Figure[], frames: Figure[], spines: Figure[] }) {
        this.figureInfos.push(figureInfo);
        let heroeInfos: HeroUpdate[] = [];
        for (let [ hid, { heroInfo, skinInfo }] of infos) {
            this.updateDbCe(true, heroInfo);
            let model = new SkinModel();
            let skins = await this.getSkinsOfThisHero(hid, { ...skinInfo, _id: model._id }, true);
            heroeInfos.push({ ...heroInfo, skins, _id: new HeroModel()._id});
        }
        this.resultHeroes = await HeroModel.insertHeroes(this.roleId, this.roleName, this.serverId, heroeInfos);
    }

    public async clearTask(activitiesTypeMap: ActivityModelType[]) {
        // 任务
        console.log('****** checkTask before', Date.now())
        let m1 = await checkTask(this.roleId, TASK_TYPE.HERO_NUM, this.heroNum, true, {});
        let m2 = await checkTaskWithHeroes(this.roleId, TASK_TYPE.HERO_QUALITY, this.resultHeroes);
        let m3 = await checkTaskWithHeroes(this.roleId, TASK_TYPE.HERO_QUALITY_STAR_UP, this.resultHeroes);
        let m4 = await checkTaskWithHeroes(this.roleId, TASK_TYPE.HERO_LV, this.resultHeroes);
        this.taskPushMessage.push(...m1, ...m2, ...m3, ...m4);
        console.log('****** checkTask after', Date.now())
        //成长任务
        console.log('****** accomplishTask before', Date.now())
        let mm1 = await accomplishTask(this.serverId, this.roleId, TASK_TYPE.HERO_NUM, this.heroNum, null, activitiesTypeMap)
        let mm2 = await accomplishTask(this.serverId, this.roleId, TASK_TYPE.HERO_QUALITY, this.heroNum, { heroes: this.resultHeroes }, activitiesTypeMap)
        console.log('****** accomplishTask after', Date.now())
        this.activityTaskPushMessage.push(...mm1, ...mm2);
    }

    public async pushMessage(pinus: any, sid: string) {
        let role = await this.getRole();
        let uids = [{ uid: this.roleId, sid }];
        pinus.app.get('channelService').pushMessageByUids('onPlayerCeUpdate', resResult(STATUS.SUCCESS, { ce: reduceCe(role.ce) , heros: this.pushHeroes.map(cur => { return {...cur, ce: reduceCe(cur.ce), incHeroCe: reduceCe(cur.incHeroCe) }}), topLineupCe:  reduceCe(role.topLineupCe) }), uids);
        pinus.app.get('channelService').pushMessageByUids('onTaskUpdate', resResult(STATUS.SUCCESS, this.taskPushMessage), uids);
        pinus.app.get('channelService').pushMessageByUids('onActivityUpdate', resResult(STATUS.SUCCESS, this.activityTaskPushMessage), uids);
        let figureInfo = combineFigureInfo(this.figureInfos);
        if (!!figureInfo && (figureInfo.heads.length > 0 || figureInfo.frames.length > 0 || figureInfo.spines.length > 0)) {
            pinus.app.get('channelService').pushMessageByUids('onHeadChange', resResult(STATUS.SUCCESS, { ...figureInfo }), uids);
        }
        pinus.app.get('channelService').pushMessageByUids('onHeroSkinChange', resResult(STATUS.SUCCESS, this.skinPushMessages), uids);
    }

    public getResultHeroes() {
        return this.resultHeroes.map(cur => { 
            return { ...cur, ce: reduceCe(cur.ce)}
        });
    }
}


export async function deletRole(roleId: string) {
    let role = await RoleModel.findByRoleId(roleId);
    if(!role || !role.hasInit) return false;
    await ActionPointModel.deleteMany({roleId});
    await ActivityBuyRecordsModel.deleteMany({ roleId });
    await ActivityDailyChallengesModel.deleteMany({ roleId });
    await ActivityDailyCoinModel.deleteMany({ roleId });
    await ActivityDailyGiftsModel.deleteMany({ roleId });
    await ActivityDailyGKModel.deleteMany({ roleId });
    await ActivityDailyMealModel.deleteMany({ roleId });
    await ActivityDailyRMBGiftsModel.deleteMany({ roleId });
    await ActivityFirstGiftModel.deleteMany({ roleId });
    await ActivityGrowthModel.deleteMany({ roleId });
    await ActivityGrowthPointModel.deleteMany({ roleId });
    await ActivityGrowthFundModel.deleteMany({ roleId });
    await ActivityMonopolyModel.deleteMany({ roleId });
    await ActivityMonopolyLandModel.deleteMany({ roleId });
    await ActivityMonthlyTicketModel.deleteMany({ roleId });
    await ActivityNewHeroGachaModel.deleteMany({ roleId });
    await ActivityNewHeroGiftModel.deleteMany({ roleId });
    await ActivityNewHeroGKModel.deleteMany({ roleId });
    await ActivityPopUpShopModel.deleteMany({ roleId });
    await ActivityPopUpShopRecordModel.deleteMany({ roleId });
    await ActivityRechargeMoneyModel.deleteMany({ roleId });
    await ActivityRefreshShopModel.deleteMany({ roleId });
    await ActivityRefreshTaskModel.deleteMany({ roleId });
    await ActivityRefreshTaskPointModel.deleteMany({ roleId });
    await ActivitySelfServiceModel.deleteMany({ roleId });
    await ActivitySelfServiceGoodsModel.deleteMany({ roleId });
    await ActivitySelfServiceShopModel.deleteMany({ roleId });
    await ActivityShopModel.deleteMany({ roleId });
    await ActivitySignInModel.deleteMany({ roleId });
    await ActivityTaskPointModel.deleteMany({ roleId });
    await ActivityThirtyDaysModel.deleteMany({ roleId });
    await ActivityThirtyDaysPointRewardModel.deleteMany({ roleId });
    await ActivityTreasureHuntFirstPageModel.deleteMany({ roleId });
    await ActivityTreasureHuntShopModel.deleteMany({ roleId });
    await ActivityTreasureHuntTaskModel.deleteMany({ roleId });
    await ActivityTreasureHuntTreasureShopModel.deleteMany({ roleId });
    await ActivityVipRechargeMoneyModel.deleteMany({ roleId });
    await BattleBlueprtDropModel.deleteMany({ roleId });
    await BattleDropModel.deleteMany({ roleId });
    await BattleRecordModel.deleteMany({ roleId });
    await BattleSweepRecordModel.deleteMany({ roleId });
    await ChatInfoModel.deleteMany({ roleId });
    await ChatInfoModel.updateMany({ 'recentPrivateChats.targetRoleId': roleId }, { $pull: { recentPrivateChats: { targetRoleId: roleId } } });
    await DailyRecordModel.deleteMany({ roleId });
    await DungeonFirstModel.deleteMany({ roleId });
    await EquipModel.deleteMany({ roleId });
    await EquipPrintDropModel.deleteMany({ roleId });
    await EventRecordModel.deleteMany({ roleId });
    await ExpeditionPointModel.deleteMany({ roleId });
    await ExpeditionRecordModel.deleteMany({ roleId });
    await ExpeditionWarRecordModel.deleteMany({ roleId });
    await FriendApplyModel.deleteMany({ roleId });
    await FriendApplyModel.deleteMany({ frdRoleId: roleId });
    await FriendPointModel.deleteMany({ roleId });
    await FriendPresentLogModel.deleteMany({ roleId });
    await FriendPresentLogModel.deleteMany({ hisRoleId: roleId });
    await FriendRelationModel.deleteMany({ roleId });
    await FriendRelationModel.updateMany({ 'friends.roleId': roleId }, { $pull: { friends: { roleId }} });
    await FriendRelationModel.updateMany({ 'blacklist.roleId': roleId }, { $pull: { blacklist: { roleId }} });
    await FriendShipModel.deleteMany({ roleIdA: roleId });
    await FriendShipModel.deleteMany({ roleIdB: roleId });
    await GroupMailModel.updateMany({ 'roleStatus.roleId': roleId }, { $pull: { roleStatus: { roleId } } });
    await GroupMailModel.deleteMany({ roleId });
    await GroupMailModel.deleteMany({ targetRoleId: roleId });
    let userGuild = await UserGuildModel.getMyGuild(roleId);
    if(userGuild) {
        if(userGuild.auth == 1) {
            const guild = await GuildModel.dismiss(userGuild.guildCode, role.serverId);
            await UserGuildModel.dismiss(userGuild.guildCode);
            const { members } = guild;
            await RoleModel.dissmissGuild(members);
            await UserGuildApplyModel.deleteApplyByGuild(userGuild.guildCode);

        } else {
            await GuildModel.update({ members: { $in: [roleId] } }, { $pull: { members: roleId }, $inc: { memberCnt: -1, managerCnt: userGuild.auth == 2? -1: 0, guildCe: -role.ce }, $set: { isMemberMax: false } })
        }
    }
    await GuildModel.updateMany({ invitedMembers: { $in: [roleId] } }, { $pull: { invitedMembers: roleId } });
    await GuildRecModel.deleteMany({ roleId });
    await HangUpSpdUpRecModel.deleteMany({ roleId });
    await HangUpRecordModel.deleteMany({ roleId });
    await HeroModel.deleteMany({ roleId });
    await ItemModel.deleteMany({ roleId });
    await MailModel.deleteMany({ roleId });
    await MessageModel.deleteMany({ roleId });
    await MessageModel.deleteMany({ targetRoleId: roleId });
    await PrivateMessageModel.deleteMany({ roleId });
    await PrivateMessageModel.deleteMany({ targetRoleId: roleId });
    await PvpDefenseModel.deleteMany({ roleId });
    await RScriptRecordModel.deleteMany({ roleId });
    await SchoolModel.deleteMany({ roleId });
    await ScriptBarrageModel.deleteMany({ roleId });
    await SearchRecordModel.deleteMany({ roleId });
    await ServerMailModel.updateMany({ 'roleStatus.roleId': roleId }, { $pull: { roleStatus: { roleId } } });
    await SkinModel.deleteMany({ roleId });
    await TowerRecordModel.deleteMany({ roleId });
    await TowerTaskRecModel.deleteMany({ roleId });
    await UserGachaModel.deleteMany({ roleId });
    await UserGachaRecModel.deleteMany({ roleId });
    await UserGiftCodeModel.deleteMany({ roleId });
    await UserGuildModel.deleteMany({ roleId });
    await UserGuildActivityRecModel.deleteMany({ roleId });
    await UserGuildApplyModel.deleteMany({ roleId });
    await UserOrderModel.deleteMany({ roleId });
    await UserShopModel.deleteMany({ roleId });
    await UserTaskModel.deleteMany({ roleId });
    await UserTaskHistoryModel.deleteMany({ roleId });
    await UserTaskRecModel.deleteMany({ roleId });
    await WishPoolReportModel.deleteMany({ wishRoleId: roleId});
    await WishPoolReportModel.deleteMany({ dntRoleId: roleId});

    let doc = new RoleModel();
    const update = Object.assign(doc.toJSON(), pick(role, ['serverType', 'userInfo', 'seqId', 'serverId']), { roleName: role.roleId });
    delete update._id;
    await RoleModel.updateMany({ roleId }, { $set: update });
    return true;
}