import { CLIENT_VERSION, STATUS } from '@consts';
import { GameModel } from '@db/Game';
import { Controller } from 'egg';
import { RoleModel } from '@db/Role';
import { NoticeModel } from '@db/Notice';
import { ServerParamWithRole, GroupParam } from '../domain/gameField/serverlist';
import { reloadResources } from 'app/pubUtils/data';
import { ServerlistModel } from '@db/Serverlist';
import { dispatch } from 'app/pubUtils/dispatcher';
import { RedisClient } from 'redis';
import { REDIS_KEY } from '@consts';

export default class GameController extends Controller {

    public async checkVersion() {
        const { ctx } = this;
        const { version } = ctx.request.body;
        if (version >= CLIENT_VERSION) {
            ctx.body = ctx.service.utils.resResult(STATUS.SUCCESS);
            return;
        }
        //版本号太低
        ctx.body = ctx.service.utils.resResult(STATUS.VERSION_ERR, { version: CLIENT_VERSION });
        return;
    }

    public async getServerList() {
        const { ctx } = this;
        let { uid, clientVersion } = ctx;
        console.log('clientVersion', clientVersion);
        let serverList = new Array<GroupParam>();
        let loginServerList = new Array<ServerParamWithRole>();

        let allServers = await ServerlistModel.findByEnv(ctx.app.config.realEnv);
        let roles = await RoleModel.findAllByUid(uid, true, true);
        for (let server of allServers) {
            let curGroup = serverList.find(cur => cur.groupId == server.groupId);
            if (!curGroup) {
                curGroup = new GroupParam(server);
                serverList.push(curGroup);
            }
            curGroup.pushServer(server);

            let role = roles.find(role => role.serverId == server.id);
            if (!!role) {
                let curLoginInfo = new ServerParamWithRole(role, server);
                loginServerList.push(curLoginInfo);
            }
        }

        loginServerList.sort((a, b) => { return b.updatedAt.getTime() - a.updatedAt.getTime() });

        if (serverList) {
            ctx.body = ctx.service.utils.resResult(STATUS.SUCCESS, { serverList, loginServerList });
        } else {
            ctx.body = ctx.service.utils.resResult(STATUS.SERVER_NOT_FOUND);
        }
        return
    }

    public async newServer() {
        const { ctx } = this;
        const { serverId, serverType, name, host, port, status } = ctx.request.body;
        const serverList = await GameModel.getAllServerList();
        for (let { id, host: preHost, port: prePort } of serverList) {
            if (preHost === host && prePort === port && id === serverId) {
                ctx.body = ctx.service.utils.resResult(STATUS.SERVER_EXISTS);
                return;
            }
        }
        const gameInfo = await GameModel.newServer(serverId, serverType, name, host, port, status);
        if (gameInfo) {
            ctx.body = ctx.service.utils.resResult(STATUS.SUCCESS, { gameInfo });
        } else {
            ctx.body = ctx.service.utils.resResult(STATUS.NEW_SERVER_ERR);
        }
        return
    }


    public async getnotice() {
        const { ctx } = this;

        let notice = await NoticeModel.getAllNotice();
        let result = notice.map(cur => {
            let { id, title, tag, type, content, time } = cur;
            return {
                id, title, tag, type, content, time
            }
        })

        ctx.body = ctx.service.utils.resResult(STATUS.SUCCESS, { notice: result });
        return
    }


    public async reloadResource() {
        const { ctx } = this;

        try {

            reloadResources();
            ctx.body = ctx.service.utils.resResult(STATUS.SUCCESS, { isOK: true });
            return;
        } catch (e) {
            ctx.body = ctx.service.utils.resResult(STATUS.SUCCESS, { isOK: false, err: (<Error>e).stack });
            return;
        }
    }

    public async queryEnter() {
        const { ctx } = this;
        const { app, userCode } = ctx;

        let redisClient: RedisClient = app.context.redisClient;
        let hash = await redisClient.hvalsAsync(REDIS_KEY.SYS_SERVER);
        let connectors = hash.map(cur => JSON.parse(cur));

        if (!connectors || connectors.length === 0) {
            ctx.body = ctx.service.utils.resResult(STATUS.CONNECTOR_ERR);
            return
        }
        // select connector
        let res = dispatch(userCode, connectors, 'connector');
        ctx.body = ctx.service.utils.resResult(STATUS.SUCCESS, { host: res.clientHost, port: res.clientPort });
        return
    }
}
