
import { scheduleJob, Job, scheduledJobs, } from 'node-schedule';
import { PVPConfigModel, PVPConfigType } from '../db/SystemConfig';
import { nowSeconds, getTimeFun, getSeconds } from '../pubUtils/timeUtil';
import { getTodayGuildActivity, gameData } from '../pubUtils/data';
import { pvpSeasonEnd } from './pvpService';
import { getAllOnlineRoles, getAllServers, delGuildActivityRank } from './redisService';
import { GUILD_ACTIVITY_TYPE, REFRESH_TIME, SEND_NAME, SERVER_OPEN_TIME, COUNTER, AUCTION_TIME, GM_MAIL_TYPE, SERVER_STATUS, SERVER_TIMER } from '../consts';
import { RoleModel } from '../db/Role';
import { pinus } from 'pinus';
import { indexOf } from 'underscore';
import { PvpSeasonResultModel } from '../db/PvpSeasonResult';
import { settleGuildWeekly } from './guildService';
import { sendMailByContent, SendMailFun } from './mailService';
import { getGuildActivityByDic, sendEndMsgToAll, autoDeclare, sendGuildActivityStatus } from './guildActivityService';
import { sendUngotDividendJob, startGuildAuction, startWorldAuction, stopAuction } from './auctionService';
import { DicGuildActivity } from '../pubUtils/dictionary/DicGuildActivity';
import { dispatch } from '../pubUtils/dispatcher';
import { Rank } from './rankService';
import { checkTask } from './taskService';
import { everydayRefresh } from './connectorService';
import { createNewServer, initMarquee } from './gmService';
import moment = require('moment');
import { CounterModel } from '../db/Counter';
import { reportOneOnline } from './authenticateService';
import { PVP } from '../pubUtils/dicParam';
import { fetch37Words } from './sdkService';
import { GMMailModel } from '../db/GMMail';
import { Maintenance, ServerlistModel, ServerlistType, ServerlistUpdate } from '../db/Serverlist';
import { getWorldChannelSid } from './chatService';
import { createMarqueeMsg, pushMarqueeMsg } from './sysChatService';
import { RegionModel, RegionType } from '../db/Region';
import { CreateServerParam } from '../domain/backEndField/params';

const PER_SECOND = 1 * 1000;
const PER_DAY = 24 * 60 * 60;
const PER_HOUR = 1 * 60 * 60;
const PER_MINUTE = 1 * 60;
var seasonMakeRewardTimJobId: Job;
var seasonRefreshTimeJobId: Job;
let guildWeeklyJobId: Job;
let guildActStartJobId: Job; // 军团活动开启后每10(or 1)秒循环的定时任务，到结束活动清除
let guildActSecondsJobId: Job; // 军团活动开启后每10(or 1)秒循环的定时任务，到结束活动清除
let guildActEndJobId: Job; // 军团活动开启后每10(or 1)秒循环的定时任务，到结束活动清除

/**
 * 初始定时器
 */
export async function init() {

    console.log('******* init systimer *******')

    // pvp赛季
    await setPvpSeason();

    // 周功勋结算任务
    guildWeeklyJobId = scheduleJob('settleGuildWeekly', '0 0 ? * * 1', settleGuildWeekly);

    // 每5分钟汇报在线玩家在线情况
    scheduleJob('reportOnline', '0 0/5 * * * *', reportOnlineSchedule);

    // 每天拉取37词库
    scheduleJob('fetchWord', '0 0 4 * * ?', fetch37Words);

    // 每天邮件
    scheduleJob('circleMail', '0 0 3 * * ?', sendCircleMail);

    // 军团活动排行榜
    guildActivitySchedule();

    // 拍卖行刷新：拍卖阶段刷新，分红发放
    auctionSchedule();

    // 每天5点推送刷新时间消息
    // 顺便每天0点计算前一天活跃玩家中位数战力
    scheduleJob('everyDayRefresh', `0 0 ${REFRESH_TIME} * * ?`, everydayRefresh);

    // 跑马灯
    await initMarquee();

    // 维护信息
    await initMaintenance();

    // 自动开服
    await initAutoCreateServer();
}

