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

export class Record {
    @prop({ required: true })
    round: number;     // 第几回合

    @prop({ required: true })
    dataId: number;    // 出兵表上的dataId

    @prop({ required: true })
    enemyType: number;    // 敌人类型 2-小兵 3-小boss 4-大boss

    @prop({ required: true })
    score: number;    // 得分

}

export class DamageRecord {
    @prop({ required: true })
    round: number;     // 第几回合

    @prop({ required: true })
    hid: number;    // 造成伤害的武将

    @prop({ required: true })
    damage: number;    // 伤害
}

@index({ code: 1 })
@index({ sourceCode: 1, roleId: 1 })
export default class UserGuildActivityRec extends BaseModel {

    @prop({ required: true })
    code: string;            // 本次记录唯一值

    @prop({ required: true })
    sourceCode: string;        // 军团记录的code

    @prop({ required: true })
    roleId: string;      // 玩家id

    @prop({ required: true })
    roleName: string;      // 军团唯一记录

    @prop({ required: true })
    guildCode: string;       // 军团code

    @prop({ required: true })
    serverId: number;       // 分服

    @prop({ required: true })
    aid: number;             // 军团活动id

    @prop({ required: true, default: false })
    isSuccess: boolean;      // 是否胜利

    @prop({ required: true, default: false })
    isCompleted: boolean;      // 是否完成结算了

    @prop({ required: true, default: 0 })
    rank: number;            // 最终排名

    @prop({ required: true, default: 0 })
    challengeCnt: number;            // 向上累加的挑战次数


    @prop({ required: true, type: Number })
    heroes: number[];            // 南蛮&诸侯混战 使用的武将

    @prop({ required: true })
    score: number;            // 个人总军功/个人总伤害

    // 南蛮入侵字段
    @prop({ required: true, type: Record, _id: false })
    record: Record[];            // 个人总军功
    @prop({ required: true })
    round: number;            // 回合数
    @prop({ required: true })
    gateHp: number;          // 最终城门血量

    // 诸侯混战字段
    @prop({ required: true, default: 0 })
    challengeTime: number;            // cd结束时间
    @prop({ required: true, type: DamageRecord, _id: false })
    damageRecord: DamageRecord[];            // 城门伤害记录
    @prop({ required: true, default: 0 })
    cityId: number;            // 挑战城池

    @prop({ required: true, default: false })
    hasShow: boolean;      // 是否显示了胜利

    // 每天一条记录
    public static async getRecord(roleId: string, roleName: string, guildCode: string, serverId: number, sourceCode: string, aid: number) {
        let today = getZeroPointD();
        let docs = new UserGuildActivityRecModel();
        let code = genCode(10);
        let update = Object.assign(docs, { code, roleId, roleName, guildCode, serverId, aid });
        delete update.heroes;
        let rec: UserGuildActivityRecType = await UserGuildActivityRecModel.findOneAndUpdate(
            { roleId, sourceCode, createdAt: { $gte: today }}, 
            { $setOnInsert: update }, 
            {new: true, upsert: true}).lean();

        return rec;
    }


    public static async findByRoleId(roleId: string, sourceCode: string) {
        let today = getZeroPointD();
        let rec: UserGuildActivityRecType = await UserGuildActivityRecModel.findOne({ roleId, sourceCode, createdAt: { $gte: today }}).lean();

        return rec;
    }

    public static async incChallengeCnt(code: string, heroes: number[], inc: number = 1 ) {
        let rec = await UserGuildActivityRecModel.findOneAndUpdate( { code}, { $push: { heroes: { $each: heroes}}, $inc: { challengeCnt: inc }}, {new: true}).lean();
        return rec;
    }

    public static async pushRecord(code: string, records: Record[], round: number) {
        let rec: UserGuildActivityRecType = await UserGuildActivityRecModel.findOneAndUpdate(
            { code }, 
            { $push: { record: { $each: records } }, $set: { round } },
            { new: true }
        ).lean();
        return rec;
    }

    public static async pushCityRecord(code: string, damageRecord: DamageRecord, challengeTime: number) {
        let rec: UserGuildActivityRecType = await UserGuildActivityRecModel.findOneAndUpdate(
            { code }, 
            { $push: { damageRecord }, $set: { challengeTime }},
            { new: true }
        ).lean();
        return rec;
    }

    public static async updateInfo(code: string, update: UserGuildActivityRecUpdateParam) {
        let rec: UserGuildActivityRecType = await UserGuildActivityRecModel.findOneAndUpdate({ code }, { $set: update }, { new: true }).lean();
        return rec;
    }

    public static async updateInfoByRoleId(roleId: string, update: UserGuildActivityRecUpdateParam) {
        let today = getZeroPointD();
        let rec: UserGuildActivityRecType = await UserGuildActivityRecModel.findOneAndUpdate(
            { roleId, createdAt: { $gte: today } }, { $set: update }, { new: true }).lean();
        return rec;
    }
}

export const UserGuildActivityRecModel = getModelForClass(UserGuildActivityRec);

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