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

// 全局加成
export class AttrCell {
    @prop({ required: true })
    attrId: number;            // 属性id
    @prop({ required: true, type: Number })
    values: number[];          // 战力公式中的全局加成的数据，查表后的结果
}

// 单武将加成
export class HeroAttr {
    @prop({ required: true })
    hid: number;               // 武将id
    @prop({ required: true })
    lv: number;
    @prop({ required: true, type: () => AttrCell, _id: false })
    attrs: AttrCell[];
    @prop({ required: true })
    historyCe: number;
    @prop({ required: true })
    objectId: string;
}

export class EquipAttr {
  @prop({ required: true })
  hid: number;               // 武将id
  @prop({ required: true })
  eplaceId: number;          // 装备位置
  @prop({ required: true })
  lv: number;
  @prop({ required: true, type: () => AttrCell, _id: false })
  attrs: AttrCell[];
}

// 百家学宫加成
export class SchoolAttr {
    @prop({ required: true })
    hid: number;               // 武将id
    @prop({ required: true })
    attrId: number;             // 属性id
    @prop({ required: true })
    value: number;              // 百家学宫有多个武将，单独拎出来方便计算，计算之后结果存到globaAttrs的global1
}

// 名将谱加成
export class ScrollAttr {
    @prop({ required: true })
    hid: number;               // 武将id
    @prop({ required: true })
    attrId: number;             // 属性id
    @prop({ required: true })
    value: number;              // 百家学宫有多个武将，单独拎出来方便计算，计算之后结果存到globaAttrs的global1
}


// 属性结果
export class SingleAttribute {
  @prop({ required: true })
  id: number;             // 属性id
  @prop({ required: true })
  val: number;              // 值
  @prop({ required: true })
  ceVal: number;              // 值
  @prop({ required: true })
  str: string;              // 公式
}

export class Attribute {
  @prop({ required: true })
  hid: number;
  @prop({ required: true, type: SingleAttribute, _id: false })
  attrs: SingleAttribute[];             // 属性id
}

/**
  * 属性表
*/

@index({ roleId: 1 })

export default class RoleCe extends BaseModel {

  @prop({ required: true })
  roleId: string;					// 角色 id

  @prop({ required: true })
  roleLv: number;					// 玩家等级

  @prop({ required: true, type: AttrCell, _id: false })
  globalAttrs: AttrCell[]

  @prop({ required: true, type: HeroAttr, _id: false })
  heroAttrs: HeroAttr[]

  @prop({ required: true, type: EquipAttr, _id: false })
  equipAttrs: EquipAttr[]

  @prop({ required: true, type: SchoolAttr, _id: false })
  schoolAttrs: SchoolAttr[];

  @prop({ required: true, type: ScrollAttr, _id: false })
  scrollAttrs: ScrollAttr[];
  
  @prop({ required: true, type: Attribute, _id: false })
  attributes: Attribute[];

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

  public static async findByRoleId(roleId: string) {
    let result: RoleCeType = await RoleCeModel.findOne({ roleId }).lean();
    return result;
  }

  public static async updateRoleCe(roleId: string, update: RoleCeUpdate) {
    let result: RoleCeType = await RoleCeModel.findOneAndUpdate({ roleId }, { $set: update }, { new: true, upsert: true }).lean();
    return result;
  }

  public static async deleteHero(roleId: string, hid: number) {
    let roleCe: RoleCeType = await RoleCeModel.findByRoleId(roleId);
    return await RoleCeModel.updateRoleCe(roleId, this.filterHid(roleCe, hid, ['heroAttrs', 'equipAttrs', 'schoolAttrs', 'scrollAttrs']));
  }

  private static filterHid(roleCe: RoleCeType, hid: number, fields: string[]) {
    let update: RoleCeUpdate = {};
    for(let field of fields) {
      if(roleCe[field] && isArray(roleCe[field])) update[field] = roleCe[field].filter(cur => cur.hid != hid);
    }
    return update;
  }
}

export const RoleCeModel = getModelForClass(RoleCe);

export interface RoleCeType extends Pick<DocumentType<RoleCe>, keyof RoleCe> { };
export type RoleCeUpdate = Partial<RoleCeType>;