import BaseModel from './BaseModel';
import { index, getModelForClass, prop, DocumentType } from '@typegoose/typegoose';
import { getTimeFun } from '../pubUtils/timeUtil';
import { genCode, robotIdComBack } from '../pubUtils/util';
import { PvpHeroInfo } from '../domain/dbGeneral';
import { EXTERIOR } from '../pubUtils/dicParam';
import { RoleType } from './Role';
import { PvpHistoryOppType } from './PvpHistoryOpp';
import { HeroType } from './Hero';
import { pvpEndParamInter } from '../pubUtils/interface';

export class HeroesRecord {
    @prop({ required: true, default: 0 })
    hid: number;               // 武将id
    @prop({ required: true, default: 0 })
    skinId: number;               // 皮肤id，fashions表的heroId
    @prop({ required: true, default: 0 })
    quality: number;           // 品质
    @prop({ required: true, default: 0 })
    star: number;               // 星级
    @prop({ required: true, default: 0 })
    colorStar: number;          // 觉醒
    @prop({ required: true, default: 0 })
    lv: number;                 // 等级
    @prop({ required: true, default: 0 })
    damage: number;             // 伤害
    @prop({ required: true, default: 0 })
    heal: number;               // 治疗
    @prop({ required: true, default: 0 })
    underDamage: number;        // 承伤
    
    setByPvpHeroInfo(pvpHero: PvpHeroInfo, params: pvpEndParamInter) {
        this.hid = pvpHero.actorId;
        this.skinId = pvpHero.skinId;
        this.quality = pvpHero.quality;
        this.star = pvpHero.star;
        this.colorStar = pvpHero.colorStar;
        this.lv = pvpHero.lv;
        this.setParams(params);
    }

    setByHero(hero: HeroType, params: pvpEndParamInter) {
        this.hid = hero.hid;
        this.skinId = hero.skinId;
        this.quality = hero.quality;
        this.star = hero.star;
        this.colorStar = hero.colorStar;
        this.lv = hero.lv;
        this.setParams(params);
    }

    setParams(params: pvpEndParamInter) {
        this.damage = params?.damage||0;
        this.heal = params?.heal||0;
        this.underDamage = params?.underDamage||0;
    }
}

export class PvpRecordPlayerInfo {
    @prop({ required: true })
    serverId: number;		    	// 区服id
    @prop({ required: true })
    roleId: string;					// 角色 id
    @prop({ required: true })
    roleName: string;					// 角色 名
    @prop({ required: true, default: 0 })
    lv: number;               // 等级
    @prop({ required: true, default: EXTERIOR.EXTERIOR_FACE })
    head: number;          // 头像
    @prop({ required: true, default: EXTERIOR.EXTERIOR_FACECASE })
    frame: number;          // 相框
    @prop({ required: true, default: EXTERIOR.EXTERIOR_APPEARANCE })
    spine: number;             // 形象
    @prop({ required: true, default: 0 })
    title: number;            // 爵位
    @prop({ required: true, default: 0 })
    ce: number;               // 最高五人战力
    @prop({ required: true, default: false })
    isSuccess: boolean;			// 是否胜利
    @prop({ required: true, default: 0 })
    score: number;			   	// 获得的总积分
    @prop({ required: true, type: HeroesRecord, default: [], _id: false })
    heroes: HeroesRecord[];			   	// 获得的总积分

    setByRole(role: RoleType, heroes: HeroesRecord[], isSuccess: boolean, score: number, lv: number ) {
        this.roleId = role.roleId;
        this.roleName = role.roleName;
        this.head = role.head;
        this.frame = role.frame;
        this.spine = role.spine;
        this.title = role.title;
        this.ce = role.topLineupCe;
        this.lv = lv;
        this.isSuccess = isSuccess;
        this.score = score;
        this.heroes = heroes;
        this.serverId = role.serverId;
    }

    setByHistoryOpp(oppRole: PvpHistoryOppType, oppHeroRecords: HeroesRecord[], isSuccess: boolean, score: number, serverId: number) {
        this.roleId = robotIdComBack(oppRole.oppRoleId);
        this.roleName = oppRole.roleName;
        this.lv = oppRole.pLv;
        this.head = oppRole.head;
        this.frame = oppRole.frame;
        this.spine = oppRole.spine;
        this.title = oppRole.title;
        this.ce = oppRole.defCe;
        this.heroes = oppHeroRecords;
        this.isSuccess = isSuccess;
        this.score = score;
        this.serverId = serverId;
    }
}

@index({ code: 1 })
@index({ battleCode: 1 })
@index({ roleId1: 1, updatedAt: -1 })
@index({ roleId2: 1, updatedAt: -1 })

export default class PvpRecord extends BaseModel {
    @prop({ required: true })
    roleId1: string;					// 角色 id
    @prop({ required: true })
    roleId2: string;					// 角色 id

    @prop({ required: false, default: '' })
    battleCode: string;
    @prop({ required: true, default: 0 })
    code: string;			   	// code
    @prop({ required: true, default: 0 })
    warId: number;			   	// 这一关使用的地图
    @prop({ required: true, type: PvpRecordPlayerInfo, default: {}, _id: false })
    attackInfo: PvpRecordPlayerInfo;			     	// 攻方信息
    @prop({ required: true, type: PvpRecordPlayerInfo, default: {}, _id: false })
    defenseInfo: PvpRecordPlayerInfo;			     	// 守方信息

    @prop({ required: true, default: false })
    hasRpl: boolean;            // 是否存在对应录像

    @prop({ required: true, default: 0 })
    createTime: number;
    @prop({ required: true, default: 0 })
    timeout: boolean;

    public static async createRec(roleId1: string, roleId2: string, battleCode: string) {
        await this.delPvpRecords();
        let code = genCode(6);
        const result = await PvpRecordModel.findOneAndUpdate({ code }, { $set: { roleId1, roleId2, battleCode } }, { new: true, upsert: true }).lean();
        return result;
    }

    public static async updateByBattleCode(battleCode: string, param: {  warId: number, attackInfo: PvpRecordPlayerInfo, defenseInfo: PvpRecordPlayerInfo, createTime: number, timeout?: boolean }) {
        const result = await PvpRecordModel.findOneAndUpdate({ battleCode }, param, { new: true }).lean();
        return result;
    }

    public static async getRecByRoleId( roleId: string, limit = 15, lean = true) {
        await this.delPvpRecords();
        const result: PvpRecord[] = await PvpRecordModel.find({ $or:[{roleId1: roleId}, {roleId2: roleId}], createTime: { $gt: 0 } }).select('-_id -__v -createdAt -updatedAt').limit(limit).sort({createTime: -1}).lean(lean);
        return result;
    }

    public static async delPvpRecords() {
        let t = <number>getTimeFun().getBeforeDayWithHour(3);
        let result = await PvpRecordModel.deleteMany({ createTime: {$lt: t}});//删除小于三天的战报
        return result;
    }

    public static async updateRplStatus(battleCode: string, hasRpl: boolean) {
        let result = await PvpRecordModel.findOneAndUpdate({ battleCode }, { hasRpl }, { new: true }).lean();
        return result;
    }
}

export const PvpRecordModel = getModelForClass(PvpRecord);

export interface PvpRecordType extends Pick<DocumentType<PvpRecord>, keyof PvpRecord> { };
export type PvpRecordParam = Partial<PvpRecordType>;