// —————————————— PVP 及赛季相关 —————————————— //
function getSeasonContinueDay(seasonNum: number) {
    const pvpSeasonDuring = PVP.PVP_SEASON_DAYS.split('|').map(cur => {
        let arr = cur.split('&');
        let seasonNum = parseInt(arr[0]);
        let day = parseInt(arr[1]);
        if(isNaN(seasonNum) || isNaN(day)) return null;
        return { seasonNum, day }
    }).filter(cur => !!cur);

    let maxDay = 0;
    for(let {seasonNum: dicSeasonNum, day } of pvpSeasonDuring) {
        if(seasonNum == dicSeasonNum) return day;
        if(maxDay < day) maxDay = day;
    }
    return maxDay;
}

async function setPvpSeasonJob() {
    await setPvpSeason();
}

async function setPvpSeason(isForce?: boolean, minute?: number) {
    console.log(`******** setPvpSeason1： isForce-${isForce}, minute-${minute}`)

    let during = minute? minute * PER_MINUTE: null; // 下一次重置赛季天数
    let oldPvpConfig = await PVPConfigModel.findCurPVPConfig();
    let pvpConfig = oldPvpConfig;
    console.log(`******** setPvpSeason2： during-${during}, seasonEndTime-${pvpConfig?.seasonEndTime}, now-${nowSeconds()}`)
    if(!pvpConfig || pvpConfig.seasonEndTime - PER_MINUTE <= nowSeconds() || isForce) {
        if(pvpConfig && !pvpConfig.hasSettleReward) {
            await pvpSeasonEnd(pvpConfig.seasonNum);
        }

        let lastSeasonNum = pvpConfig? pvpConfig.seasonNum: 0;
        let lastSeasonEndTime = pvpConfig? pvpConfig.seasonEndTime: 0;
        console.log(`******** setPvpSeason3： lastSeasonNum-${lastSeasonNum}, lastSeasonEndTime-${lastSeasonEndTime}`)

        let newSeasonStartTime = lastSeasonEndTime;
        if(!during) during = getSeasonContinueDay(lastSeasonNum + 1) * PER_DAY;
        let rewardTime = PVP.PVP_SEASON_REWARD_TIME_BEFORE * PER_MINUTE;
        if(nowSeconds() - newSeasonStartTime > during) {
            newSeasonStartTime = <number>getTimeFun().getDayZeroPoint(0);
        }
        console.log(`******** setPvpSeason4： newSeasonStartTime-${newSeasonStartTime}, during-${during}`)

        if(isForce) { // debug使用，如果seasonEndTime是未来的，强行结束掉，新赛季从现在开始
            newSeasonStartTime = nowSeconds();
        } else { // 不是用debug的情况，如果（因为debug）newSeasonStartTime不是每天0点结算，那么改成lastSeasonEndTime之后的0点开始
            let d = new Date(newSeasonStartTime * 1000);
            if(d.getHours() != 0) {
                d.setHours(0, 0, 0, 0);
                newSeasonStartTime = getSeconds(d);
            }
        }
        console.log(`******** setPvpSeason5： isForce-${isForce}, newSeasonStartTime-${newSeasonStartTime}`)
        let newSeasonNum = await CounterModel.getNewCounter(COUNTER.PVP_SEASON_NUM);
        pvpConfig = await PVPConfigModel.createPVPConfig(newSeasonNum, newSeasonStartTime, newSeasonStartTime + during - rewardTime, newSeasonStartTime + during);
    }
    await setPvpSeasonMakeRewardJob(pvpConfig);
    await setNextSeasonJob(pvpConfig);
    setPvpSeasonNum(pvpConfig);
    return pvpConfig;
}

