import Testing
@testable import SoliCards

@Suite("MoveValidator Tests")
struct MoveValidatorTests {

    @Test("Alternating color detection")
    func alternatingColor() {
        let redCard = Card(suit: .hearts, rank: .five, isFaceUp: true)
        let blackCard = Card(suit: .spades, rank: .four, isFaceUp: true)
        let anotherRed = Card(suit: .diamonds, rank: .three, isFaceUp: true)

        #expect(MoveValidator.isAlternatingColor(redCard, with: blackCard))
        #expect(MoveValidator.isAlternatingColor(blackCard, with: redCard))
        #expect(!MoveValidator.isAlternatingColor(redCard, with: anotherRed))
    }

    @Test("Same suit detection")
    func sameSuit() {
        let spade1 = Card(suit: .spades, rank: .ace, isFaceUp: true)
        let spade2 = Card(suit: .spades, rank: .king, isFaceUp: true)
        let heart = Card(suit: .hearts, rank: .ace, isFaceUp: true)

        #expect(MoveValidator.isSameSuit(spade1, as: spade2))
        #expect(!MoveValidator.isSameSuit(spade1, as: heart))
    }

    @Test("Ascending rank (for foundations)")
    func ascending() {
        let ace = Card(suit: .hearts, rank: .ace, isFaceUp: true)
        let two = Card(suit: .hearts, rank: .two, isFaceUp: true)
        let three = Card(suit: .hearts, rank: .three, isFaceUp: true)

        #expect(MoveValidator.isAscending(two, onto: ace))
        #expect(MoveValidator.isAscending(three, onto: two))
        #expect(!MoveValidator.isAscending(three, onto: ace))
        #expect(!MoveValidator.isAscending(ace, onto: two))
    }

    @Test("Descending rank (for tableaus)")
    func descending() {
        let king = Card(suit: .spades, rank: .king, isFaceUp: true)
        let queen = Card(suit: .hearts, rank: .queen, isFaceUp: true)
        let jack = Card(suit: .spades, rank: .jack, isFaceUp: true)

        #expect(MoveValidator.isDescending(queen, onto: king))
        #expect(MoveValidator.isDescending(jack, onto: queen))
        #expect(!MoveValidator.isDescending(king, onto: queen))
    }

    @Test("Can place on foundation")
    func canPlaceOnFoundation() {
        let ace = Card(suit: .hearts, rank: .ace, isFaceUp: true)
        let two = Card(suit: .hearts, rank: .two, isFaceUp: true)
        let twoSpades = Card(suit: .spades, rank: .two, isFaceUp: true)
        let three = Card(suit: .hearts, rank: .three, isFaceUp: true)

        // Ace on empty foundation
        #expect(MoveValidator.canPlaceOnFoundation(ace, topCard: nil))
        // Non-ace on empty foundation
        #expect(!MoveValidator.canPlaceOnFoundation(two, topCard: nil))
        // Two of hearts on ace of hearts
        #expect(MoveValidator.canPlaceOnFoundation(two, topCard: ace))
        // Two of spades on ace of hearts (wrong suit)
        #expect(!MoveValidator.canPlaceOnFoundation(twoSpades, topCard: ace))
        // Three on ace (skipping)
        #expect(!MoveValidator.canPlaceOnFoundation(three, topCard: ace))
    }

    @Test("Ace and King detection")
    func aceAndKing() {
        let ace = Card(suit: .clubs, rank: .ace)
        let king = Card(suit: .clubs, rank: .king)
        let five = Card(suit: .clubs, rank: .five)

        #expect(MoveValidator.isAce(ace))
        #expect(!MoveValidator.isAce(king))
        #expect(MoveValidator.isKing(king))
        #expect(!MoveValidator.isKing(five))
    }
}
