"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.Config = void 0;
const constants_1 = require("@scrabble-solver/constants");
const CharacterBonus_1 = require("./CharacterBonus");
const WordBonus_1 = require("./WordBonus");
class Config {
    constructor(config) {
        this.bonuses = getBonuses(config);
        this.config = config;
        this.pointsMap = getPointsMap(this.config);
    }
    get alphabet() {
        return getAlphabet(this.config);
    }
    get bingo() {
        return this.config.bingo;
    }
    get blankScore() {
        return this.config.blankScore;
    }
    get blanksCount() {
        return this.config.blanksCount;
    }
    get boardHeight() {
        return this.config.boardHeight;
    }
    get boardWidth() {
        return this.config.boardWidth;
    }
    get game() {
        return this.config.game;
    }
    get locale() {
        return this.config.locale;
    }
    get twoCharacterTiles() {
        return this.config.tiles.filter((tile) => tile.character.length === 2).map((tile) => tile.character);
    }
    getCellBonus(cell) {
        return this.bonuses.find((bonus) => bonus.matchesCellCoordinates(cell));
    }
    getCellBonusValue(cell) {
        return this.getCellBonus(cell)?.value || constants_1.NO_BONUS;
    }
    getCharacterPoints(character) {
        if (character === null) {
            return undefined;
        }
        if (character === constants_1.BLANK) {
            return this.blankScore;
        }
        return this.pointsMap[character];
    }
    getTwoCharacterTileByPrefix(character) {
        if (character.length !== 1) {
            return undefined;
        }
        return this.twoCharacterTiles.find((characters) => characters.startsWith(character.toLocaleLowerCase()));
    }
    getTilePoints(tile) {
        if (tile === null) {
            return undefined;
        }
        return tile.isBlank ? this.blankScore : this.getCharacterPoints(tile.character);
    }
    hasCharacter(character) {
        return character in this.pointsMap;
    }
    isTwoCharacterTilePrefix(character) {
        return typeof this.getTwoCharacterTileByPrefix(character) !== 'undefined';
    }
    get rackSize() {
        return this.config.rackSize;
    }
    get supportsRemainingTiles() {
        return this.tiles.every((tile) => typeof tile.count === 'number');
    }
    get tiles() {
        return this.config.tiles;
    }
    toJson() {
        return this.config;
    }
}
exports.Config = Config;
Config.fromJson = (json) => {
    return new Config(json);
};
const getBonuses = (config) => {
    return config.bonuses.map((bonus) => {
        if (bonus.type === constants_1.BONUS_CHARACTER) {
            return new CharacterBonus_1.CharacterBonus(bonus);
        }
        if (bonus.type === constants_1.BONUS_WORD) {
            return new WordBonus_1.WordBonus(bonus);
        }
        throw new Error(`Unsupported Bonus type: "${bonus.type}"`);
    });
};
const getAlphabet = (config) => config.tiles.map(({ character }) => character);
const getPointsMap = (config) => config.tiles.reduce((pointsMap, { character, score }) => ({
    ...pointsMap,
    [character]: score,
}), {});