function setPvpSeasonNum(pvpConfig: PVPConfigType) {
    if(pvpConfig) {
        pinus.app.set('pvpSeasonNum', pvpConfig.seasonNum);
        pinus.app.set('pvpSeasonEndTime', pvpConfig.seasonEndTime);
        pinus.app.rpc.battle.battleRemote.setPvpSeasonNum.broadcast(pvpConfig);
        pinus.app.rpc.role.roleRemote.setPvpSeasonNum.broadcast(pvpConfig);
        pinus.app.rpc.connector.connectorRemote.setPvpSeasonNum.broadcast(pvpConfig);
    }
}

async function setPvpSeasonMakeRewardJob(pvpConfig: PVPConfigType) {
    if (!!seasonMakeRewardTimJobId) {
        seasonMakeRewardTimJobId.cancel();
    }
    if(!pvpConfig) return;
    if(pvpConfig.seasonRewardTime < nowSeconds() && !pvpConfig.hasSettleReward) { // 未发奖励
        await pvpSeasonEnd(pvpConfig.seasonNum);
    } else {
        seasonMakeRewardTimJobId = scheduleJob('seasonMakeRewardTimJobId', pvpConfig.seasonRewardTime * 1000, async () => {
            console.log('************ seasonMakeRewardTimJobId *********');
            await pvpSeasonEnd(pvpConfig.seasonNum);
        });
    }
}

async function setNextSeasonJob(pvpConfig: PVPConfigType) {
    if (!!seasonRefreshTimeJobId) {
        seasonRefreshTimeJobId.cancel();
    }
    //定时开启新赛季，比seasonEndTime多定一分钟，保证定时器时间没错
    seasonRefreshTimeJobId = scheduleJob('seasonRefreshTimeJobId', (pvpConfig.seasonEndTime) * 1000, setPvpSeasonJob);
}

/**
 * debug接口
 * @param hour 
 */
export async function resetPvpSeasonTime(minute: number) {
    return await setPvpSeason(true, minute);
}

export async function reportOnlineSchedule() {
    let allRoles = await getAllOnlineRoles();
    console.log('reportOnlineSchedule all roles count: ', allRoles.length)
    for (let { roleId, userCode, sid } of allRoles) {
        let result = reportOneOnline(roleId, userCode, sid, false);
        if (!result) continue;
    }
}

// —————————————— PVP 及赛季相关 end —————————————— //

// —————————————— 军团活动 —————————————— //
/**
 * 军团活动，每晚8点开启
 */
export async function guildActivitySchedule() {
    /***********guildActivitySchedule***********/
    if (guildActStartJobId) {
        guildActStartJobId.cancel();
    }

    let dicGuildActivity = getTodayGuildActivity();
    await delGuildActivityRank(dicGuildActivity.id);

    // console.log(dicGuildActivity)

    guildActStartJobId = scheduleJob('guildActivityStart', `${dicGuildActivity.startSeconds} ${dicGuildActivity.startMinute} ${dicGuildActivity.startTime} * * ?`, guildActivityStartSchedule);
}

// 军团晚间活动，每天8点开始
async function guildActivityStartSchedule() {
    await guildActivityStart();
}

