import {Application, BackendSession, pinus} from 'pinus';
import { RoleModel } from '../../../db/Role';
import { EventRecordModel } from '../../../db/EventRecord';
import { getEvent } from '../../../services/eventSercive';
import { resResult } from '../../../pubUtils/util';
import { STATUS } from '../../../consts/statusCode';
import { GMMailModel } from '../../../db/GMMail';
import { setGmMails } from '../../../pubUtils/gmData/gmDataUtil';
import { getRoleOnlineInfo } from '../../../services/redisService';
import { dispatch } from '../../../util/dispatcher';
import { SendMailFun } from '../../../services/mailService';
import { GM_MAIL_TYPE } from '../../../consts';
import { RewardInter } from '../../../pubUtils/interface';
export default function(app: Application) {
    return new GmHandler(app);
}

export class GmHandler {
    constructor(private app: Application) {
    }

    async pushEvent(msg: { uid: number, serverId: number }, session: BackendSession) {
        let sid = session.get('sid');

        let { uid, serverId } = msg;
        let role = await RoleModel.findByUid(uid, serverId);
        if(!role) return resResult(STATUS.GM_ROLE_NOT_FOUND);
        let {roleId, roleName, eventStatus } = role;

        let channelService = this.app.get('channelService');
        let channel = channelService.getChannel(roleId, true);
        let users = channel.getMembers();
        if (users.indexOf(roleId) === -1) {
            channel.add(roleId, sid);
        }

        let event = await getEvent(eventStatus, roleId, roleName);

        let tsid = channel.getMember(roleId)['sid'];
        channelService.pushMessageByUids('onSpecialEvent', resResult(STATUS.SUCCESS, { event }), [{
            uid: roleId,
            sid: tsid
        }]);
        return resResult(STATUS.SUCCESS, { list: event });
    }

    async clearEvent(msg: { }, session: BackendSession) {
        let roleId = session.get('roleId');
        
        await EventRecordModel.deleteAccount(roleId);
        return resResult(STATUS.SUCCESS);
    }


    async pushMessage(msg: { uid: number, serverId: number, eventName: string, message: string }, session: BackendSession) {

        let { uid, serverId, eventName, message } = msg;

        let content = {};
        try {
            content = JSON.parse(message);
        } catch(e) {
            return resResult(STATUS.GM_JSON_FORMAT_ERR);
        }
        console.log(uid, serverId)
        let role = await RoleModel.findByUid(uid, serverId);
        if(!role) return resResult(STATUS.GM_ROLE_NOT_FOUND);
        let { roleId } = role;

        let hisOnlineInfo = await getRoleOnlineInfo(role.roleId);
        if(hisOnlineInfo.isOnline) {
            let sid = hisOnlineInfo.sid;
            if (!!sid) {//下发邮件，对应前端红点提示
                pinus.app.channelService.pushMessageByUids(eventName, resResult(STATUS.SUCCESS, content), [{uid: roleId, sid}]);
            }
        }
        return resResult(STATUS.SUCCESS, { msg: content });
    }

    //对接gm后台，下发邮件
    async addMail(msg: { endTime: number, sendName: string, content: string, goods: RewardInter[], sendTime: number }) {
        let {endTime, content, sendName, sendTime, goods } = msg;
        let mail = await GMMailModel.addMail({endTime, content, sendName, sendTime, goods});
        return resResult(STATUS.SUCCESS, { mail });
    }

    async sendMail(msg: { id: string, mailType: number, roleIds?: string[], serverIds?: number[] }, session: BackendSession) {
        const uid: number = session.get('uid')
        let { id, mailType, roleIds, serverIds } = msg;
        let f = new SendMailFun();
        await f.setWithGmMail(id);
        if(mailType == GM_MAIL_TYPE.SINGLE || mailType == GM_MAIL_TYPE.GROUP) {
            await f.sendToUsers(mailType, roleIds);
        } else {
            await f.sendToServer(serverIds);
        }
        await f.saveRecord(uid);
        return resResult(STATUS.SUCCESS);
    }

    async sendWithContent(msg: { contentId: number, mailType: number, params: { params?: string[], sendName?: string, goods?: RewardInter[], endTime?: number}, roleIds?: string[], serverIds?: number[] }, session: BackendSession) {
        let { contentId, mailType, roleIds, serverIds, params } = msg;
        let f = new SendMailFun();
        f.setWithContentId(contentId, params);
        if(mailType == GM_MAIL_TYPE.SINGLE || mailType == GM_MAIL_TYPE.GROUP) {
            await f.sendToUsers(mailType, roleIds);
        } else {
            await f.sendToServer(serverIds);
        }
        return resResult(STATUS.SUCCESS);
    }

    async reloadResource(msg: {}, session: BackendSession) {
        try {
            let activityServers = this.app.getServersByType('activity');
            for(let { id } of activityServers) {
                await this.app.rpc.activity.activityRemote.reloadResources.toServer(id);
            }
            let battleServers = this.app.getServersByType('battle');
            for(let { id } of battleServers) {
                await this.app.rpc.battle.battleRemote.reloadResources.toServer(id);
            }
            let chatServers = this.app.getServersByType('chat');
            for(let { id } of chatServers) {
                await this.app.rpc.chat.chatRemote.reloadResources.toServer(id);
            }
            let connectServers = this.app.getServersByType('connector');
            for(let { id } of connectServers) {
                await this.app.rpc.connector.connectorRemote.reloadResources.toServer(id);
            }
            let guildServers = this.app.getServersByType('guild');
            for(let { id } of guildServers) {
                await this.app.rpc.guild.guildRemote.reloadResources.toServer(id);
            }
            let roleServers = this.app.getServersByType('role');
            for(let { id } of roleServers) {
                await this.app.rpc.role.roleRemote.reloadResources.toServer(id);
            }
            let systimerServers = this.app.getServersByType('systimer');
            for(let { id } of systimerServers) {
                await this.app.rpc.systimer.systimerRemote.reloadResources.toServer(id);
            }
            let orderServers = this.app.getServersByType('order');
            for(let { id } of orderServers) {
                await this.app.rpc.order.orderRemote.reloadResources.toServer(id);
            }
            return resResult(STATUS.SUCCESS, {
                isOK: true
            });
        } catch(e) {
            return resResult(STATUS.SUCCESS, {
                isOK: false,
                err: e.stack
            });
        }
    }
}