import BaseModel from './BaseModel';
import { getModelForClass, prop, DocumentType, index, Ref } from '@typegoose/typegoose';
import GVGLeague, { GVGLeagueType } from './GVGLeague';
import Guild, { GuildType } from './Guild';
import { GVG_APPLY_TYPE } from '../consts';

@index({ leagueCode: 1, guildCode: 1, type: 1 })
export default class GVGLeagueApply extends BaseModel {

    @prop({ required: true })    
    leagueCode: string;          // 发起的联军 or 收到申请的联军

    @prop({ required: true })
    league:  Ref<GVGLeague>;

    @prop({ required: true })    
    guildCode: string;           // 受邀的军团 or 发出申请的联军

    @prop({ required: true })
    guild:  Ref<Guild>;

    @prop({ required: true })    
    type: number;                // 类型 1-邀请 2-申请

    public static async findApplyFromGuild(guildCode: string) {
        const result: GVGLeagueApplyType[] = await GVGLeagueApplyModel.find({ guildCode, type: GVG_APPLY_TYPE.APPLY }).lean();
        return result;
    }

    public static async checkApply(leagueCode: string, guildCode: string, type: GVG_APPLY_TYPE) {
        // console.log('####', leagueCode, guildCode, type)
        const result = await GVGLeagueApplyModel.exists({ guildCode, leagueCode, 
            type: type == GVG_APPLY_TYPE.ALL? { $in: [GVG_APPLY_TYPE.APPLY, GVG_APPLY_TYPE.INVITE] }: type
        });
        return result;
    }

    public static async createApply(league: GVGLeagueType, guild: GuildType, type: number) {
        const result: GVGLeagueApplyType = await GVGLeagueApplyModel.findOneAndUpdate({ leagueCode: league.leagueCode, guildCode: guild.code, type }, { $set: { league: league._id, guild: guild._id,  }}, { new: true, upsert: true })
        .lean();
        return result;
    }

    public static async findApplyFromLeagueWithoutPopulate(leagueCode: string) {
        const result: GVGLeagueApplyType[] = await GVGLeagueApplyModel.find({ leagueCode, type: GVG_APPLY_TYPE.APPLY }).select('_id').lean();
        return result;
    }

    public static async findApplyFromLeague(leagueCode: string) {
        const result: GVGLeagueApplyType[] = await GVGLeagueApplyModel.find({ leagueCode, type: GVG_APPLY_TYPE.APPLY })
        .select({ _id: 0, guild: 1, guildCode: 1 })
        .populate({
            path: 'guild',
            select: 'code icon name lv memberCnt leader guildCe +serverId',
            model: 'Guild',
            populate: {
                path: 'leader',
                select: 'roleName',
                model: 'Role'
            }
        })
        .lean();
        return result;
    }

    public static async findInviteFromLeague(leagueCode: string) {
        const result: GVGLeagueApplyType[] = await GVGLeagueApplyModel.find({ leagueCode, type: GVG_APPLY_TYPE.INVITE }).lean();
        return result;
    }

    public static async findInviteFromGuildWithoutPopulate(guildCode: string) {
        const result: GVGLeagueApplyType[] = await GVGLeagueApplyModel.find({ guildCode, type: GVG_APPLY_TYPE.INVITE }).select('_id').lean();
        return result;
    }

    public static async findInviteFromGuild(guildCode: string) {
        const result: GVGLeagueApplyType[] = await GVGLeagueApplyModel.find({ guildCode, type: GVG_APPLY_TYPE.INVITE })
        .select({ _id: 0, guild: 1, guildCode: 1 })
        .populate({
            path: 'league',
            // select: 'code icon name lv memberCnt leader guildCe +serverId',
            model: 'GVGLeague',
            populate: {
                path: 'leader',
                select: 'roleName',
                model: 'Role'
            }
        })
        .lean();
        return result;
    }

    public static async deleteApply(guildCode: string, leagueCode: string) {
        const n = await GVGLeagueApplyModel.deleteMany({ guildCode, leagueCode, type: GVG_APPLY_TYPE.APPLY });
        return n;
    }
    
    public static async deleteByGuild(guildCode: string) {
        const n = await GVGLeagueApplyModel.deleteMany({ guildCode });
        return n;
    }

    public static async deleteByLeague(leagueCode: string) {
        const n = await GVGLeagueApplyModel.deleteMany({ leagueCode });
        return n;
    }

    public static async deleteInvite(guildCode: string, leagueCode: string) {
        const n = await GVGLeagueApplyModel.deleteMany({ guildCode, leagueCode, type: GVG_APPLY_TYPE.INVITE });
        return n;
    }
}

export const GVGLeagueApplyModel = getModelForClass(GVGLeagueApply);

export interface GVGLeagueApplyType extends Pick<DocumentType<GVGLeagueApply>, keyof GVGLeagueApply> {
    id: number;
};
export type GVGLeagueApplyUpdate = Partial<GVGLeagueApplyType>; // 将所有字段变成可选项