export async function guildActivityStart(dicGuildActivity?: DicGuildActivity) {
    console.log('*******开始军团晚间活动****')
    if (!dicGuildActivity) dicGuildActivity = getTodayGuildActivity();
    if (!dicGuildActivity) return;

    console.log('********', dicGuildActivity.id, Date.now() + dicGuildActivity.duringTime * 1000)
    let servers = await getAllServers(); // 玩家serverId列表
    console.log('****** guildActSecondsJobId', guildActSecondsJobId)
    if (guildActSecondsJobId) {
        guildActSecondsJobId.cancel();
        guildActSecondsJobId = undefined;
    }
    if (guildActEndJobId) {
        guildActEndJobId.cancel();
        guildActEndJobId = undefined;
    }
    if (dicGuildActivity.id == GUILD_ACTIVITY_TYPE.GATE_ACTIVITY) {
        guildActSecondsJobId = scheduleJob('guildActivitySeconds', '*/10 * * * * *', gateActivitySeconds);
        // 结束时间
        guildActEndJobId = scheduleJob('guildActivityEnd', Date.now() + dicGuildActivity.duringTime * 1000, gateActivityEnd);
    } else if (dicGuildActivity.id == GUILD_ACTIVITY_TYPE.CITY_ACTIVITY) {
        guildActSecondsJobId = scheduleJob('guildActivitySeconds', '*/10 * * * * *', cityActivitySeconds);
        // 结束时间
        guildActEndJobId = scheduleJob('guildActivityEnd', Date.now() + dicGuildActivity.duringTime * 1000, cityActivityEnd);
    } else if (dicGuildActivity.id == GUILD_ACTIVITY_TYPE.RACE_ACTIVITY) {

        // 开始活动
        let guildServers = pinus.app.getServersByType('guild');
        for (let serverId of servers) {
            let sid = dispatch(serverId.toString(), guildServers, 'guild');
            await pinus.app.rpc.guild.guildActivityRemote.raceActivityStart.toServer(sid.id, serverId);
        }

        guildActSecondsJobId = scheduleJob('guildActivitySeconds', '*/2 * * * * *', raceActivitySeconds);
        // 结束时间
        guildActEndJobId = scheduleJob('guildActivityEnd', Date.now() + dicGuildActivity.duringTime * 1000, raceActivityEnd);
    }

    for (let serverId of servers) {
        await sendGuildActivityStatus(serverId);
    }
    return true;
}

// 蛮夷入侵
// 结束军团活动
export async function gateActivityEnd() {

    console.log('*****gateActivityEnd');
    await sendEndMsgToAll();
    await pinus.app.rpc.guild.guildActivityRemote.guildActivityEnd.broadcast(GUILD_ACTIVITY_TYPE.GATE_ACTIVITY);

    if (guildActSecondsJobId) {
        guildActSecondsJobId.cancel();
        guildActSecondsJobId = undefined;
    }
    if (guildActEndJobId) {
        guildActEndJobId.cancel();
        guildActEndJobId = undefined;
    }
}

// 每10秒下发一次的任务
export async function gateActivitySeconds() {
    console.log('*****gateActivitySeconds')
    await pinus.app.rpc.guild.guildActivityRemote.sendRankToGuilds.broadcast(GUILD_ACTIVITY_TYPE.GATE_ACTIVITY);
}

// 诸侯混战
// 结束军团活动
export async function cityActivityEnd() {
    console.log('*****cityActivityEnd');
    await sendEndMsgToAll();
    await pinus.app.rpc.guild.guildActivityRemote.guildActivityEnd.broadcast(GUILD_ACTIVITY_TYPE.CITY_ACTIVITY);

    // 发完之后再做下周自动宣战
    let serverlists = await getAllServers();
    for (let serverId of serverlists) {
        await autoDeclare(serverId);
    }
    if (guildActSecondsJobId) {
        guildActSecondsJobId.cancel();
        guildActSecondsJobId = undefined;
    }
    if (guildActEndJobId) {
        guildActEndJobId.cancel();
        guildActEndJobId = undefined;
    }
}

// 每10秒下发一次的任务
export async function cityActivitySeconds() {
    console.log('*****cityActivitySeconds')
    await pinus.app.rpc.guild.guildActivityRemote.sendRankToGuilds.broadcast(GUILD_ACTIVITY_TYPE.CITY_ACTIVITY);
}

// 粮草先行
// 结束军团活动
export async function raceActivityEnd() {
    console.log('*****raceActivityEnd');
    await sendEndMsgToAll();
    await pinus.app.rpc.guild.guildActivityRemote.guildActivityEnd.broadcast(GUILD_ACTIVITY_TYPE.RACE_ACTIVITY);

    if (guildActSecondsJobId) {
        guildActSecondsJobId.cancel();
        guildActSecondsJobId = undefined;
    }
    if (guildActEndJobId) {
        guildActEndJobId.cancel();
        guildActEndJobId = undefined;
    }
}

