// 征战中原对手锁
import BaseModel from './BaseModel';
import { index, getModelForClass, prop, DocumentType } from '@typegoose/typegoose';
import { OppPlayerInfo, OppPlayerHeroInfo } from '../domain/gvgField/gvgDb';
import { genCode } from '../pubUtils/util';
import { getTimeFunD } from '../pubUtils/timeUtil';

class LeagueGood {
    @prop({ required: true })
    itemType: number;

    @prop({ required: true })
    id: number;
    
    @prop({ required: true })
    count: number
}

@index({ battleCode: 1 })
@index({ groupKey: 1, vestigeId: 1, rank: 1 })
export default class GVGVestigeRec extends BaseModel {

    @prop({ required: true })
    battleCode: string;					// 唯一code

    @prop({ required: true })
    warId: number;					// 关卡id

    @prop({ required: true })
    attackRoleId: string;				// 攻方玩家id

    @prop({ required: true })
    defenseRoleId: string;				// 守方玩家id

    @prop({ required: true })
    configId: number;					// 赛期

    @prop({ required: true })
    groupKey: string;					// 战区id

    @prop({ required: true })
    vestigeId: number;					// 遗迹id

    @prop({ required: true })
    cancel: boolean;			      // 是否取消了

    @prop({ required: true })
    checkTime: number;					// 开始出兵的时间，13位时间戳

    @prop({ required: true })
    battleTime: number;				// 开始挑战的时间，13位时间

    @prop({ required: true })
    endTime: number;				// 结束时间，13位时间戳

    @prop({ required: true, type: () => OppPlayerInfo, default: {}, _id: false })
    attackInfo: OppPlayerInfo;			     	// 攻方信息

    @prop({ required: true, type: () => OppPlayerInfo, default: {}, _id: false })
    defenseInfo: OppPlayerInfo;			     	// 守方信息

    @prop({ required: true, type: () => LeagueGood, default: [], _id: false })
    leagueGoods: LeagueGood[];			     	// 奖励

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

    public static async createRec(configId: number, vestigeId: number, groupKey: string, warId: number, attackInfo: OppPlayerInfo, defenseInfo: OppPlayerInfo, leagueGoods: LeagueGood[]) {
        const battleCode = genCode(10);
        const result: GVGVestigeRecType = await GVGVestigeRecModel.findOneAndUpdate({ battleCode }, {
            $set: { configId, vestigeId, groupKey, attackRoleId: attackInfo.roleId, defenseRoleId: defenseInfo.roleId, warId, checkTime: Date.now(), attackInfo, defenseInfo, leagueGoods }
        }, { new: true, upsert: true }).lean();
        return result;
    }

    public static async findByBattleCode(battleCode: string, select = '') {
        const result: GVGVestigeRecType = await GVGVestigeRecModel.findOne({ battleCode }).select(select).lean();
        return result;
    }

    public static async startBattle(battleCode: string, attackHeroes: OppPlayerHeroInfo[], ce: number) {
        const result: GVGVestigeRecType = await GVGVestigeRecModel.findOneAndUpdate({ battleCode }, {
            $set: { battleTime: Date.now(), 'attackInfo.heroes': attackHeroes, 'attackInfo.ce': ce }
        }, { new: true }).lean();
        return result;
    }

    public static async battleEnd(battleCode: string, isSuccess: boolean, endTime: number, atkNewRank?: number, defNewRank?: number) {
        console.log('battleEnd', battleCode, isSuccess, endTime, atkNewRank, defNewRank)

        let update: GVGVestigeRecUpdate = { endTime };
        if(isSuccess) {
            update['attackInfo.isSuccess'] = true;
            update['defenseInfo.isSuccess'] = false;
        }
        if(atkNewRank != undefined && defNewRank != undefined) {
            update['attackInfo.newRank'] = atkNewRank;
            update['defenseInfo.newRank'] = defNewRank;
            update['attackInfo.oldRank'] = isSuccess? defNewRank: atkNewRank;
            update['defenseInfo.oldRank'] = isSuccess? atkNewRank: defNewRank;
        }

        const result: GVGVestigeRecType = await GVGVestigeRecModel.findOneAndUpdate({ battleCode }, { $set: update }, { new: true }).lean();
        return result;
    }

    public static async giveup(roleId: string, battleCode: string) {
        const result: GVGVestigeRecType = await GVGVestigeRecModel.findOneAndUpdate({ attackRoleId: roleId, battleCode }, { $set: { cancel: true, endTime: Date.now() }}, { new: true }).lean();
        return result;
    }


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

    public static async findRec(roleId: string, vestigeId: number) {
        let recs: GVGVestigeRecType[] = await GVGVestigeRecModel.find({ 
            vestigeId, $or: [{attackRoleId: roleId}, { defenseRoleId: roleId }],
            createdAt: { $gte: <Date>getTimeFunD().getBeforeDayWithHour(3) },
        }).select({ battleCode: 1, attackRoleId: 1, defenseRoleId: 1,  _id: 0, endTime: 1, attackInfo: 1, defenseInfo: 1, hasRpl: 1 }).limit(1000).lean();
        return recs;
    }
}

export const GVGVestigeRecModel = getModelForClass(GVGVestigeRec);

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