import Testing
@testable import SoliCards

@Suite("GameState Tests")
struct GameStateTests {

    @Test("Snapshot captures current state")
    func snapshotCapture() {
        let state = GameState()
        let card = Card(suit: .hearts, rank: .ace, isFaceUp: true)
        state.tableaus = [[card]]
        state.foundations = [[], [], [], []]
        state.moves = 5
        state.score = 100

        let snapshot = state.snapshot()
        #expect(snapshot.tableaus[0].count == 1)
        #expect(snapshot.moves == 5)
        #expect(snapshot.score == 100)
    }

    @Test("Restore from snapshot")
    func restoreFromSnapshot() {
        let state = GameState()
        let card = Card(suit: .spades, rank: .king, isFaceUp: true)
        let snapshot = GameSnapshot(
            tableaus: [[card]],
            foundations: [[], [], [], []],
            stock: [],
            waste: [],
            freeCells: [],
            moves: 10,
            score: 50
        )

        state.restore(from: snapshot)
        #expect(state.tableaus[0].count == 1)
        #expect(state.moves == 10)
        #expect(state.score == 50)
    }

    @Test("Push and pop history")
    func historyStack() {
        let state = GameState()
        state.tableaus = [[]]
        state.foundations = [[], [], [], []]
        state.moves = 0
        state.score = 0

        state.pushHistory()
        state.moves = 5

        #expect(state.canUndo)
        let restored = state.popHistory()
        #expect(restored != nil)
        #expect(restored?.moves == 0)
        #expect(!state.canUndo)
    }

    @Test("History caps at 20 entries")
    func historyCap() {
        let state = GameState()
        state.tableaus = [[]]
        state.foundations = [[], [], [], []]

        for i in 0..<25 {
            state.moves = i
            state.pushHistory()
        }

        #expect(state.history.count == 20)
        // First entries should have been removed
        #expect(state.history.first?.moves == 5)
    }

    @Test("Clear history")
    func clearHistory() {
        let state = GameState()
        state.tableaus = [[]]
        state.foundations = [[], [], [], []]
        state.pushHistory()
        state.pushHistory()
        #expect(state.canUndo)

        state.clearHistory()
        #expect(!state.canUndo)
        #expect(state.history.isEmpty)
    }

    @Test("Reset from snapshot sets phase to playing")
    func resetSetsPlaying() {
        let state = GameState()
        let snapshot = GameSnapshot(
            tableaus: Array(repeating: [], count: 7),
            foundations: [[], [], [], []],
            stock: [],
            waste: [],
            freeCells: [],
            moves: 0,
            score: 0
        )

        state.reset(from: snapshot, variant: .klondike)
        #expect(state.phase == .playing)
        #expect(state.history.isEmpty)
    }
}