// 每10秒下发一次的任务
export async function raceActivitySeconds() {
    console.log('*****raveActivitySeconds')
    let servers = await getAllServers(); // 玩家serverId列表
    let guildServers = pinus.app.getServersByType('guild');
    for (let serverId of servers) {
        let sid = dispatch(serverId.toString(), guildServers, 'guild');
        await pinus.app.rpc.guild.guildActivityRemote.calWoodenHorseAndSend.toServer(sid.id, serverId);
    }
}

// —————————————— 军团活动 end —————————————— //

// —————————————— 拍卖行 —————————————— //

let startGuildAuctionJobId: Job;
let startWorldAuctionJobId: Job;
let stopAuctionJobId: Job;
let sendUngotDividendJobId: Job;

export function auctionSchedule() {
    clearAuctionSchedule();
    let guildOpen = gameData.auctionTime.get(AUCTION_TIME.GUILD_OPEN);
    let worldOpen = gameData.auctionTime.get(AUCTION_TIME.WORLD_OPEN);
    let worldClose = gameData.auctionTime.get(AUCTION_TIME.WORLD_CLOSE);

    console.log('***** auctionSchedule', guildOpen.hour, guildOpen.minute, guildOpen.seconds);
    console.log('***** auctionSchedule', worldOpen.hour, worldOpen.minute, worldOpen.seconds);
    console.log('***** auctionSchedule', worldClose.hour, worldClose.minute, worldClose.seconds);
    startGuildAuctionJobId = scheduleJob('startGuildAuction', `${guildOpen.seconds} ${guildOpen.minute} ${guildOpen.hour} * * ?`, startGuildAuction);
    startWorldAuctionJobId = scheduleJob('startWorldAuction', `${worldOpen.seconds} ${worldOpen.minute} ${worldOpen.hour} * * ?`, startWorldAuction);
    stopAuctionJobId = scheduleJob('stopAuction', `${worldClose.seconds} ${worldClose.minute} ${worldClose.hour} * * ?`, stopAuction);
    sendUngotDividendJobId = scheduleJob('sendUngotDividendJob', '0 0 5 00 * ?', sendUngotDividendJob);

}

function clearAuctionSchedule() {
    if (startGuildAuctionJobId) {
        startGuildAuctionJobId.cancel();
        startGuildAuctionJobId = undefined;
    }
    if (startWorldAuctionJobId) {
        startWorldAuctionJobId.cancel();
        startWorldAuctionJobId = undefined;
    }
    if (stopAuctionJobId) {
        stopAuctionJobId.cancel();
        stopAuctionJobId = undefined;
    }
    if (sendUngotDividendJobId) {
        sendUngotDividendJobId.cancel();
        sendUngotDividendJobId = undefined;
    }
}

// —————————————— 拍卖行 end —————————————— //

// —————————————— 邮件 —————————————— //
async function sendCircleMail() {
    let gmmails = await GMMailModel.findCircleMails(pinus.app.get('env'));
    for(let gmmail of gmmails) {
        let { receivers, mailType } = gmmail;
        let f = new SendMailFun();
        await f.setWithGmMail(gmmail);

        if (mailType == GM_MAIL_TYPE.SINGLE || mailType == GM_MAIL_TYPE.GROUP) {
            let roleIds = receivers.map(cur => cur.roleId);
            await f.sendToUsers(mailType, roleIds);
        } else {
            let serverIds = receivers.map(cur => cur.serverId);
            await f.sendToServer(serverIds);
        }
    }
}

// —————————————— 邮件 end —————————————— //

// —————————————— 维护 —————————————— //
let maintenInfos = new Map<string, { servers: ServerlistType[], maintenance: Maintenance }>(); // batchCode => {servers, maintenance}
export async function initMaintenance(servers?: ServerlistType[]) {
    if(!servers) servers = await ServerlistModel.findByEnv(pinus.app.get('env'));

    for(let server of servers) {
        let { maintenance } = server;
        if(maintenance && maintenance.isOpen) {
            if(!maintenInfos.has(maintenance.batchCode)) {
                maintenInfos.set(maintenance.batchCode, { servers: [], maintenance });
            }
            maintenInfos.get(maintenance.batchCode).servers.push(server);
        }
    }
    for(let [batchCode] of maintenInfos) {
        await setMaintenance(batchCode);
    }
}

