import BaseModel from "./BaseModel";
import { index, getModelForClass, prop, DocumentType } from '@typegoose/typegoose';
import { GVGLeagueType } from "./GVGLeague";

class Player {
    @prop({ required: true })
    leagueCode: string;
    @prop({ required: true })
    roleId: string;
    @prop({ required: true })
    teamCnt: number;
}

@index({ configId: 1, cityId: 1, groupKey: 1 })
// GVGCity 类，继承自 BaseModel
export default class GVGCity extends BaseModel {
    @prop({ required: true, default: 1 })
    configId: number;       // config唯一id 

    @prop({ required: true })
    groupKey: string;       // 战区 

    @prop({ required: true })
    cityId: number;         // 城池id

    @prop({ required: true, default: [], type: Player, _id: false })
    players: Player[];  // 联军

    @prop({ required: false })
    hasGuard: boolean;    // 是否有联军占领

    @prop({ required: false })
    guardLeague: string;    // 占领的联军

    @prop({ required: false })
    guardLeagueName: string;    // 占领的联军

    @prop({ required: false })
    guardLeagueIcon: number;    // 占领的联军

    @prop({ required: true, default: 0 })
    userCnt: number;        // 城池人数

    // 通过 cityId 获取城市
    public static async findByCityId(configId: number, groupKey: string, cityId: number) {
        const city: GVGCityType = await GVGCityModel.findOne({ configId, groupKey, cityId }).lean();
        return city;
    }

    // 添加人数
    public static async increasePlayer(configId: number, groupKey: string, cityId: number, roleId: string, leagueCode: string, teamCnt: number) {
        await GVGCityModel.findOneAndUpdate({ configId, groupKey, cityId }, { $setOnInsert: { userCnt: 0, players: [] } }, { upsert: true }).lean() 
        const city: GVGCityType = await GVGCityModel.findOneAndUpdate({ configId, groupKey, cityId, userCnt: { $lt: 200 } }, { $inc: { userCnt: 1 }, $push: { players: { roleId, leagueCode, teamCnt } }}, { new: true }).lean();
        return city;
    }

    // 减少人数
    public static async decreasePlayerByCity(configId: number, groupKey: string, cityId: number, roleId: string) {
        const city: GVGCityType = await GVGCityModel.findOneAndUpdate({ configId, groupKey, cityId, 'players.roleId': roleId }, { $inc: { userCnt: -1 }, $pull: { players: { roleId } }}, { new: true }).lean();
        return city;
    }

    public static async decreasePlayer(configId: number, groupKey: string, roleId: string) {
        const city: GVGCityType = await GVGCityModel.findOneAndUpdate({ configId, groupKey, 'players.roleId': roleId }, { $inc: { userCnt: -1 }, $pull: { players: { roleId } }}, { new: true }).lean();
        return city;
    }

    // 添加人数
    public static async increaseTeam(configId: number, groupKey: string, cityId: number, roleId: string) {
        const city: GVGCityType = await GVGCityModel.findOneAndUpdate({ configId, groupKey, cityId, 'players.roleId': roleId }, { $inc: { 'players.$.teamCnt': 1 }}, { new: true }).lean();
        return city;
    }

    // 查询联军驻守情况
    public static async findGuardCityByLeague(configId: number, leagueCode: string, select = '') {
        const cities: GVGCityType[] = await GVGCityModel.find({ configId, guardLeague: leagueCode, hasGuard: true }).select(select).lean();
        return cities
    }

    // 查询联军驻守情况
    public static async checkLeagueHasGuard(groupKey: string, leagueCode: string) {
        return await GVGCityModel.exists({ groupKey, guardLeague: leagueCode, hasGuard: true });
    }

    // 查询联军驻守情况
    public static async findGuardCity(configId: number, groupKey: string, select = '') {
        let cities: GVGCityType[] = await GVGCityModel.find({ configId: configId + 1, groupKey, hasGuard: true }).select(select).lean();
        if(cities.length <= 0) cities = await GVGCityModel.find({ configId, groupKey }).select(select).lean();
        return cities
    }

    // 查询有联军驻守的城池
    public static async findAllGuardCities(configId: number) {
        const cities: GVGCityType[] = await GVGCityModel.find({ configId, hasGuard: true }).lean();
        return cities
    }

    // 占领城池
    public static async guardCity(configId: number, groupKey: string, cityId: number, league: GVGLeagueType) {
        const city: GVGCityType = await GVGCityModel.findOneAndUpdate({ configId: configId + 1, cityId, groupKey }, { $set: { 
            hasGuard: true, guardLeague: league.leagueCode, guardLeagueName: league.name, guardLeagueIcon: league.icon
         }, $setOnInsert: { userCnt: 0, players: [] } }, { upsert: true, new: true }).lean();
        return city;
    }

    public static async findByConfigAndGroup(configId: number, groupKey: string) {
        let cities: GVGCityType[] = await GVGCityModel.find({ configId: configId + 1, groupKey, hasGuard: true }).lean();
        if(!cities || cities.length == 0) cities = await GVGCityModel.find({ configId, groupKey, hasGuard: true }).lean();
        return cities
    }

    public static async findByConfig(configId: number) {
        const cities: GVGCityType[] = await GVGCityModel.find({ configId, hasGuard: true }).lean();
        return cities
    }

    public static async updateLeagueInfo(leagueCode: string, leagueName: string, icon: number) {
        let updateInfo: GVGCityUpdate = {};
        if(leagueName != undefined) updateInfo.guardLeagueName = leagueName;
        if(icon != undefined) updateInfo.guardLeagueIcon = icon;
        await GVGCityModel.updateMany({ guardLeague: leagueCode }, { $set: updateInfo });
    }

    public static async leagueDismiss(configId: number, groupKey: string, leagueCode: string) {
        await GVGCityModel.updateMany({ configId, groupKey, guardLeague: leagueCode }, { $set: { hasGuard: false, guardLeague: '', guardLeagueIcon: 0, guardLeagueName: '' } })
    }
}


export const GVGCityModel = getModelForClass(GVGCity);

export interface GVGCityType extends Pick<DocumentType<GVGCity>, keyof GVGCity> {
    id: number;
};

export type GVGCityUpdate = Partial<GVGCityType>; // 将所有字段变成可选项

