import BaseModel from './BaseModel';
import { index, getModelForClass, prop, DocumentType } from '@typegoose/typegoose';
import { EXPEDITION_WAR_RECORD_STATUS } from '../consts';
import { Enemies } from '../domain/dbGeneral';


class EnemiesCurHPAP {
    @prop({ required: true })
    dataId: number; // 战场中唯一指向武将的代码
    @prop({ required: true })
    hp: number; // 生命
    @prop({ required: true })
    ap: number; // 怒气
}

/**
  * 远征记录
  */
@index({ expeditionCode: 1 })

export default class ExpeditionWarRecord extends BaseModel {
    @prop({ required: true, default: '' })
    roleId: string;	                // 角色 id
    @prop({ required: true, default: '' })
    expeditionCode: string;         // 远征的唯一标识
    @prop({ required: true, default: 0 })
    expeditionId: number;         // 远征序号
    @prop({ required: true, default: 0 })
    battleId: number;				// 相关关卡id
    @prop({ required: true, default: 0 })
    mapseid: number;				// 关卡随机buff
    @prop({ required: true, default: '' })
    battleCode: string;             // 关联关卡唯一值
    @prop({ required: true, default: 0 })
    battleStatus: number;           // 是否通过, -1-已生成 0-可挑战 1-成功 2-挑战失败
    @prop({ required: true, default: 0 })
    enemyFrom: number;              // 敌军数据来源：1-配表的敌军队，2-玩家
    @prop({ required: true, default: '' })
    enemyId: string;                // 敌军队伍id或玩家id
    @prop({ required: true, type: Enemies, default: [], _id: false })
    enemies: Array<Enemies>;        // 敌军数据
    @prop({ required: true, type: EnemiesCurHPAP, default: [], _id: false })
    enemiesCurHpAp: Array<EnemiesCurHPAP>;                // 敌军数据
    @prop({ required: true, default: 0 })
    ce: number;                // 敌军战力

    public static async getRecordByCode(expeditionCode: string, lean = true) {
        const result: ExpeditionWarRecordType[] = await ExpeditionWarRecordModel.find({ expeditionCode, battleStatus: {$gte: EXPEDITION_WAR_RECORD_STATUS.WAITING} }).select('expeditionId battleId battleCode battleStatus ce').sort({expeditionId: 1}).lean(lean);
        return result;
    }

    public static async getRecordByCodeAndId(expeditionCode: string, expeditionId: number, lean = true) {
        const result: ExpeditionWarRecordType = await ExpeditionWarRecordModel.findOne({ expeditionCode, expeditionId }).select('expeditionId battleId battleCode battleStatus enemyFrom enemies enemiesCurHpAp ce mapseid').lean(lean);
        return result;
    }
    
    public static async saveRecord(expeditionCode: string, expeditionId: number, params: ExpeditionWarRecordUpdate, lean = true) {
        const doc = new ExpeditionWarRecordModel();
        const update = Object.assign(doc.toJSON(), params, {expeditionCode, expeditionId});
        // console.log('*****', JSON.stringify(update));
        const result: ExpeditionWarRecordType = await ExpeditionWarRecordModel.findOneAndUpdate({ expeditionCode, expeditionId }, update, {new: true, upsert: true}).select('expeditionId battleId battleCode battleStatus enemyFrom enemies enemiesCurHpAp ce').lean(lean);
        return result;
    }
    
    public static async updateStatus(expeditionCode: string, expeditionId: number, battleStatus: number, lean = true) {
        const result: ExpeditionWarRecordType = await ExpeditionWarRecordModel.findOneAndUpdate({ expeditionCode, expeditionId }, {battleStatus}, {new: true}).lean(lean);
        return result;
    }

    public static async updateBattleCode(expeditionCode: string, expeditionId: number, battleStatus: number, battleCode: string, lean = true) {
        const result: ExpeditionWarRecordType = await ExpeditionWarRecordModel.findOneAndUpdate({ expeditionCode, expeditionId }, {battleStatus, battleCode}, {new: true}).lean(lean);
        return result;
    }

    public static async updateEnemiesStatus(expeditionCode: string, expeditionId: number, battleStatus: number, enemies: Array<{dataId: number, hp: number, ap: number}>, lean = true) {

        const result: ExpeditionWarRecordType = await ExpeditionWarRecordModel.findOneAndUpdate(
            {expeditionCode, expeditionId},
            {$set: {battleStatus}, enemiesCurHpAp: enemies},
            {new: true}
        ).lean(lean);
        return result;
    }

    public static async deleteAccount(roleId: string) {
        let result = await ExpeditionWarRecordModel.deleteMany({roleId});
        return result;
      }
}

export const ExpeditionWarRecordModel = getModelForClass(ExpeditionWarRecord);

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