"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.rememberDeathrattles = exports.applySoulJugglerEffect = exports.dealDamageToAllMinions = exports.applyWheneverMinionDiesEffect = exports.applyAfterMinionDiesEffect = exports.handleAfterMinionKillsEffect = exports.handleWheneverMinionsKillEffect = exports.applyRecurringNightmareDeathrattleEffect = exports.applyLeapFroggerEffect = exports.applyEarthInvocationEnchantment = exports.applyFireInvocationEnchantment = exports.applyWaterInvocationEnchantment = exports.applyLightningInvocationEnchantment = exports.computeDeathrattleMultiplier = void 0;
const reference_data_1 = require("@firestone-hs/reference-data");
const eternal_portrait_1 = require("../cards/impl/trinket/eternal-portrait");
const divine_shield_1 = require("../keywords/divine-shield");
const taunt_1 = require("../keywords/taunt");
const utils_1 = require("../services/utils");
const simulate_bgs_battle_1 = require("../simulate-bgs-battle");
const utils_2 = require("../utils");
const card_interface_1 = require("../cards/card.interface");
const _card_mappings_1 = require("../cards/impl/_card-mappings");
const attack_1 = require("./attack");
const deathrattle_spawns_1 = require("./deathrattle-spawns");
const remembered_deathrattle_1 = require("./remembered-deathrattle");
const stats_1 = require("./stats");
const DEATHRATTLES_REQUIRE_MEMORY = ["BG31_999", "BG31_999_G"];
const DOUBLE_DEATHRATTLE_CARD_IDS = [
    "BG27_518",
    "BG28_843",
    "BG34_Giant_376",
];
const TRIPLE_DEATHRATTLE_CARD_IDS = ["BG27_518_G", "BG34_Giant_376_G"];
const computeDeathrattleMultiplier = (board, boardHero, deadEntity, sharedState) => {
    var _a, _b, _c, _d, _e, _f;
    const cardIds = [...board.map((e) => e.cardId), ...((_b = (_a = boardHero.secrets) === null || _a === void 0 ? void 0 : _a.map((e) => e.cardId)) !== null && _b !== void 0 ? _b : [])];
    const triggerMult = cardIds.some((cardId) => TRIPLE_DEATHRATTLE_CARD_IDS.includes(cardId))
        ? 3
        : cardIds.some((cardId) => DOUBLE_DEATHRATTLE_CARD_IDS.includes(cardId))
            ? 2
            : 1;
    const titus = board.filter((entity) => entity.cardId === "BG25_354").length;
    const goldenTitus = board.filter((entity) => entity.cardId === "BG25_354_G").length;
    const deathlyPhylacteries = boardHero.trinkets.filter((t) => t.cardId === "BG30_MagicItem_700" && t.scriptDataNum1 > 0).length;
    const tombs = (_e = (_d = (_c = boardHero.questRewardEntities) === null || _c === void 0 ? void 0 : _c.filter((entity) => entity.cardId === "BG27_Reward_803")) === null || _d === void 0 ? void 0 : _d.length) !== null && _e !== void 0 ? _e : 0;
    const echoesOfArgus = sharedState.anomalies.includes("BG27_Anomaly_802") ? 1 : 0;
    const scourgeMultiplier = ((_f = deadEntity.additionalCards) === null || _f === void 0 ? void 0 : _f.includes("RLK_912")) ? 2 : 1;
    const multiplier = scourgeMultiplier * (triggerMult + deathlyPhylacteries + titus + 2 * goldenTitus + tombs + echoesOfArgus);
    return multiplier;
};
exports.computeDeathrattleMultiplier = computeDeathrattleMultiplier;
const applyLightningInvocationEnchantment = (boardWithDeadEntity, boardWithDeadEntityHero, deadEntity, otherBoard, otherBoardHero, gameState) => {
    const multiplier = (deadEntity === null || deadEntity === void 0 ? void 0 : deadEntity.cardId) === "BG22_HERO_001_Buddy_G" ? 2 : 1;
    const previousVenomous = deadEntity.venomous;
    deadEntity.venomous = false;
    for (let i = 0; i < multiplier; i++) {
        const targets = (0, utils_1.pickMultipleRandomDifferent)(otherBoard, 5);
        for (const target of targets) {
            (0, attack_1.dealDamageToMinion)(target, otherBoard, otherBoardHero, deadEntity, 1, boardWithDeadEntity, boardWithDeadEntityHero, gameState);
        }
    }
    deadEntity.venomous = previousVenomous;
};
exports.applyLightningInvocationEnchantment = applyLightningInvocationEnchantment;
const applyWaterInvocationEnchantment = (boardWithDeadEntity, boardWithDeadEntityHero, otherHero, deadEntity, sourceEntity, gameState) => {
    const multiplier = (deadEntity === null || deadEntity === void 0 ? void 0 : deadEntity.cardId) === "BG22_HERO_001_Buddy_G" ? 2 : 1;
    for (let i = 0; i < multiplier; i++) {
        const validBoard = boardWithDeadEntity.filter((e) => e.health > 0 && !e.definitelyDead);
        const target = validBoard[validBoard.length - 1];
        if (!!target) {
            (0, taunt_1.updateTaunt)(target, true, boardWithDeadEntity, boardWithDeadEntityHero, otherHero, gameState);
            (0, divine_shield_1.updateDivineShield)(target, boardWithDeadEntity, boardWithDeadEntityHero, otherHero, true, gameState);
        }
    }
};
exports.applyWaterInvocationEnchantment = applyWaterInvocationEnchantment;
const applyFireInvocationEnchantment = (boardWithDeadEntity, boardWithDeadEntityHero, deadEntity, sourceEntity, gameState) => {
    const multiplier = (deadEntity === null || deadEntity === void 0 ? void 0 : deadEntity.cardId) === "BG22_HERO_001_Buddy_G" ? 2 : 1;
    for (let i = 0; i < multiplier; i++) {
        const target = boardWithDeadEntity.filter((e) => e.health > 0 && !e.definitelyDead)[0];
        if (!!target) {
            (0, stats_1.modifyStats)(target, sourceEntity, target.attack, 0, boardWithDeadEntity, boardWithDeadEntityHero, gameState);
        }
    }
};
exports.applyFireInvocationEnchantment = applyFireInvocationEnchantment;
const applyEarthInvocationEnchantment = (boardWithDeadEntity, deadEntity, sourceEntity, gameState) => {
    const multiplier = (deadEntity === null || deadEntity === void 0 ? void 0 : deadEntity.cardId) === "BG22_HERO_001_Buddy_G" ? 2 : 1;
    for (let i = 0; i < multiplier; i++) {
        const minionsGrantedDeathrattle = (0, utils_1.pickMultipleRandomDifferent)(boardWithDeadEntity, 4);
        minionsGrantedDeathrattle.forEach((minion) => {
            minion.enchantments.push({
                cardId: "BG22_HERO_001p_t1e",
                originEntityId: deadEntity === null || deadEntity === void 0 ? void 0 : deadEntity.entityId,
                timing: gameState.sharedState.currentEntityId++,
            });
            gameState.spectator.registerPowerTarget(sourceEntity, minion, boardWithDeadEntity, null, null);
        });
    }
};
exports.applyEarthInvocationEnchantment = applyEarthInvocationEnchantment;
const applyLeapFroggerEffect = (boardWithDeadEntity, boardWithDeadEntityHero, deadEntity, isPremium, gameState, multiplier) => {
    var _a;
    multiplier = (_a = multiplier !== null && multiplier !== void 0 ? multiplier : deadEntity.deathrattleRepeats) !== null && _a !== void 0 ? _a : 1;
    const buffed = (0, utils_2.grantRandomStats)(deadEntity, boardWithDeadEntity, boardWithDeadEntityHero, multiplier * (isPremium ? 2 : 1), multiplier * (isPremium ? 2 : 1), reference_data_1.Race.BEAST, false, gameState);
    if (buffed) {
        const enchantmentCardId = isPremium
            ? "BG21_000_Ge"
            : "BG21_000e";
        buffed.enchantments.push({
            cardId: enchantmentCardId,
            originEntityId: deadEntity.entityId,
            repeats: multiplier > 1 ? multiplier : 1,
            timing: gameState.sharedState.currentEntityId++,
        });
        const leapfroggerDeathrattles = (0, remembered_deathrattle_1.groupLeapfroggerDeathrattles)(buffed.enchantments);
        const nonLeapfroggerEnchants = buffed.enchantments.filter((d) => { var _a; return !((_a = d.cardId) === null || _a === void 0 ? void 0 : _a.startsWith("BG21_000")); });
        const newEnchants = [...leapfroggerDeathrattles, ...nonLeapfroggerEnchants];
        buffed.enchantments = newEnchants;
    }
};
exports.applyLeapFroggerEffect = applyLeapFroggerEffect;
const applyRecurringNightmareDeathrattleEffect = (boardWithDeadEntity, boardWithDeadEntityHero, deadEntity, isPremium, gameState, multiplier = 1) => {
};
exports.applyRecurringNightmareDeathrattleEffect = applyRecurringNightmareDeathrattleEffect;
const handleWheneverMinionsKillEffect = (board, hero, otherBoard, otherHero, gameState) => {
    handleWheneverMinionsKillEffectForBoard(board, hero, otherBoard, otherHero, gameState);
};
exports.handleWheneverMinionsKillEffect = handleWheneverMinionsKillEffect;
const handleWheneverMinionsKillEffectForBoard = (board, hero, otherBoard, otherHero, gameState) => {
    for (let i = 0; i < board.length; i++) {
        if (board[i].health <= 0 || board[i].definitelyDead) {
            const futureDeadEntity = board[i];
            const killer = futureDeadEntity.lastAffectedByEntity;
            if (!killer) {
                return;
            }
            if (killer.friendly !== futureDeadEntity.friendly) {
                for (const heroPower of otherHero.heroPowers) {
                    if (heroPower.cardId === "BG20_HERO_100p" && !(0, utils_2.isDead)(killer)) {
                        (0, stats_1.modifyStats)(killer, otherHero, 1, 0, otherBoard, otherHero, gameState);
                    }
                }
            }
        }
    }
};
const handleAfterMinionKillsEffect = (deadEntity, deadEntityIndexFromRight, boardWithDeadEntity, boardWithDeadEntityHero, otherBoard, otherBoardHero, gameState) => {
};
exports.handleAfterMinionKillsEffect = handleAfterMinionKillsEffect;
const applyAfterMinionDiesEffect = (deadEntity, deadEntityIndexFromRight, boardWithDeadEntity, boardWithDeadEntityHero, otherBoard, otherBoardHero, gameState) => {
    if ((0, utils_2.hasCorrectTribe)(deadEntity, boardWithDeadEntityHero, reference_data_1.Race.DEMON, gameState.anomalies, gameState.allCards)) {
        (0, exports.applySoulJugglerEffect)(boardWithDeadEntity, boardWithDeadEntityHero, otherBoard, otherBoardHero, gameState);
    }
};
exports.applyAfterMinionDiesEffect = applyAfterMinionDiesEffect;
const applyWheneverMinionDiesEffect = (deadEntity, deadEntityIndexFromRight, boardWithDeadEntity, boardWithDeadEntityHero, otherBoard, otherBoardHero, gameState) => {
    var _a;
    if ((0, utils_2.hasCorrectTribe)(deadEntity, boardWithDeadEntityHero, reference_data_1.Race.BEAST, gameState.anomalies, gameState.allCards)) {
        applyScavengingHyenaEffect(boardWithDeadEntity, boardWithDeadEntityHero, gameState);
    }
    if ((0, utils_2.hasCorrectTribe)(deadEntity, boardWithDeadEntityHero, reference_data_1.Race.MECH, gameState.anomalies, gameState.allCards)) {
        applyJunkbotEffect(boardWithDeadEntity, boardWithDeadEntityHero, gameState);
    }
    if ((0, utils_2.hasCorrectTribe)(deadEntity, boardWithDeadEntityHero, reference_data_1.Race.MURLOC, gameState.anomalies, gameState.allCards)) {
        removeOldMurkEyeAttack(boardWithDeadEntity, boardWithDeadEntityHero, gameState);
        removeOldMurkEyeAttack(otherBoard, otherBoardHero, gameState);
    }
    if ((0, utils_2.hasCorrectTribe)(deadEntity, boardWithDeadEntityHero, reference_data_1.Race.ELEMENTAL, gameState.anomalies, gameState.allCards)) {
        applyMossOfTheSchlossEffect(deadEntity, boardWithDeadEntity, boardWithDeadEntityHero, gameState);
    }
    for (const entity of boardWithDeadEntity) {
        const impl = _card_mappings_1.cardMappings[entity.cardId];
        if ((0, card_interface_1.hasOnAfterFriendlyMinionDeath)(impl)) {
            impl.onAfterFriendlyMinionDeath(entity, {
                deadEntity,
                board: boardWithDeadEntity,
                hero: boardWithDeadEntityHero,
                gameState,
            });
        }
    }
    if (deadEntity.taunt) {
        applyQirajiHarbringerEffect(boardWithDeadEntity, boardWithDeadEntityHero, deadEntityIndexFromRight, gameState);
    }
    if (deadEntity.cardId === "BG25_008" ||
        deadEntity.cardId === "BG25_008_G") {
        applyEternalKnightEffect(boardWithDeadEntity, boardWithDeadEntityHero, gameState);
    }
    boardWithDeadEntity
        .filter((e) => { var _a; return (_a = e.additionalCards) === null || _a === void 0 ? void 0 : _a.includes("BG26_tt_004"); })
        .forEach((e) => {
        (0, stats_1.modifyStats)(e, null, 1, 0, boardWithDeadEntity, boardWithDeadEntityHero, gameState);
    });
    applyRotHideGnollEffect(boardWithDeadEntity, boardWithDeadEntityHero, gameState);
    if (deadEntity.health < 0 &&
        gameState.sharedState.currentAttackerEntityId != null &&
        gameState.sharedState.currentAttackerEntityId === ((_a = deadEntity.lastAffectedByEntity) === null || _a === void 0 ? void 0 : _a.entityId)) {
        if (deadEntity.lastAffectedByEntity.cardId === "TRL_232") {
            const newEntities = (0, deathrattle_spawns_1.spawnEntities)("TRL_232t", 1, otherBoard, otherBoardHero, boardWithDeadEntity, boardWithDeadEntityHero, gameState, !deadEntity.friendly, false);
            otherBoard.splice(otherBoard.length - deadEntityIndexFromRight, 0, ...newEntities);
        }
    }
};
exports.applyWheneverMinionDiesEffect = applyWheneverMinionDiesEffect;
const dealDamageToAllMinions = (board1, board1Hero, board2, board2Hero, damageSource, damageDealt, gameState) => {
    if (board1.length === 0 && board2.length === 0) {
        return;
    }
    for (let i = 0; i < board1.length; i++) {
        (0, attack_1.dealDamageToMinion)(board1[i], board1, board1Hero, damageSource, damageDealt, board2, board2Hero, gameState);
    }
    for (let i = 0; i < board2.length; i++) {
        (0, attack_1.dealDamageToMinion)(board2[i], board2, board2Hero, damageSource, damageDealt, board1, board1Hero, gameState);
    }
};
exports.dealDamageToAllMinions = dealDamageToAllMinions;
const applySoulJugglerEffect = (boardWithJugglers, boardWithJugglersHero, boardToAttack, boardToAttackHero, gameState) => {
    if (boardWithJugglers.length === 0 && boardToAttack.length === 0) {
        return;
    }
    const jugglers = boardWithJugglers.filter((entity) => entity.cardId === "BGS_002");
    for (const juggler of jugglers) {
        const target = (0, utils_2.getRandomMinionWithHighestHealth)(boardToAttack);
        gameState.spectator.registerPowerTarget(juggler, target, boardWithJugglers, boardWithJugglersHero, boardToAttackHero);
        (0, attack_1.dealDamageToMinion)(target, boardToAttack, boardToAttackHero, juggler, 4, boardWithJugglers, boardWithJugglersHero, gameState);
    }
    const goldenJugglers = boardWithJugglers.filter((entity) => entity.cardId === "TB_BaconUps_075");
    for (const juggler of goldenJugglers) {
        for (let i = 0; i < 2; i++) {
            const target = (0, utils_2.getRandomMinionWithHighestHealth)(boardToAttack);
            gameState.spectator.registerPowerTarget(juggler, target, boardWithJugglers, boardWithJugglersHero, boardToAttackHero);
            (0, attack_1.dealDamageToMinion)(target, boardToAttack, boardToAttackHero, juggler, 4, boardWithJugglers, boardWithJugglersHero, gameState);
        }
    }
};
exports.applySoulJugglerEffect = applySoulJugglerEffect;
const applyScavengingHyenaEffect = (board, boardWithDeadEntityHero, gameState) => {
    for (let i = 0; i < board.length; i++) {
        if (board[i].cardId === "BG_EX1_531") {
            (0, stats_1.modifyStats)(board[i], null, 2, 1, board, boardWithDeadEntityHero, gameState);
            gameState.spectator.registerPowerTarget(board[i], board[i], board, null, null);
        }
        else if (board[i].cardId === "TB_BaconUps_043") {
            (0, stats_1.modifyStats)(board[i], null, 4, 2, board, boardWithDeadEntityHero, gameState);
            gameState.spectator.registerPowerTarget(board[i], board[i], board, null, null);
        }
    }
};
const applyEternalKnightEffect = (board, hero, gameState) => {
    for (let i = 0; i < board.length; i++) {
        if (board[i].cardId === "BG25_008" ||
            board[i].cardId === "BG25_008_G") {
            const multiplier = board[i].cardId === "BG25_008_G" ? 2 : 1;
            (0, stats_1.modifyStats)(board[i], null, multiplier * eternal_portrait_1.eternalKnightAttack, multiplier * eternal_portrait_1.eternalKnightHealth, board, hero, gameState);
            gameState.spectator.registerPowerTarget(board[i], board[i], board, null, null);
        }
    }
};
const applyRotHideGnollEffect = (board, hero, gameState) => {
    for (let i = 0; i < board.length; i++) {
        if (board[i].cardId === "BG25_013" || board[i].cardId === "BG25_013_G") {
            const multiplier = board[i].cardId === "BG25_013_G" ? 2 : 1;
            (0, stats_1.modifyStats)(board[i], null, multiplier * 1, 0, board, hero, gameState);
            gameState.spectator.registerPowerTarget(board[i], board[i], board, null, null);
        }
    }
};
const applyMossOfTheSchlossEffect = (deadEntity, board, hero, gameState) => {
    board
        .filter((e) => e.cardId === "BG30_111" || e.cardId === "BG30_111_G")
        .filter((e) => e.abiityChargesLeft > 0)
        .forEach((entity) => {
        (0, stats_1.modifyStats)(entity, null, deadEntity.maxAttack, deadEntity.maxHealth, board, hero, gameState);
        entity.abiityChargesLeft--;
        gameState.spectator.registerPowerTarget(entity, entity, board, null, null);
    });
};
const applyJunkbotEffect = (board, hero, gameState) => {
    for (let i = 0; i < board.length; i++) {
        if (board[i].cardId === "GVG_106") {
            (0, stats_1.modifyStats)(board[i], board[i], 2, 2, board, hero, gameState);
        }
    }
};
const applyQirajiHarbringerEffect = (board, hero, deadEntityIndexFromRight, gameState) => {
};
const rememberDeathrattles = (fish, inputDeadEntities, cardsData, allCards, sharedState) => {
    var _a, _b;
    const deadEntities = inputDeadEntities.filter((e) => !(0, utils_2.isFish)(e));
    if (!(deadEntities === null || deadEntities === void 0 ? void 0 : deadEntities.length)) {
        return;
    }
    if (((_a = fish.rememberedDeathrattles) === null || _a === void 0 ? void 0 : _a.length) > 100) {
        return;
    }
    const debug = deadEntities.some((e) => e.cardId === "BG32_431");
    const validDeathrattles = deadEntities
        .filter((entity) => { var _a; return (_a = allCards.getCard(entity.cardId).mechanics) === null || _a === void 0 ? void 0 : _a.includes(reference_data_1.GameTag[reference_data_1.GameTag.DEATHRATTLE]); })
        .filter((e) => !DEATHRATTLES_REQUIRE_MEMORY.includes(e.cardId) || e.memory)
        .map((entity) => {
        const result = {
            cardId: entity.cardId,
            repeats: 1,
            timing: sharedState.currentEntityId++,
            memory: entity.memory,
            tagScriptDataNum1: entity.scriptDataNum1,
            tagScriptDataNum2: entity.scriptDataNum2,
        };
        return result;
    });
    const validEnchantments = deadEntities
        .map((entity) => entity.enchantments)
        .reduce((a, b) => a.concat(b), [])
        .flatMap((enchantment) => {
        var _a;
        const result = {
            cardId: enchantment.cardId,
            repeats: (_a = enchantment.repeats) !== null && _a !== void 0 ? _a : 1,
            timing: sharedState.currentEntityId++,
        };
        return result;
    })
        .filter((enchantment) => (0, simulate_bgs_battle_1.isValidDeathrattleEnchantment)(enchantment.cardId));
    const deadEntityRememberedDeathrattles = (_b = deadEntities
        .filter((e) => { var _a; return !!((_a = e.rememberedDeathrattles) === null || _a === void 0 ? void 0 : _a.length); })
        .filter((e) => e.entityId !== fish.rebornFromEntityId)
        .filter((e) => !DEATHRATTLES_REQUIRE_MEMORY.includes(e.cardId) || e.memory)
        .flatMap((e) => e.rememberedDeathrattles)) !== null && _b !== void 0 ? _b : [];
    const newDeathrattles = [...validDeathrattles, ...validEnchantments, ...deadEntityRememberedDeathrattles];
    if (newDeathrattles.length > 0) {
        if ((0, utils_2.isFish)(fish) && (0, utils_2.isGolden)(fish.cardId, allCards)) {
            const doubleDr = newDeathrattles.reduce((res, current) => res.concat([current, current]), []);
            fish.rememberedDeathrattles = [...(fish.rememberedDeathrattles || []), ...doubleDr];
        }
        else {
            fish.rememberedDeathrattles = [...(fish.rememberedDeathrattles || []), ...newDeathrattles];
        }
        if (newDeathrattles.some((d) => { var _a; return (_a = d.cardId) === null || _a === void 0 ? void 0 : _a.startsWith("BG21_000"); })) {
            const leapfroggerDeathrattles = (0, remembered_deathrattle_1.groupLeapfroggerDeathrattles)(fish.rememberedDeathrattles);
            fish.rememberedDeathrattles = [
                ...fish.rememberedDeathrattles.filter((d) => { var _a; return !((_a = d.cardId) === null || _a === void 0 ? void 0 : _a.startsWith("BG21_000")); }),
                ...leapfroggerDeathrattles,
            ];
        }
    }
};
exports.rememberDeathrattles = rememberDeathrattles;
const removeOldMurkEyeAttack = (boardWithDeadEntity, hero, gameState) => {
};
//# sourceMappingURL=deathrattle-effects.js.map