import {Application, RouteRecord, FrontendOrBackendSession, HandlerCallback } from "pinus";
import { resResult } from "../../../pubUtils/util";
import { GUILD_AUTH_CHECK_TYPE, GUILD_OPERATE, GUILD_ROUTE_TO_OPERATE, STATUS } from "../../../consts";
import { UserGuildModel, UserGuildType } from "../../../db/UserGuild";
import { checkAuth, setUserGuildSession } from "../../../services/guildService";

export function guildAuthFilter(app: Application) {
    return new Filter(app);
}

var Filter = function(this: any, app: Application) {
    this.app = app;
};

Filter.prototype.before = async function (routeRecord: RouteRecord, msg: any, session: FrontendOrBackendSession, next: HandlerCallback) {
    const roleId: string = session.get('roleId');
    let guildCode: string = session.get('guildCode');
    let guildAuth: number = session.get('guildAuth');
    // console.log('********guildAuth', guildAuth);
    
    const { code, roleId: hisRoleId } = msg;

    let route = routeRecord.route;
    if(GUILD_ROUTE_TO_OPERATE.has(route)) {
        let myUserGuild: UserGuildType;
        let hisUserGuild: UserGuildType;

        if(!guildAuth) {
            myUserGuild = await UserGuildModel.getMyGuild(roleId, '+refTimeDaily');
            if(myUserGuild) {
                guildCode = myUserGuild.guildCode;
                guildAuth = myUserGuild.auth;
            }
            setUserGuildSession(session, myUserGuild);
        }

        let arr = GUILD_ROUTE_TO_OPERATE.get(route);
        for(let { operate, type } of arr) {
            if( type == GUILD_AUTH_CHECK_TYPE.CHECK_SELF) {
                myUserGuild = await UserGuildModel.getMyGuild(roleId, '+refTimeDaily');
                const checkResult = await checkAuth(operate, code||guildCode, guildAuth);
                if (!checkResult) return next(new Error(), resResult(STATUS.GUILD_AUTH_NOT_ENOUGH));
            } else if (type == GUILD_AUTH_CHECK_TYPE.CHECK_SELF_IF_EXIST) {
                if(!!guildCode) {
                    myUserGuild = await UserGuildModel.getMyGuild(roleId, '+refTimeDaily');
                    const checkResult = await checkAuth(operate, code||guildCode, guildAuth);
                    if (!checkResult) return next(new Error(), resResult(STATUS.GUILD_AUTH_NOT_ENOUGH));
                }
            } else if (type == GUILD_AUTH_CHECK_TYPE.CHECK_OTHERS) {
                hisUserGuild = await UserGuildModel.getMyGuild(hisRoleId, 'auth guildCode job');
                const checkResult = await checkAuth(operate, code||guildCode, hisUserGuild?.auth);
                if (!checkResult) return next(new Error(), resResult(STATUS.GUILD_AUTH_NOT_ENOUGH));
            } else if (type == GUILD_AUTH_CHECK_TYPE.CHECK_SELF_WITH_SESSION) {
                const checkResult = await checkAuth(operate, code||guildCode, guildAuth);
                if (!checkResult) return next(new Error(), resResult(STATUS.GUILD_AUTH_NOT_ENOUGH));
            }
        }
        
        msg.myUserGuild = myUserGuild;
        msg.hisUserGuild = hisUserGuild;
    }

    next(null);
};

Filter.prototype.after = function (err: Error, routeRecord: RouteRecord, msg: any, session: FrontendOrBackendSession, resp: any, next: HandlerCallback) {
    next(err);
};