"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.CardsData = exports.hasKeyword = exports.validBonusKeywords = exports.isWhelp = void 0;
const reference_data_1 = require("@firestone-hs/reference-data");
const debug_state_1 = require("../debug-state");
const utils_1 = require("../services/utils");
const utils_2 = require("../utils");
const card_interface_1 = require("./card.interface");
const _card_mappings_1 = require("./impl/_card-mappings");
const isWhelp = (cardId, allCards) => {
    var _a;
    return (_a = allCards.getCard(cardId).mechanics) === null || _a === void 0 ? void 0 : _a.includes(reference_data_1.GameTag[reference_data_1.GameTag.WHELP]);
};
exports.isWhelp = isWhelp;
exports.validBonusKeywords = [
    reference_data_1.GameTag.TAUNT,
    reference_data_1.GameTag.DIVINE_SHIELD,
    reference_data_1.GameTag.VENOMOUS,
    reference_data_1.GameTag.POISONOUS,
    reference_data_1.GameTag.WINDFURY,
    reference_data_1.GameTag.STEALTH,
    reference_data_1.GameTag.REBORN,
];
const hasKeyword = (entity, keyword) => {
    switch (keyword) {
        case reference_data_1.GameTag.TAUNT:
            return entity.taunt;
        case reference_data_1.GameTag.DIVINE_SHIELD:
            return entity.divineShield;
        case reference_data_1.GameTag.VENOMOUS:
            return entity.venomous;
        case reference_data_1.GameTag.WINDFURY:
            return entity.windfury;
        case reference_data_1.GameTag.STEALTH:
            return entity.stealth;
        case reference_data_1.GameTag.REBORN:
            return entity.reborn;
        default:
            return false;
    }
};
exports.hasKeyword = hasKeyword;
class CardsData {
    constructor(allCards, init = true) {
        this.allCards = allCards;
        if (init) {
            this.inititialize();
        }
    }
    inititialize(validTribes, anomalies) {
        const poolWithGolden = this.allCards
            .getCards()
            .filter((card) => (0, reference_data_1.isBattlegroundsCard)(card))
            .filter((card) => { var _a; return card.isBaconPool || ((_a = this.allCards.getCard(card.battlegroundsNormalDbfId)) === null || _a === void 0 ? void 0 : _a.isBaconPool); })
            .filter((card) => { var _a; return ((_a = card.type) === null || _a === void 0 ? void 0 : _a.toUpperCase()) === reference_data_1.CardType[reference_data_1.CardType.MINION]; })
            .filter((card) => !(0, utils_2.hasMechanic)(card, reference_data_1.GameTag.BACON_BUDDY))
            .filter((card) => card.set !== 'Vanilla')
            .filter((card) => (anomalies === null || anomalies === void 0 ? void 0 : anomalies.includes("BG27_Anomaly_100"))
            ? card.techLevel >= 3
            : (anomalies === null || anomalies === void 0 ? void 0 : anomalies.includes("BG27_Anomaly_800"))
                ? card.techLevel <= 4
                : true);
        this.pool = poolWithGolden
            .filter((card) => this.isValidTribe(validTribes, card.races))
            .filter((card) => (anomalies === null || anomalies === void 0 ? void 0 : anomalies.includes("BG27_Anomaly_801"))
            ? this.isGolden(card)
            : !this.isGolden(card));
        this.minionsForTier = (0, utils_1.groupByFunction)((card) => card.techLevel)(this.pool);
        this.ghastcoilerSpawns = this.pool
            .filter((card) => card.id !== 'BGS_008')
            .filter((card) => (0, utils_2.hasMechanic)(card, reference_data_1.GameTag.DEATHRATTLE))
            .filter((card) => this.isValidTribe(validTribes, card.races))
            .map((card) => card.id);
        this.demonSpawns = this.pool.filter((card) => (0, utils_2.isCorrectTribe)(card.races, reference_data_1.Race.DEMON)).map((card) => card.id);
        this.impMamaSpawns = this.demonSpawns.filter((cardId) => cardId !== "BGS_044");
        this.gentleDjinniSpawns = this.pool
            .filter((card) => (0, utils_2.isCorrectTribe)(card.races, reference_data_1.Race.ELEMENTAL))
            .filter((card) => card.id !== "BGS_121")
            .map((card) => card.id);
        this.kilrekSpawns = this.pool
            .filter((card) => (0, utils_2.isCorrectTribe)(card.races, reference_data_1.Race.DEMON))
            .filter((card) => card.id !== "TB_BaconShop_HERO_37_Buddy")
            .map((card) => card.id);
        this.battlecryMinions = this.pool.filter((card) => (0, utils_2.hasMechanic)(card, reference_data_1.GameTag.BATTLECRY)).map((card) => card.id);
        this.deathrattleMinions = this.pool
            .filter((card) => (0, utils_2.hasMechanic)(card, reference_data_1.GameTag.DEATHRATTLE))
            .map((card) => card.id);
        this.pirateSpawns = this.pool.filter((card) => (0, utils_2.isCorrectTribe)(card.races, reference_data_1.Race.PIRATE)).map((card) => card.id);
        this.beastSpawns = this.pool.filter((card) => (0, utils_2.isCorrectTribe)(card.races, reference_data_1.Race.BEAST)).map((card) => card.id);
        this.scrapScraperSpawns = this.pool
            .filter((card) => (0, utils_2.hasMechanic)(card, reference_data_1.GameTag.MAGNETIC))
            .map((card) => card.id);
        this.endOfTurnMinions = this.pool
            .filter((card) => (0, utils_2.hasMechanic)(card, reference_data_1.GameTag.END_OF_TURN))
            .map((card) => card.id);
        this.magneticMinions = this.pool.filter((card) => (0, utils_2.hasMechanic)(card, reference_data_1.GameTag.MAGNETIC));
        this.spellcraftPool = this.allCards
            .getCards()
            .filter((c) => c.spellSchool === reference_data_1.SpellSchool[reference_data_1.SpellSchool.SPELLCRAFT])
            .filter((c) => !c.premium)
            .filter((c) => c.set === 'Battlegrounds')
            .filter((c) => _card_mappings_1.cardMappings[c.id] != null);
        this.bountyTavernSpellIds = this.allCards
            .getCards()
            .filter((c) => c.set === 'Battlegrounds' && !c.premium)
            .filter((c) => { var _a; return ((_a = c.type) === null || _a === void 0 ? void 0 : _a.toUpperCase()) === reference_data_1.CardType[reference_data_1.CardType.SPELL]; })
            .filter((c) => { var _a; return (_a = c.mechanics) === null || _a === void 0 ? void 0 : _a.includes('BACON_BOUNTY'); })
            .filter((c) => _card_mappings_1.cardMappings[c.id] != null)
            .map((c) => c.id);
        this.putricidePool1 = this.allCards
            .getCards()
            .filter((card) => card.battlegroundsPutridicePool1)
            .map((card) => card.id);
        this.putricidePool2 = this.allCards
            .getCards()
            .filter((card) => card.battlegroundsPutridicePool2)
            .map((card) => card.id);
        this.putridicePool2ForEternalSummoner = this.allCards
            .getCards()
            .filter((card) => card.battlegroundsPutridicePool2)
            .filter((card) => !card.battlegroundsPutridiceSummonerExclusion)
            .map((card) => card.id);
    }
    avengeValue(cardId) {
        const avengeImpl = _card_mappings_1.cardMappings[cardId];
        if ((0, card_interface_1.hasAvenge)(avengeImpl)) {
            return avengeImpl.baseAvengeValue(cardId);
        }
        switch (cardId) {
            case "BG25_014":
            case "BG25_014_G":
                return 1;
            case "BG21_023":
            case "BG21_023_G":
            case "BG21_001":
            case "BG21_001_G":
            case "BG22_HERO_003_Buddy":
            case "BG22_HERO_003_Buddy_G":
            case "BG26_157":
            case "BG26_157_G":
                return 2;
            case "BG27_Reward_502":
            case "BG28_967":
            case "BG28_967_G":
                return 3;
            case "BG22_HERO_305p":
            case "BG21_007":
            case "BG21_007_G":
            case "BG25_003":
            case "BG25_003_G":
            case "BG28_403":
            case "BG28_403_G":
            case "BG28_Reward_505":
            case "BG28_Reward_504":
            case "BG28_740":
            case "BG28_740_G":
            case "BG29_991":
            case "BG29_991_G":
                return 4;
            case "BG27_010":
            case "BG27_010_G":
            case "BG30_MagicItem_437":
                return 5;
            case "BG28_Reward_518":
                return 7;
            case "BG30_MagicItem_713":
                return 9;
        }
        return 0;
    }
    defaultScriptDataNum(cardId) {
        const defaultScriptDataNumImpl = _card_mappings_1.cardMappings[cardId];
        if ((0, card_interface_1.hasDefaultScriptDataNum)(defaultScriptDataNumImpl)) {
            return defaultScriptDataNumImpl.defaultScriptDataNum(cardId);
        }
        switch (cardId) {
            case "BG28_Reward_505":
            case "BG30_MagicItem_822":
            case "BG30_MagicItem_822t2":
            case "BG30_MagicItem_440":
            case "BG30_MagicItem_433":
            case "BG30_MagicItem_433t":
            case "BG30_MagicItem_700":
            case "BG30_MagicItem_918":
                return 1;
            case "BG30_MagicItem_442":
            case "BG30_MagicItem_910":
            case "BG32_MagicItem_363":
                return 3;
            default:
                return 0;
        }
    }
    getTavernLevel(cardId) {
        var _a;
        return (_a = this.allCards.getCard(cardId).techLevel) !== null && _a !== void 0 ? _a : 1;
    }
    getRandomMinionForTavernTier(tavernTier) {
        var _a;
        const minionsForTier = this.minionsForTier[tavernTier !== null && tavernTier !== void 0 ? tavernTier : 1];
        if (!(minionsForTier === null || minionsForTier === void 0 ? void 0 : minionsForTier.length)) {
            console.error('incorrect minions for tier', tavernTier);
        }
        return (_a = (0, utils_1.pickRandom)(minionsForTier)) === null || _a === void 0 ? void 0 : _a.id;
    }
    getRandomMinionForMinTavernTier(tavernTier) {
        var _a;
        const minionsForTier = this.pool.filter((m) => m.techLevel >= tavernTier);
        if (!(minionsForTier === null || minionsForTier === void 0 ? void 0 : minionsForTier.length)) {
            console.error('incorrect minions for tier', tavernTier);
        }
        return (_a = (0, utils_1.pickRandom)(minionsForTier)) === null || _a === void 0 ? void 0 : _a.id;
    }
    getRandomMechToMagnetize(tavernLimitUpper) {
        var _a;
        const magneticMechs = this.pool
            .filter((m) => { var _a; return ((_a = m.type) === null || _a === void 0 ? void 0 : _a.toUpperCase()) === reference_data_1.CardType[reference_data_1.CardType.MINION]; })
            .filter((m) => (0, utils_2.hasMechanic)(m, reference_data_1.GameTag.MODULAR));
        const pool = magneticMechs.filter((m) => m.techLevel <= tavernLimitUpper);
        return (_a = (0, utils_1.pickRandom)(pool)) === null || _a === void 0 ? void 0 : _a.id;
    }
    getRandomMagneticVolumizer(playerEntity, anomalies, tavernLimitUpper, sourceEntity, targetEntity) {
        var _a;
        const magneticVolumizers = this.magneticMinions.filter((m) => (0, utils_2.isVolumizer)(m.id, playerEntity, anomalies, this.allCards));
        const pool = magneticVolumizers.filter((m) => m.techLevel <= tavernLimitUpper);
        if (sourceEntity && targetEntity && debug_state_1.debugState.active && debug_state_1.debugState.forcedRandomPicks.length > 0) {
            const forced = debug_state_1.debugState.forcedRandomPicks.find((p) => debug_state_1.debugState.isCorrectEntity(p.source, sourceEntity) &&
                debug_state_1.debugState.isCorrectEntity(p.target, targetEntity));
            if (forced === null || forced === void 0 ? void 0 : forced.chosenCardId) {
                const inPool = pool.some((m) => m.id === forced.chosenCardId);
                if (inPool) {
                    debug_state_1.debugState.forcedRandomPicks = debug_state_1.debugState.forcedRandomPicks.filter((p) => p !== forced);
                    return forced.chosenCardId;
                }
            }
        }
        return (_a = (0, utils_1.pickRandom)(pool)) === null || _a === void 0 ? void 0 : _a.id;
    }
    getRandomDivineShield(tavernLimitUpper) {
        var _a;
        const divineShieldPool = this.pool
            .filter((m) => { var _a; return ((_a = m.type) === null || _a === void 0 ? void 0 : _a.toUpperCase()) === reference_data_1.CardType[reference_data_1.CardType.MINION]; })
            .filter((m) => (0, utils_2.hasMechanic)(m, reference_data_1.GameTag.DIVINE_SHIELD));
        const pool = divineShieldPool.filter((m) => m.techLevel <= tavernLimitUpper);
        return (_a = (0, utils_1.pickRandom)(pool)) === null || _a === void 0 ? void 0 : _a.id;
    }
    getRandomRally(tavernLimitUpper) {
        var _a;
        const targetPool = this.pool
            .filter((m) => { var _a; return ((_a = m.type) === null || _a === void 0 ? void 0 : _a.toUpperCase()) === reference_data_1.CardType[reference_data_1.CardType.MINION]; })
            .filter((m) => (0, utils_2.hasMechanic)(m, reference_data_1.GameTag.BACON_RALLY));
        const pool = targetPool.filter((m) => m.techLevel <= tavernLimitUpper);
        return (_a = (0, utils_1.pickRandom)(pool)) === null || _a === void 0 ? void 0 : _a.id;
    }
    getRandomMinionForTribe(tribe, tavernLimitUpper, excludedCards = []) {
        var _a;
        const pool = this.pool
            .filter((m) => this.isValidTribe([tribe], m.races, false))
            .filter((m) => { var _a; return ((_a = m.type) === null || _a === void 0 ? void 0 : _a.toUpperCase()) === reference_data_1.CardType[reference_data_1.CardType.MINION]; })
            .filter((m) => m.techLevel <= tavernLimitUpper)
            .filter((m) => !excludedCards.includes(m.id));
        return (_a = (0, utils_1.pickRandom)(pool)) === null || _a === void 0 ? void 0 : _a.id;
    }
    getRandomProtossMinion(tavernLimitUpper) {
        var _a;
        const pool = this.pool
            .filter((m) => { var _a; return (_a = m.mechanics) === null || _a === void 0 ? void 0 : _a.includes(reference_data_1.GameTag[reference_data_1.GameTag.PROTOSS]); })
            .filter((m) => { var _a; return ((_a = m.type) === null || _a === void 0 ? void 0 : _a.toUpperCase()) === reference_data_1.CardType[reference_data_1.CardType.MINION]; })
            .filter((m) => m.techLevel <= tavernLimitUpper);
        return (_a = (0, utils_1.pickRandom)(pool)) === null || _a === void 0 ? void 0 : _a.id;
    }
    getRandomSpellcraft(options) {
        var _a;
        const pool = this.spellcraftPool.filter((c) => options.maxTavernTier ? c.techLevel <= options.maxTavernTier : true);
        return (_a = (0, utils_1.pickRandom)(pool)) === null || _a === void 0 ? void 0 : _a.id;
    }
    isGolden(card) {
        return card.premium;
    }
    isValidTribe(validTribes, cardRaces, allowEmptyRaces = true) {
        if (!(cardRaces === null || cardRaces === void 0 ? void 0 : cardRaces.length) && allowEmptyRaces) {
            return true;
        }
        return (cardRaces !== null && cardRaces !== void 0 ? cardRaces : [])
            .map((race) => (0, utils_2.getRaceEnum)(race))
            .some((raceEnum) => raceEnum === reference_data_1.Race.ALL || !(validTribes === null || validTribes === void 0 ? void 0 : validTribes.length) || validTribes.includes(raceEnum));
    }
    getRandomTavernSpell(options) {
        return null;
    }
    getTwoCostBattlegroundsSpellIdsImplemented() {
        return this.allCards
            .getCards()
            .filter((c) => {
            var _a, _b;
            return c.set === 'Battlegrounds' &&
                !c.premium &&
                ((_a = c.cost) !== null && _a !== void 0 ? _a : 0) === 2 &&
                ((_b = c.type) === null || _b === void 0 ? void 0 : _b.toUpperCase()) === reference_data_1.CardType[reference_data_1.CardType.SPELL] &&
                _card_mappings_1.cardMappings[c.id] != null;
        })
            .map((c) => c.id);
    }
}
exports.CardsData = CardsData;
//# sourceMappingURL=cards-data.js.map