import Testing
@testable import SoliCards

@Suite("AutoCompleter Tests")
struct AutoCompleterTests {
    let rules = KlondikeRules()

    @Test("Finds ace to move to empty foundation")
    func findAceMove() {
        let ace = Card(suit: .hearts, rank: .ace, isFaceUp: true)
        var snapshot = emptySnapshot()
        snapshot.tableaus[0] = [ace]

        let result = AutoCompleter.findNextAutoMove(state: snapshot, rules: rules)
        #expect(result != nil)
        #expect(result?.to == .foundation(0))
    }

    @Test("Finds card to build on foundation")
    func findFoundationBuild() {
        let ace = Card(suit: .hearts, rank: .ace, isFaceUp: true)
        let two = Card(suit: .hearts, rank: .two, isFaceUp: true)
        var snapshot = emptySnapshot()
        snapshot.foundations[0] = [ace]
        snapshot.tableaus[0] = [two]

        let result = AutoCompleter.findNextAutoMove(state: snapshot, rules: rules)
        #expect(result != nil)
        #expect(result?.from == .tableau(0))
        #expect(result?.to == .foundation(0))
    }

    @Test("Returns nil when no moves available")
    func noMovesAvailable() {
        let snapshot = emptySnapshot()
        let result = AutoCompleter.findNextAutoMove(state: snapshot, rules: rules)
        #expect(result == nil)
    }

    @Test("Finds waste pile ace")
    func findWasteAce() {
        let ace = Card(suit: .spades, rank: .ace, isFaceUp: true)
        var snapshot = emptySnapshot()
        snapshot.waste = [ace]

        let result = AutoCompleter.findNextAutoMove(state: snapshot, rules: rules)
        #expect(result != nil)
        #expect(result?.from == .waste)
    }

    @Test("Finds free cell card for FreeCell variant")
    func findFreeCellMove() {
        let freeCellRules = FreeCellRules()
        let ace = Card(suit: .diamonds, rank: .ace, isFaceUp: true)
        var snapshot = GameSnapshot(
            tableaus: Array(repeating: [], count: 8),
            foundations: [[], [], [], []],
            stock: [],
            waste: [],
            freeCells: [ace, nil, nil, nil],
            moves: 0,
            score: 0
        )

        let result = AutoCompleter.findNextAutoMove(state: snapshot, rules: freeCellRules)
        #expect(result != nil)
        #expect(result?.from == .freeCell(0))
    }

    private func emptySnapshot() -> GameSnapshot {
        GameSnapshot(
            tableaus: Array(repeating: [], count: 7),
            foundations: [[], [], [], []],
            stock: [],
            waste: [],
            freeCells: [],
            moves: 0,
            score: 0
        )
    }
}
