import BaseModel from './BaseModel';
import { index, getModelForClass, prop, DocumentType } from '@typegoose/typegoose';
import { nowSeconds } from '../pubUtils/timeUtil';
import { CounterModel } from './Counter';
import { COUNTER } from '../consts';

@index({ isCurrent: 1 })
@index({ seasonNum: 1 })
export default class PVPConfig extends BaseModel {

    @prop({ required: true, default: 1 })
    seasonNum: number;              // 赛季

    @prop({ required: true })
    seasonStartTime: number;         // 赛季开始时间

    @prop({ required: true })
    seasonRewardTime: number;         // 结算奖励时间

    @prop({ required: true })
    seasonEndTime: number;         // 赛季结束的时间

    @prop({ required: true })
    hasSettleReward: boolean;         // 是否发放奖励

    @prop({ required: true, type: Number })
    warIds: number[];         // 关卡id

    @prop({ required: true })
    isCurrent: boolean;         // 是否是当前赛季

    public static async findCurPVPConfig() {
        let result: PVPConfigType = await PVPConfigModel.findOne({ isCurrent: true }).lean();
        if(!result) {
            result = await PVPConfigModel.findOneAndUpdate({ seasonStartTime: { $lte: nowSeconds() } }, { $set: { isCurrent: true }}, { new: true }).sort({ seasonStartTime: -1 }).lean();
        }
        return result;
    }

    public static async findPVPConfig(seasonNum: number) {
        const result: PVPConfigType = await PVPConfigModel.findOne({ seasonNum }).lean(true);
        return result;
    }

    public static async createPVPConfig(seasonNum: number|'new', params: PVPConfigUpdate, uid: number) {
        if(seasonNum == 'new') {
            seasonNum = await CounterModel.getNewCounter(COUNTER.PVP_SEASON_NUM);
        }
        const result: PVPConfigType = await PVPConfigModel.findOneAndUpdate({ seasonNum }, { $set: { ...params, updatedBy: uid }, $setOnInsert: { hasSettleReward: false, isCurrent: false, createdBy: uid } }, { upsert: true, new: true }).lean(true);
        return result;
    }

    public static async getSettledConfig() {
        const result: PVPConfigType = await PVPConfigModel.findOne({ hasSettleReward: true }).sort({ seasonNum: -1}).lean();
        return result;
    }

    public static async checkTime(seasonNum: number|'new', seasonStartTime: number, seasonRewardTime: number) {
        if(seasonNum == 'new') {
            return await PVPConfigModel.exists({ seasonRewardTime: { $gt: seasonStartTime } })
        } else {
            return await PVPConfigModel.exists({ 
                seasonNum: { $ne: seasonNum },
                $or: [
                    { seasonNum: { $lt: seasonNum }, seasonRewardTime: { $gt: seasonStartTime } },
                    { seasonNum: { $gt: seasonNum }, seasonStartTime: { $lt: seasonRewardTime } }
                ]
            })
        }
    }

    public static async setReward(seasonNum: number) {
        const result: PVPConfigType = await PVPConfigModel.findOneAndUpdate({ seasonNum }, { hasSettleReward: true }, { new: true }).lean(true);
        return result;
    }

    public static async setCurrentPvp() {
        await PVPConfigModel.updateMany({ isCurrent: true }, { $set: { isCurrent: false } });
        const result: PVPConfigType = await PVPConfigModel.findOneAndUpdate({ seasonStartTime: { $lte: nowSeconds() } }, { $set: { isCurrent: true }}, {new: true}).sort({ seasonStartTime: -1 }).lean(true);
        return result;
    }

    public static async setNextPvp(seasonNum: number) {
        await PVPConfigModel.updateMany({ isCurrent: true }, { $set: { isCurrent: false } });
        const result: PVPConfigType = await PVPConfigModel.findOneAndUpdate({ seasonNum }, { $set: { isCurrent: true }}, {new: true}).sort({ seasonStartTime: -1 }).lean(true);
        return result;
    }

    public static async findByCondition(page: number, pageSize: number, sortField: string = 'seasonNum', sortOrder: string = 'descend') {
        let sort = {};
        if (sortField && sortOrder) {
            if (sortOrder == 'ascend') {
                sort[sortField] = 1;
            } else if (sortOrder == 'descend') {
                sort[sortField] = -1;
            }
        }
        const result: PVPConfigType[] = await PVPConfigModel.find().limit(pageSize).skip((page - 1) * pageSize).sort(sort).lean({ getters: true, virtuals: true });
        return result;

    }

    public static async countByCondition() {

        const result = await PVPConfigModel.count({});
        return result;
    }
}

export const PVPConfigModel = getModelForClass(PVPConfig);

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