import BaseModel from './BaseModel';
import { index, getModelForClass, prop, DocumentType } from '@typegoose/typegoose';
import { nowSeconds } from '../pubUtils/timeUtil';
import { genCode } from '../pubUtils/util';

class Rank {
    @prop({ required: true })
    roleId: string;
    @prop({ required: true })
    score: number;
    @prop({ required: true })
    time: number;
    @prop({ required: true })
    job: number;
}

@index({ guildCode: 1 })
export default class BossInstance extends BaseModel {
    @prop({ required: true })
    code: string;           // 这个boss本的唯一值

    @prop({ required: true })
    guildCode: string;

    @prop({ required: true })
    warId: number;

    @prop({ required: true })
    bossHp: number;

    @prop({ required: true })
    bossLv: number;

    @prop({ required: true, type: Rank, default:[]})
    ranks:Array<Rank>;

    @prop({ required: true })
    startTime: number;
    
    @prop({ required: true, default: 0})
    num: number; //重置次数

    @prop({ required: true, default:[], type: String, _id: false})
    roleIdRecords: Array<string>; //记录提示过胜利boss关的玩家

    @prop({ required: true })
    winWarId: number; //记录上一次通关的关卡，boss被压制成功后，首次点开boss界面会提示文字，boss已被压制

    @prop({ required: true })
    winBossLv: number; //记录上一次通关的boss等级

    @prop({ required: true })
    winTime: number; //记录上一次通关的时间

    @prop({ required: true, default: 0})
    winNum: number; //记录上一次重置次数

    @prop({ required: true, type: Rank, default:[]})
    recordRanks:Array<Rank>;//上一场排名信息

    @prop({ required: true, default: false })
    winSettled: boolean; //胜利是否结算过

    public static async findBossInstance(guildCode: string, lean = true) {
        const bossInstance: BossInstanceType = await BossInstanceModel.findOne({ guildCode }).lean(lean);
        return bossInstance;
    }

    public static async openBossInstance(guildCode: string, bossHp: number, warId: number, bossLv: number, lean = true) {
        let code = genCode(10);
        const bossInstance: BossInstanceType = await BossInstanceModel.findOneAndUpdate({ guildCode },{ $setOnInsert: { code }, ranks:[], time: nowSeconds(), bossHp, bossLv, warId, $inc: { num: 1 }}, {new: true, upsert: true}).lean(lean);
        return bossInstance;
    }
    //记录玩家boss通关后首次查看boss关卡
    public static async recordRoleIdWhenCheck(guildCode: string, roleId: string, lean = true) {
        const bossInstance: BossInstanceType = await BossInstanceModel.findOneAndUpdate({ guildCode }, { $push:{ roleIdRecords: roleId } }, { new: true }).lean(lean);
        return bossInstance;
    }

    public static async pushRecordRanks(guildCode: string, recordRank: Rank, lean = true) {
        const bossInstance: BossInstanceType = await BossInstanceModel.findOneAndUpdate({ guildCode }, { $push:{ recordRanks: recordRank } }, { new: true }).lean(lean);
        return bossInstance;
    }

    public static async pushRanks(guildCode: string, rank: Rank, lean = true) {
        const bossInstance: BossInstanceType = await BossInstanceModel.findOneAndUpdate({ guildCode }, { $push:{ ranks: rank } }, { new: true }).lean(lean);
        return bossInstance;
    }

    public static async updateBossInstance(guildCode: string, update:BossInstanceTypeParam, lean = true) {
        const bossInstance: BossInstanceType = await BossInstanceModel.findOneAndUpdate({ guildCode }, { $set:update }, { new: true }).lean(lean);
        return bossInstance;
    }

    public static async updateBossHp(guildCode: string, hp: number, roleId: string, lean = true) {
        const bossInstance: BossInstanceType = await BossInstanceModel.findOneAndUpdate({ guildCode, 'ranks.roleId': roleId, bossHp: { $gte: hp } }, { $inc: { bossHp: - hp ,'ranks.$.score': hp}, }, { new: true }).lean(lean);
        return bossInstance;
    }

    public static async updateRank(guildCode: string, roleId: string, lean = true) {
        const bossInstance: BossInstanceType = await BossInstanceModel.findOneAndUpdate({ guildCode, 'ranks.roleId': roleId }, { $set:{ 'ranks.$.time': nowSeconds() } }, { new: true }).lean(lean);
        return bossInstance;
    }
    
    public static async removeBossRank(guildCode: string, roleId: string, lean = true) {
        const guildTrain: BossInstanceType = await BossInstanceModel.findOneAndUpdate({ guildCode },
            { $pull:{ ranks: { roleId } }}, {new: true}).lean(lean);
        return guildTrain;
    }

    public static async findBySourceCode(guildCode: string, sourceCode: string) {
        const rec = await BossInstanceModel.findOne({ guildCode, code: sourceCode }).select('ranks').lean();
        return rec;
    }
}

export const BossInstanceModel = getModelForClass(BossInstance);

export interface BossInstanceType extends Pick<DocumentType<BossInstance>, keyof BossInstance> {};
export type BossInstanceTypeParam = Partial<BossInstanceType>; // 将所有字段变成可选项