// 设置维护
async function setMaintenance(batchCode: string) {
    let { maintenance } = maintenInfos.get(batchCode);
    let now = nowSeconds();
    // 发送消息
    if(maintenance.hasNotify && now < maintenance.startTime) {
        if(now > maintenance.startTime - 5 * 60) {
            maintenanceNotifySchedule(batchCode);
        } else {
            scheduleJob(`maintenNotify${batchCode}`, maintenance.startTime - 5 * 60, () => {
                maintenanceNotifySchedule(batchCode);
            })
        }
    } else {
        if(scheduledJobs[`maintenNotify${batchCode}`]) scheduledJobs[`maintenNotify${batchCode}`].cancel();
    }
    // 开始维护
    console.log('******* setMaintenance', now, now < maintenance.endTime, now > maintenance.startTime)
    if(now < maintenance.endTime) {
        if(now > maintenance.startTime) {
            console.log('*******')
            await startMaintenanceSchedule(batchCode);
        } else {
            scheduleJob(`startMainten${batchCode}`, maintenance.startTime * 1000, async () => {
                await startMaintenanceSchedule(batchCode);
            });
        }
    } else {
        if(scheduledJobs[`startMainten${batchCode}`]) scheduledJobs[`startMainten${batchCode}`].cancel();
    }

}

// 维护前通知
async function maintenanceNotifySchedule(batchCode: string) {
    let { servers, maintenance } = maintenInfos.get(batchCode);
    if(scheduledJobs[`maintenNotify${batchCode}`]) scheduledJobs[`maintenNotify${batchCode}`].cancel();
    if(scheduledJobs[`maintenSec${batchCode}`]) scheduledJobs[`maintenSec${batchCode}`].cancel();

    scheduleJob(`maintenSec${batchCode}`, `0 */1 * * * *`, async () => {
        for(let { id: serverId } of servers) {
            let msgData = await createMarqueeMsg('', '系统', serverId, '服务器即将维护，请玩家提前退出游戏');
            await pushMarqueeMsg(msgData);
        }
    })
}

// 开始维护
async function startMaintenanceSchedule(batchCode: string) {
    let { servers, maintenance } = maintenInfos.get(batchCode);
    let serverIds = servers.map(cur => cur.id);
    if(scheduledJobs[`maintenNotify${batchCode}`]) scheduledJobs[`maintenNotify${batchCode}`].cancel();
    if(scheduledJobs[`maintenSec${batchCode}`]) scheduledJobs[`maintenSec${batchCode}`].cancel();
    if(scheduledJobs[`startMainten${batchCode}`]) scheduledJobs[`startMainten${batchCode}`].cancel();

    // 向全服发送
    for(let { id: serverId } of servers) {
        let chatSid = await getWorldChannelSid(serverId);
        if(chatSid) {
            await pinus.app.rpc.chat.chatRemote.sendServerMaintenance.toServer(chatSid, serverId);
        }
    }
    
    // 更新connectorRemote里面的维护服务器
    console.log('******** startMaintenanceSchedule', batchCode, serverIds, maintenance.startTime, maintenance.endTime)
    pinus.app.rpc.connector.connectorRemote.setServerMainten.broadcast(serverIds, maintenance.startTime, maintenance.endTime);
    pinus.app.rpc.activity.activityRemote.setServerMainten.broadcast(serverIds, maintenance.startTime, maintenance.endTime);
    pinus.app.rpc.battle.battleRemote.setServerMainten.broadcast(serverIds, maintenance.startTime, maintenance.endTime);
    pinus.app.rpc.chat.chatRemote.setServerMainten.broadcast(serverIds, maintenance.startTime, maintenance.endTime);
    pinus.app.rpc.guild.guildRemote.setServerMainten.broadcast(serverIds, maintenance.startTime, maintenance.endTime);
    pinus.app.rpc.order.orderRemote.setServerMainten.broadcast(serverIds, maintenance.startTime, maintenance.endTime);
    pinus.app.rpc.role.roleRemote.setServerMainten.broadcast(serverIds, maintenance.startTime, maintenance.endTime);
    // 数数flush
    pinus.app.rpc.activity.activityRemote.taflush.broadcast();
    pinus.app.rpc.battle.battleRemote.taflush.broadcast();
    pinus.app.rpc.chat.chatRemote.taflush.broadcast();
    pinus.app.rpc.connector.connectorRemote.taflush.broadcast();
    pinus.app.rpc.guild.guildRemote.taflush.broadcast();
    pinus.app.rpc.order.orderRemote.taflush.broadcast();
    pinus.app.rpc.role.roleRemote.taflush.broadcast();
    pinus.app.rpc.systimer.systimerRemote.taflush.broadcast();
}

