"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.applyAfterStatsUpdate = exports.modifyStats = exports.multiplyStats = exports.setEntityStats = void 0;
const reference_data_1 = require("@firestone-hs/reference-data");
const card_interface_1 = require("../cards/card.interface");
const _card_mappings_1 = require("../cards/impl/_card-mappings");
const utils_1 = require("../utils");
const add_minion_to_board_1 = require("./add-minion-to-board");
const attack_1 = require("./attack");
const quest_1 = require("./quest");
const setEntityStats = (entity, attack, health, board, boardHero, gameState, applyAttackAuras = true, applyHealthAuras = true) => {
    (0, add_minion_to_board_1.removeAurasFromSelf)(entity, board, boardHero, gameState, applyAttackAuras, applyHealthAuras);
    if (attack !== null) {
        entity.attack = attack;
        entity.maxAttack = attack;
    }
    if (health !== null) {
        entity.health = health;
        entity.maxHealth = health;
    }
    (0, add_minion_to_board_1.applyAurasToSelf)(entity, board, boardHero, gameState, applyAttackAuras, applyHealthAuras);
};
exports.setEntityStats = setEntityStats;
const multiplyStats = (entity, multiplier, board, hero, gameState) => {
    (0, exports.modifyStats)(entity, entity, (multiplier - 1) * entity.maxAttack, (multiplier - 1) * entity.maxHealth, board, hero, gameState);
    (0, add_minion_to_board_1.applyAurasToSelf)(entity, board, hero, gameState);
};
exports.multiplyStats = multiplyStats;
const modifyStats = (entity, source, attackAmount, healthAmount, friendlyBoard, friendlyBoardHero, gameState, registerSpectator = true, isEnchantment = true, countsAsStatsGain = true) => {
    if (!(entity === null || entity === void 0 ? void 0 : entity.maxHealth)) {
        return;
    }
    if (attackAmount === 0 && healthAmount === 0) {
        return;
    }
    if (entity.cardId === "BG29_889" || entity.cardId === "BG29_889_G") {
        const buff = entity.cardId === "BG29_889_G" ? 2 : 1;
        attackAmount += 2 * buff;
        healthAmount += 1 * buff;
    }
    if ((entity === null || entity === void 0 ? void 0 : entity.entityId) !== (source === null || source === void 0 ? void 0 : source.entityId) &&
        (0, utils_1.hasCorrectTribe)(source, friendlyBoardHero, reference_data_1.Race.ELEMENTAL, gameState.anomalies, gameState.allCards) &&
        attackAmount >= 0 &&
        healthAmount >= 0) {
        attackAmount += friendlyBoardHero.globalInfo.ElementalAttackBuff;
        healthAmount += friendlyBoardHero.globalInfo.ElementalHealthBuff;
    }
    if ((entity === null || entity === void 0 ? void 0 : entity.entityId) !== (source === null || source === void 0 ? void 0 : source.entityId) &&
        (0, utils_1.hasCorrectTribe)(source, friendlyBoardHero, reference_data_1.Race.PIRATE, gameState.anomalies, gameState.allCards) &&
        attackAmount >= 0 &&
        healthAmount >= 0) {
        attackAmount += friendlyBoardHero.globalInfo.PirateAttackBuff;
        healthAmount += friendlyBoardHero.globalInfo.PirateHealthBuff;
    }
    const otherBoardHero = gameState.gameState.player.player === friendlyBoardHero
        ? gameState.gameState.opponent.player
        : gameState.gameState.player.player;
    const neighbours = (0, attack_1.getNeighbours)(friendlyBoard, entity);
    const poetMultipliers = isEnchantment &&
        (0, utils_1.hasCorrectTribe)(entity, friendlyBoardHero, reference_data_1.Race.DRAGON, gameState.anomalies, gameState.allCards)
        ? neighbours.filter((e) => e.cardId === "BG29_813_G").length * 2 +
            friendlyBoard.filter((e) => e.cardId === "BG34_Giant_314_G").length * 2 || 1
        : 1;
    const tarecgosaMultiplier = isEnchantment && entity.cardId === "BG21_015_G" ? 2 : 1;
    const realAttackAmount = attackAmount * poetMultipliers * tarecgosaMultiplier;
    const realHealthAmount = healthAmount * poetMultipliers * tarecgosaMultiplier;
    entity.attack = Math.max(0, entity.attack + realAttackAmount);
    entity.previousAttack = entity.attack;
    entity.pendingAttackBuffs = entity.pendingAttackBuffs || [];
    entity.pendingAttackBuffs.push(realAttackAmount);
    entity.health += realHealthAmount;
    if (realAttackAmount > 0) {
        entity.maxAttack += realAttackAmount;
        if ((0, utils_1.hasCorrectTribe)(entity, friendlyBoardHero, reference_data_1.Race.DRAGON, gameState.anomalies, gameState.allCards)) {
            if (entity.cardId !== "BG26_966" && entity.cardId !== "BG26_966_G") {
                const stormbringers = friendlyBoard.filter((e) => e.cardId === "BG26_966" || e.cardId === "BG26_966_G");
                stormbringers.forEach((stormbringer) => {
                    const multiplier = stormbringer.cardId === "BG26_966_G" ? 2 : 1;
                    stormbringer.attack += multiplier * realAttackAmount;
                    gameState.spectator.registerPowerTarget(stormbringer, stormbringer, friendlyBoard, friendlyBoardHero, otherBoardHero);
                });
            }
        }
        friendlyBoard
            .filter((e) => e.cardId === "TB_BaconShop_HERO_52_Buddy" ||
            e.cardId === "TB_BaconShop_HERO_52_Buddy_G")
            .forEach((sinestra) => {
            const buff = sinestra.cardId === "TB_BaconShop_HERO_52_Buddy_G" ? 2 : 1;
            entity.health += buff;
            gameState.spectator.registerPowerTarget(sinestra, entity, friendlyBoard, friendlyBoardHero, otherBoardHero);
        });
    }
    if (realHealthAmount > 0) {
        entity.maxHealth += realHealthAmount;
        const titanicGuardians = friendlyBoard
            .filter((e) => e.entityId !== entity.entityId)
            .filter((e) => e.cardId === "TB_BaconShop_HERO_39_Buddy" ||
            e.cardId === "TB_BaconShop_HERO_39_Buddy_G");
        titanicGuardians.forEach((guardian) => {
            const buff = (guardian.cardId === "TB_BaconShop_HERO_39_Buddy_G" ? 2 : 1) * realHealthAmount;
            if (buff > 0) {
                guardian.health += buff;
                guardian.maxHealth += buff;
            }
        });
    }
    if (registerSpectator && !!source) {
        gameState.spectator.registerPowerTarget(source, entity, friendlyBoard, friendlyBoardHero, otherBoardHero);
    }
    if (countsAsStatsGain) {
        onStatsUpdate(entity, source, realAttackAmount, realHealthAmount, friendlyBoard, friendlyBoardHero, otherBoardHero, gameState);
    }
};
exports.modifyStats = modifyStats;
const onStatsUpdate = (entity, source, realAttackAmount, realHealthAmount, friendlyBoard, friendlyHero, otherHero, gameState) => {
    onStatUpdateMinions(entity, source, realAttackAmount, realHealthAmount, friendlyBoard, friendlyHero, otherHero, gameState);
    onStatUpdateQuests(entity, friendlyBoard, friendlyHero, gameState);
};
const applyAfterStatsUpdate = (gameState) => {
    for (const entity of gameState.gameState.player.board) {
        applyAfterStatsUpdateForEntity(entity, gameState.gameState.player, gameState.gameState.opponent, gameState);
    }
    for (const entity of gameState.gameState.opponent.board) {
        applyAfterStatsUpdateForEntity(entity, gameState.gameState.opponent, gameState.gameState.player, gameState);
    }
};
exports.applyAfterStatsUpdate = applyAfterStatsUpdate;
const applyAfterStatsUpdateForEntity = (entity, playerState, opponentState, gameState) => {
    entity.pendingAttackBuffs = [];
};
const onStatUpdateQuests = (entity, board, hero, gameState) => {
    var _a;
    const quests = (_a = hero.questEntities) !== null && _a !== void 0 ? _a : [];
    if (!quests.length) {
        return;
    }
    for (const quest of quests) {
        switch (quest.CardId) {
            case "BG24_Quest_123":
                (0, quest_1.onQuestProgressUpdated)(hero, quest, board, gameState);
                break;
            case "BG27_Quest_801":
                const totalAttack = board.map((e) => e.attack).reduce((a, b) => a + b, 0);
                if (totalAttack >= 35) {
                    (0, quest_1.onQuestProgressUpdated)(hero, quest, board, gameState);
                }
                break;
        }
    }
};
const onStatUpdateMinions = (entity, source, attackAmount, healthAmount, friendlyBoard, friendlyBoardHero, otherHero, gameState) => {
    if (attackAmount > 0 || healthAmount > 0) {
        for (const boardEntity of friendlyBoard) {
            const onStatsChangedImpl = _card_mappings_1.cardMappings[boardEntity.cardId];
            if ((0, card_interface_1.hasOnStatsChanged)(onStatsChangedImpl)) {
                onStatsChangedImpl.onStatsChanged(boardEntity, {
                    target: entity,
                    source: source,
                    attackAmount: attackAmount,
                    healthAmount: healthAmount,
                    board: friendlyBoard,
                    hero: friendlyBoardHero,
                    otherHero: otherHero,
                    gameState: gameState,
                });
            }
        }
    }
    if ((0, utils_1.hasCorrectTribe)(entity, friendlyBoardHero, reference_data_1.Race.ELEMENTAL, gameState.anomalies, gameState.allCards)) {
        const masterOfRealities = friendlyBoard.filter((e) => e.cardId === "BG21_036" || e.cardId === "BG21_036_G");
        masterOfRealities.forEach((master) => {
            const baseBuff = 2;
            const mult = master.cardId === "BG21_036_G" ? 2 : 1;
            (0, exports.modifyStats)(master, master, baseBuff * mult, baseBuff * mult, friendlyBoard, friendlyBoardHero, gameState);
        });
    }
    const tentaclesOfCthun = friendlyBoard
        .filter((e) => e.entityId !== entity.entityId)
        .filter((e) => e.cardId === "TB_BaconShop_HERO_29_Buddy" ||
        e.cardId === "TB_BaconShop_HERO_29_Buddy_G");
    tentaclesOfCthun.forEach((tentacle) => {
        tentacle.attack += tentacle.cardId === "TB_BaconShop_HERO_29_Buddy_G" ? 2 : 1;
        tentacle.health += tentacle.cardId === "TB_BaconShop_HERO_29_Buddy_G" ? 2 : 1;
    });
};
//# sourceMappingURL=stats.js.map