import { ApiCall } from "tsrpc";
import { DxltFun } from '../../public/dxlt';
import { FightFun } from '../../public/fight';
import { PlayerFun } from '../../public/player';
import { formatNpcData } from '../../shared/fightControl/fightFun';
import { roleDataType } from '../../shared/fightControl/fightType';
import { ReqFight, ResFight } from "../../shared/protocols/dixialeitai/PtlFight";
import { ResOpen } from '../../shared/protocols/dixialeitai/PtlOpen';
import { HongDianChange } from "../hongdian/fun";

export default async function (call: ApiCall<ReqFight, ResFight>) {
    let change: Partial<ResOpen> = {};
    let data = await DxltFun.getData(call);

    if (data.killBoss >= G.gc.dxlt_com.dayFightLayer) return call.error(globalThis.lng.dixialeitai_13);
    if (G.gc.dxlt_layer[data.curLayer].type != 1) return call.error(globalThis.lng.dixialeitai_3);
    if (data.over) return call.error(globalThis.lng.dixialeitai_4);
    if (!data.heros[call.req]) return call.error(globalThis.lng.dixialeitai_5);
    if (data.heros[call.req].attr.hp <= 0) return call.error(globalThis.lng.dixialeitai_6);

    let hero: roleDataType = JSON.parse(JSON.stringify(data.heros[call.req]));
    Object.assign(hero.attr, DxltFun.getBuff(data));

    let npc = formatNpcData(G.gc.dxlt_layer[data.curLayer].npcId);
    Object.entries(data.enemyState).forEach(role => {
        Object.assign(npc.roles[role[0]].attr, role[1]);
    });

    const result = FightFun.fight(
        [
            {
                player: call.conn.gud,
                roles: Object.fromEntries([hero].map(hero => [1, hero]))
            },
            npc
        ],
        30,
        'pve'
    );

    let _role = result.fightData[0].roles[1];
    Object.assign(data.heros[call.req].attr, { hp: _role.attr.hp, maxHp: _role.attr.maxHp });

    change.heros = data.heros;
    change.enemyState = {};

    let prize: atn[] = [];
    if (result.winSide == 0) {

        DxltFun.saodan(data, 1);
        change.over = true;
        change.item = data.item;
        change.buff = data.buff;

        if (data.saodang.mibaoNum) {
            change.mibao = (data.mibao || 0) + data.saodang.mibaoNum;
        }

        if (G.gc.dxlt_layer[data.curLayer].isBoss) {
            change.killBoss = (data.killBoss || 0) + 1;
        }

        prize.push(...G.gc.dxlt_layer[data.curLayer].price);

        if (data.saodang.prize) {
            prize.push(...data.saodang.prize);
        }

        if (data.saodang.shop) {
            DxltFun.changeShop(data, change);
        }

        DxltFun.passLayerChange(data, change);
    } else {
        Object.entries(result.fightData[1].roles).forEach(role => {
            change.enemyState[role[0]] = { hp: role[1].attr.hp, maxHp: role[1].attr.maxHp };
        });
    }

    if (prize.length > 0) {
        await PlayerFun.sendPrize(call, prize);
    }

    await DxltFun.changeData(call, change);

    HongDianChange.sendChangeKey(call.uid, ['dxlthd']);

    call.succ({
        change: change,
        result: result,
        fightPrize: data.saodang || {},
        prize: prize
    });
}