// 提前结束维护
export async function stopMaintenance(batchCode: string, serverIds: number[]) {
    // console.log('***********', serverIds)
    let { servers = [], maintenance = {} as Maintenance } = maintenInfos.get(batchCode)||{};
    for(let id of serverIds) {
        let index = servers.findIndex(cur => cur.id == id);
        if(index != -1) servers.splice(index);
    }
    if(servers.length == 0) {
        if(scheduledJobs[`maintenNotify${batchCode}`]) scheduledJobs[`maintenNotify${batchCode}`].cancel();
        if(scheduledJobs[`maintenSec${batchCode}`]) scheduledJobs[`maintenSec${batchCode}`].cancel();
        if(scheduledJobs[`startMainten${batchCode}`]) scheduledJobs[`startMainten${batchCode}`].cancel();
        maintenInfos.delete(batchCode);
    }

    // 更新connectorRemote里面的维护服务器
    pinus.app.rpc.connector.connectorRemote.stopServerMainten.broadcast(serverIds);
    pinus.app.rpc.activity.activityRemote.stopServerMainten.broadcast(serverIds);
    pinus.app.rpc.battle.battleRemote.stopServerMainten.broadcast(serverIds);
    pinus.app.rpc.chat.chatRemote.stopServerMainten.broadcast(serverIds);
    pinus.app.rpc.guild.guildRemote.stopServerMainten.broadcast(serverIds);
    pinus.app.rpc.order.orderRemote.stopServerMainten.broadcast(serverIds);
    pinus.app.rpc.role.roleRemote.stopServerMainten.broadcast(serverIds);
}

// —————————————— 维护 end —————————————— //
// —————————————— 自动开服 —————————————— //
export async function initAutoCreateServer(region?: RegionType) {
    if(!region) region = await RegionModel.findRegionByEnv(pinus.app.get('env'));
    if(region && region.stategy) {
        for(let timer of region.stategy.timers) {
            setStategyTimer(timer, region)
        }
    }
}

function setStategyTimer(timerId: number, region: RegionType) {
    if(scheduledJobs[`autoServer${timerId}`]) scheduledJobs[`autoServer${timerId}`].cancel();
    let cron = '';
    switch(timerId) {
        case SERVER_TIMER.FIVE_HALF:
            cron = '0 30 5 * * *'; break;
        case SERVER_TIMER.TEN_HALF:
            cron = '0 30 10 * * *'; break;
        case SERVER_TIMER.FIFTEEN_HALF:
            cron = '0 30 15 * * *'; break;
        case SERVER_TIMER.NINETEEN_HALF:
            cron = '0 30 19 * * *'; break;
    }
    if(cron) {
        scheduleJob(`autoServer${timerId}`, cron, () => {
            autoCreateServerSchedule(region);
        })
    }
}

async function autoCreateServerSchedule(region: RegionType) {
    console.log('******* createNewServer *******')
    let latestServer = await ServerlistModel.findByServerId(region.latestServerUniqId);
    if(!latestServer || latestServer.playerCnt >= region.stategy.maxPlayerCnt) {
        let params = new CreateServerParam();
        params.setByRegionStategy(region, nowSeconds())
        await createNewServer(region, (latestServer?.serverId||0) + 1, params);
    }
}
// —————————————— 自动开服 end —————————————— //