import { ConfigType } from '../config.js';
import GridData from '../grid.js';
import { State } from '../primitives.js';
import AreaNumberSymbol from '../symbols/areaNumberSymbol.js';
import NumberSymbol from '../symbols/numberSymbol.js';
import Rule from './rule.js';
class OffByXRule extends Rule {
    /**
     * **All numbers are off by &lt;number&gt;**
     *
     * @param number - The number that all cells are off by.
     */
    constructor(number) {
        super();
        Object.defineProperty(this, "number", {
            enumerable: true,
            configurable: true,
            writable: true,
            value: number
        });
        this.number = number;
    }
    get id() {
        return `off_by_x`;
    }
    get explanation() {
        return `All numbers are off by ${this.number}`;
    }
    get configs() {
        return OffByXRule.CONFIGS;
    }
    createExampleGrid() {
        if (this.number < 1 || this.number >= OffByXRule.EXAMPLE_GRID.length) {
            return GridData.create(['bbbbb', 'bbwbb', 'bbbbb', 'bbbbb']).addSymbol(new AreaNumberSymbol(2, 1, this.number + 1));
        }
        return OffByXRule.EXAMPLE_GRID[this.number - 1];
    }
    get searchVariants() {
        return OffByXRule.SEARCH_VARIANTS;
    }
    validateGrid(_grid) {
        return { state: State.Incomplete };
    }
    onSymbolValidation(grid, symbol, _validator) {
        if (symbol instanceof NumberSymbol) {
            const counts = symbol.countTiles(grid);
            if (counts.completed > symbol.number + this.number ||
                counts.possible < symbol.number - this.number ||
                (counts.completed > symbol.number - this.number &&
                    counts.possible < symbol.number + this.number)) {
                return State.Error;
            }
            else if ((counts.completed === symbol.number + this.number ||
                counts.completed === symbol.number - this.number) &&
                counts.completed === counts.possible) {
                return State.Satisfied;
            }
            else {
                return State.Incomplete;
            }
        }
        else {
            return undefined;
        }
    }
    copyWith({ number }) {
        return new OffByXRule(number ?? this.number);
    }
    withNumber(number) {
        return this.copyWith({ number });
    }
}
Object.defineProperty(OffByXRule, "CONFIGS", {
    enumerable: true,
    configurable: true,
    writable: true,
    value: Object.freeze([
        {
            type: ConfigType.Number,
            default: 1,
            min: 1,
            field: 'number',
            description: 'Number',
            configurable: true,
        },
    ])
});
Object.defineProperty(OffByXRule, "EXAMPLE_GRID", {
    enumerable: true,
    configurable: true,
    writable: true,
    value: Object.freeze([
        GridData.create(['bbbbb', 'bwbwb', 'bbwwb', 'bbbbb']).withSymbols([
            new AreaNumberSymbol(1, 1, 2),
            new AreaNumberSymbol(3, 2, 2),
        ]),
        GridData.create(['bbbbb', 'bwbwb', 'bbbwb', 'bwwwb']).withSymbols([
            new AreaNumberSymbol(1, 1, 3),
            new AreaNumberSymbol(3, 3, 3),
        ]),
        GridData.create(['bbbbw', 'bwbbw', 'bbbbw', 'bwwww']).withSymbols([
            new AreaNumberSymbol(1, 1, 4),
            new AreaNumberSymbol(4, 3, 4),
        ]),
        GridData.create(['bbbbw', 'bwbbw', 'bbbww', 'wwwww']).withSymbols([
            new AreaNumberSymbol(1, 1, 5),
            new AreaNumberSymbol(4, 3, 5),
        ]),
        GridData.create(['bbbww', 'bwbww', 'bbbww', 'wwwww']).withSymbols([
            new AreaNumberSymbol(1, 1, 6),
            new AreaNumberSymbol(4, 3, 6),
        ]),
        GridData.create(['wbbww', 'bbwww', 'bbwww', 'wwwww']).withSymbols([
            new AreaNumberSymbol(0, 0, 7),
            new AreaNumberSymbol(4, 3, 7),
        ]),
        GridData.create(['wbbww', 'bwwww', 'bwwww', 'wwwww']).withSymbols([
            new AreaNumberSymbol(0, 0, 8),
            new AreaNumberSymbol(4, 3, 8),
        ]),
        GridData.create(['wbwww', 'bwwww', 'wwwww', 'wwwww']).withSymbols([
            new AreaNumberSymbol(0, 0, 9),
            new AreaNumberSymbol(4, 3, 9),
        ]),
    ])
});
Object.defineProperty(OffByXRule, "SEARCH_VARIANTS", {
    enumerable: true,
    configurable: true,
    writable: true,
    value: [new OffByXRule(1).searchVariant()]
});
export default OffByXRule;
export const instance = new OffByXRule(1);
