import {Application, RouteRecord, FrontendOrBackendSession, HandlerCallback, pinus, FrontendSession} from "pinus";
// import { checkEvent } from '../../../services/eventSercive';
import { refresh } from '../../../services/refreshService';
import { checkPrivateChat, checkGuildChat, checkOtherChat, checkRoleName, checkGuildName } from "../../../services/sdkService";
import { resResult, checkWhiteList, genCode } from "../../../pubUtils/util";
import { ACCESS_FREQUENCY, BLOCK_TYPE, CHANNEL_PREFIX, MSG_TYPE, STATUS } from "../../../consts";
import { UserModel } from "../../../db/User";
import { SERVER_DEBUG_MODE } from "../../../pubUtils/dicParam";
import { nowSeconds } from "../../../pubUtils/timeUtil";
import { getServerMainten } from "../../../services/gmService";
// import { errlogger } from "../../../util/logger";
export function globalFilter(app: Application) {
    return new Filter(app);
}

var Filter = function(this: any, app: Application) {
    this.app = app;
    this.accessTime = new Map<string, number>();
};

Filter.prototype.before = async function (routeRecord: RouteRecord, msg: any, session: FrontendOrBackendSession, next: HandlerCallback) {
    const serverId: number = session.get('serverId');
    const sid: string = session.get('sid');
    const roleId: string = session.get('roleId');
    const uid: number = session.get('userid');
    const ip: string = session.get('ip');
    console.log('*********** global before ip', ip)
    let guildCode = session.get('guildCode');
    let blockType = session.get('blockType');
    // 访问频率控制
    let keyOfRouteWithUser = `${routeRecord.route}_${roleId}`;
    if(this.accessTime && this.accessTime.has(keyOfRouteWithUser)) {
        console.log(this.accessTime.get(keyOfRouteWithUser) - Date.now());
        if(Date.now() - this.accessTime.get(keyOfRouteWithUser) < ACCESS_FREQUENCY) {
            // errlogger.error(`${keyOfRouteWithUser} 间隔时间小于${ACCESS_FREQUENCY}ms，为 ${Date.now() - this.accessTime.get(keyOfRouteWithUser)}`);
            // return next(new Error(), resResult(STATUS.ACCESS_BUSY));
        }
    }
    if(!this.accessTime) this.accessTime = new Map<string, number>();
    this.accessTime.set(keyOfRouteWithUser, Date.now());
    // 玩家屏蔽
    if(blockType == BLOCK_TYPE.BLOCK) return next(new Error(), resResult(STATUS.BLOCKED));
    if(blockType == BLOCK_TYPE.BAN) {
        if([
            'chat.chatHandler.sendPrivateMessage',
            'chat.chatHandler.sendGroupMessage',
            'battle.barrageHandler.sendBarrage',
            'guild.guildHandler.sendMail',
            'guild.guildHandler.setGuildInfo',
        ].indexOf(routeRecord.route) != -1) {
            return next(new Error(), resResult(STATUS.BANNED));
        }
    }

    session.push('teamCode', () => {});

    if(sid) {
        const mainten = getServerMainten(serverId);
        if(mainten) { // 该服务器维护
            if(mainten.startTime > nowSeconds() || mainten.endTime < nowSeconds()) return next(null)

            let isWhiteList = await checkWhiteList(this.app.get('env'), ip, uid, serverId);
            if(isWhiteList) return next(null);
    
            pinus.app.get('channelService').pushMessageByUids('onServerMaintenance', resResult(STATUS.SERVER_MAINTENANCE), [{ uid: roleId, sid }]);
            return next(new Error(), resResult(STATUS.SERVER_MAINTENANCE));
        }
    }

    let hasBlockWords = false;
    if(SERVER_DEBUG_MODE.CHECK_WORD == 1) {
        switch(routeRecord.route) {
            case 'chat.chatHandler.sendPrivateMessage':
                {
                    if(msg.type == MSG_TYPE.IMG) break;
                    let result = await checkPrivateChat(roleId, msg.targetRoleId, msg.content);
                    if(!result) hasBlockWords = true; 
                    break;
                }
            case 'chat.chatHandler.sendGroupMessage':
                {
                    if(msg.type == MSG_TYPE.IMG) break;
                    if(msg.channel == CHANNEL_PREFIX.GUILD) {
                        let result = await checkGuildChat(roleId, guildCode, msg.content);
                        if(!result) hasBlockWords = true; 
                        break;
                    } else {
                        let result = await checkOtherChat(roleId, msg.channel, msg.content);
                        if(!result) hasBlockWords = true; 
                        break;
                    }
                }
            case 'battle.barrageHandler.sendBarrage':
                {
                    let result = await checkOtherChat(roleId, CHANNEL_PREFIX.WORLD, msg.content);
                    if(!result) hasBlockWords = true; 
                    break;
                }
            case 'guild.guildHandler.sendMail':
                {
                    let result = await checkGuildChat(roleId, guildCode, msg.info);
                    if(!result) hasBlockWords = true; 
                    break;
                }
            case 'role.roleHandler.rename':
            case 'role.roleHandler.initRole':
                {
                    let result = await checkRoleName(roleId, msg.roleName);
                    if(!result) hasBlockWords = true; 
                    break;
                }
            case 'guild.guildHandler.createGuild':
            case 'guild.guildHandler.setGuildInfo':
                {
                    if(!guildCode) {
                        guildCode = genCode(6);
                        msg.guildCode = guildCode;
                    }
                    let result = await checkGuildName(guildCode, serverId, msg.name, msg.notice);
                    if(!result) hasBlockWords = true; 
                    break;
                }
        }
    }

    if(hasBlockWords) return next(new Error(), resResult(STATUS.BLOCK_WORDS));

    next(null);
};

Filter.prototype.after = async function (err: Error, routeRecord: RouteRecord, msg: any, session: FrontendOrBackendSession, resp: any, next: HandlerCallback) {
    //刷新
    await refresh(session);
    // return checkEvent(session).then(()=>{
    //     next(err);
    // }).catch(e => {
    //     console.error(e);
    //     next(err);
    // });    // 奇遇本检查
    next(null);
};