import { ApiCall } from "tsrpc";
import { FightFun } from '../../../public/fight';
import { PlayerFun } from '../../../public/player';
import { ReqFight, ResFight } from "../../../shared/protocols/hbzb/zbs/PtlFight";

export default async function (call: ApiCall<ReqFight, ResFight>) {
    let dbData = await G.mongodb.cPlayerInfo('hbzbZbs').findOne({ uid: call.uid, type: 'hbzbZbs' });
    let data = dbData.data;
    if(!data) return call.errorCode(1);
    //战败CD
    if (data.failCd && data.failCd + G.gc.hbzb.zbsFightFailCd > G.time) return call.errorCode(0);
    //挑战次数
    if (data.useFightNum >= data.buyFightNum + G.gc.hbzb.zbsFightNum) return call.errorCode(-1);

    //选出战斗目标
    let enemy = data.enemy.find(e => e.data.player.uid == call.req.uid);
    if (!enemy) return call.errorCode(-2);

    //判断目标此时的排名已经发生了变化
    let eRank = (await G.clientCross.callApi('hbzb/zbs/GetStatus', { uid: enemy.data.player.uid })).res.status;
    if (eRank != enemy.rank) return call.errorCode(-4);

    let change: ResFight['change'] = {};
    //获取我的最新排名
    let mRank = (await G.clientCross.callApi('hbzb/zbs/GetStatus', { uid: call.uid })).res.status;
    let my = await call.conn.getDefaultFightData();
    let result = FightFun.fight([my, enemy.data]);

    //记录排名，前端显示需要
    if(!result.otherData)result.otherData={};
    result.otherData['userRank'] = mRank;
    result.otherData['enemyRank'] = eRank;

    if (result.winSide == 0 && mRank > eRank) {
        //交换位置
        G.crossmongodb.collection("hbzb_user_cross").updateOne({
            uid: call.uid
            },
            {$set: {
                rank: eRank
            }}
        )
        G.crossmongodb.collection("hbzb_user_cross").updateOne({
            uid: enemy.data.player.uid
            },
            {$set: {
                rank: mRank
            }}
        )
        
        //交换排名
        result.otherData['userRank'] = eRank;
        result.otherData['enemyRank'] = mRank;
    }

    //记录战报
    G.clientCross?.sendMsg('msg_cross/HbzbZbsLog', {
        uid: call.uid,
        toUid: enemy.data.player.uid,
        log: result
    });

    //更新战败cd时间
    change.useFightNum = data.useFightNum + 1;
    if (result.winSide != 0) change.failCd = G.time;

    G.mongodb.cPlayerInfo('hbzbZbs').updateOne(
        { uid: call.uid, type: 'hbzbZbs' },
        {
            $set: G.mongodb.createTreeObj(...Object.entries(change).map(v => {
                return {
                    key: `data.${v[0]}`,
                    val: v[1]
                };
            }))
        }
    );
    
    //发放奖励
    let prize = result.winSide == 0 ? G.gc.hbzb.zbsFightWinPrize : G.gc.hbzb.zbsFightFailPrize;
    await PlayerFun.sendPrize(call, prize);

    call.succ({
        change: change,
        result: result,
        prize: prize
    });
}