import Testing
@testable import SoliCards

@Suite("Spider Rules Tests")
struct SpiderRulesTests {
    let rules = SpiderRules()

    @Test("Deal creates correct layout with 2 decks")
    func dealLayout() {
        let deck = Deck.double()
        let snapshot = rules.deal(deck: deck)

        #expect(snapshot.tableaus.count == 10)
        // First 4 get 6 cards, last 6 get 5 cards
        for i in 0..<4 {
            #expect(snapshot.tableaus[i].count == 6)
        }
        for i in 4..<10 {
            #expect(snapshot.tableaus[i].count == 5)
        }

        // Total dealt: 4*6 + 6*5 = 24 + 30 = 54
        let totalDealt = snapshot.tableaus.reduce(0) { $0 + $1.count }
        #expect(totalDealt == 54)

        // Remaining in stock: 104 - 54 = 50
        #expect(snapshot.stock.count == 50)

        // 8 empty foundations
        #expect(snapshot.foundations.count == 8)
    }

    @Test("Can place any card on descending rank in tableau")
    func tableauStacking() {
        let ten = Card(suit: .spades, rank: .ten, isFaceUp: true)
        let nine = Card(suit: .hearts, rank: .nine, isFaceUp: true) // different suit OK
        var snapshot = emptySpiderSnapshot()
        snapshot.tableaus[0] = [ten]
        snapshot.tableaus[1] = [nine]

        #expect(rules.canMove(cards: [nine], from: .tableau(1), to: .tableau(0), state: snapshot))
    }

    @Test("Complete K-A same-suit sequence detected")
    func completeSequence() {
        var tableau: [Card] = []
        for rank in Rank.allCases.reversed() {
            tableau.append(Card(suit: .spades, rank: rank, isFaceUp: true))
        }
        #expect(rules.isCompleteSequence(in: tableau))
    }

    @Test("Mixed-suit sequence not complete")
    func mixedSuitSequence() {
        var tableau: [Card] = []
        for (i, rank) in Rank.allCases.reversed().enumerated() {
            let suit: Suit = i == 5 ? .hearts : .spades
            tableau.append(Card(suit: suit, rank: rank, isFaceUp: true))
        }
        #expect(!rules.isCompleteSequence(in: tableau))
    }

    @Test("Cannot pick up mixed-suit sequence")
    func cannotPickUpMixedSuit() {
        let spade5 = Card(suit: .spades, rank: .five, isFaceUp: true)
        let heart4 = Card(suit: .hearts, rank: .four, isFaceUp: true)
        var snapshot = emptySpiderSnapshot()
        snapshot.tableaus[0] = [spade5, heart4]

        #expect(!rules.canPickUp(cards: [spade5, heart4], from: .tableau(0), state: snapshot))
    }

    // MARK: - Helpers

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