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

class Question {
  @prop({ required: true })
  id: number; 
  @prop({ required: true })
  question: string;
  @prop({ required: false, type: String })
  answer: [string];
  @prop({ required: true })
  status: number;
}
/**
  * 战斗记录接口
  */
@index({ roleId: 1, eventCode: 1, eventId: 1 })
@index({ eventCode: 1 })

export default class EventRecord extends BaseModel {
    @prop({ required: true })
    roleId: string;					    // 角色 id
    @prop({ required: true })
    roleName: string;					    // 角色 名
    @prop({ required: true })
    eventCode: string;					// 这次刷新出的事件的唯一标识
    @prop({ required: true })
    eventId: number;					// 事件 id
    @prop({ required: true })
    type: number;						// 事件类型
    @prop({ required: true })
    quality: number;						// 事件品质
    @prop({ required: true, default: 0 })
    status: number;                     // 状态 0-初始状态 1-挑战成功 2-挑战失败 3-领取成功奖励 4-领取了失败奖励
    @prop({ required: true, default: 0 })
    refTime: number;				    // 刷新时间
    @prop({ required: true, default: 0 })
    battleId: number;				    // 关卡类型，关卡id
    @prop({ required: true, default: 0 })
    battleCode: string;				    // 关卡类型，关卡code
    @prop({ required: true, default: 0 })
    turn: number;				    // 随机的轮数，保证每个event_id都能随机到一次再进行下一轮
    @prop({ required: true })
    point: number;				    // 位置
    @prop({ required: true, type: Question, default: [], _id: false })
    question: Array<Question>;				    // 题库id

    
    public static async getEventRecordByTime(roleId: string, refTime: number, lean=true ) {
      let data: EventRecordType[] = await EventRecordModel.find({roleId, refTime}).select('eventCode eventId type quality status battleId point question').lean(lean);
      return data;
    }

    public static async getEventRecordByCode(roleId: string, eventCode: string, lean=true ) {
      let data: EventRecordType = await EventRecordModel.findOne({roleId, eventCode}).lean(lean);
      return data;
    }
    public static async getHostoryEventRecord(roleId: string, lean=true) {
        let latest: EventRecordType = await EventRecordModel.findOne({roleId}).sort({turn: -1}).lean();
        let {turn = 0} = latest||{};
        let result: EventRecordType[] = await EventRecordModel.find({roleId, turn}).lean(lean);
        return {history: result, turn};
    }

    public static async saveEventAnswer(eventCode: string, questionId: number, status: number , lean=true ) {
      let data: EventRecordType = await EventRecordModel.findOneAndUpdate(
        {eventCode, 'question.id': questionId}, { $set: {'question.$.status': status} }, {upsert: true, new: true}).lean(lean);
      return data;
    }

    public static async saveEventRecord(eventCode: string, params: {roleId: string, refTime: number, eventId: number, roleName:string, turn?: number, type: number, quality: number, battleId?: number, status: number, point: number, question: Array<any> } , lean=true ) {
      let doc = new EventRecordModel();
      let update = Object.assign(doc.toJSON(), params, {eventCode});
      let data: EventRecordType = await EventRecordModel.findOneAndUpdate({eventCode}, { $set: update }, {upsert: true, new: true}).select('eventCode eventId type quality status battleId point question').lean(lean);
      return data;
    }

    public static async setBattleCode(roleId: string, battleId: number, refTime: number, battleCode: string , lean=true ) {
      let result: EventRecordType = await EventRecordModel.findOneAndUpdate({roleId, battleId, refTime}, {$set:{ battleCode }}).sort({turn: 1}).lean(lean);
      return result;
    }

    public static async setBattleStatus(roleId: string, battleId: number, battleCode: string, status: number , lean=true ) {
      let result: EventRecordType = await EventRecordModel.findOneAndUpdate({roleId, battleId, battleCode}, {$set:{ status }}).lean(lean);
      return result;
    }

    public static async setStatusByCode(roleId: string, eventCode: string, status: number , lean=true ) {
      let result: EventRecordType = await EventRecordModel.findOneAndUpdate({ roleId, eventCode }, {$set:{ status }}, {new: true, upsert: true}).lean(lean);
      return result;
    }

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

export const EventRecordModel = getModelForClass(EventRecord);

export interface EventRecordType extends Pick<DocumentType<EventRecord>, keyof EventRecord>{};