package domain

class Game(
    val grid: Grid,
    val clues: List<Clue>
) {
    val horizontalClues = clues.filterIsInstance<HorizontalClue>()
    val verticalClues = clues.filterIsInstance<SameColumnClue<ItemClass<*>, ItemClass<*>>>()
    val positionalClues = clues.filterIsInstance<PositionClue<ItemClass<*>>>()

    init {
        for (position in positionalClues) {
            val row = grid[position.item.itemType.companion]
            row.forEachIndexed { index, gameCell ->
                if (index == position.index) {
                    gameCell.selection = position.item
                } else {
                    gameCell.options.remove(position.item)
                }
            }
        }
    }

    fun areCategoriesValid(): Boolean {
        val usedCategories = mutableSetOf<ItemClassCompanion<*>>()
        for (row in grid.rows) {
            if (usedCategories.contains(row.category)) {
                return false
            }
            usedCategories.add(row.category)
        }
        return true
    }

    fun areRulesViolated(): Boolean = clues
        .any { it.isRuleViolated(grid) }
}