import Testing
@testable import SoliCards

@Suite("Difficulty Tests")
struct DifficultyTests {

    @Test("Easy settings")
    func easySettings() {
        let settings = Difficulty.easy.settings
        #expect(settings.drawCount == 1)
        #expect(settings.maxUndos == .max)
        #expect(settings.hintsEnabled)
        #expect(settings.scoreMultiplier == 0.5)
    }

    @Test("Medium settings")
    func mediumSettings() {
        let settings = Difficulty.medium.settings
        #expect(settings.drawCount == 3)
        #expect(settings.maxUndos == 20)
        #expect(settings.hintsEnabled)
    }

    @Test("Hard settings disable hints")
    func hardNoHints() {
        let settings = Difficulty.hard.settings
        #expect(!settings.hintsEnabled)
        #expect(settings.maxUndos == 10)
    }

    @Test("Expert settings are most restrictive")
    func expertSettings() {
        let settings = Difficulty.expert.settings
        #expect(!settings.hintsEnabled)
        #expect(settings.maxUndos == 5)
        #expect(settings.scoreMultiplier == 2.0)
    }

    @Test("All difficulties have display names")
    func displayNames() {
        for difficulty in Difficulty.allCases {
            #expect(!difficulty.displayName.isEmpty)
        }
    }
}

@Suite("GameVariant Tests")
struct GameVariantTests {

    @Test("Klondike properties")
    func klondikeProps() {
        let v = GameVariant.klondike
        #expect(v.tableauCount == 7)
        #expect(v.foundationCount == 4)
        #expect(v.deckCount == 1)
        #expect(v.hasWaste)
        #expect(v.hasStock)
        #expect(!v.hasFreeCells)
    }

    @Test("Spider properties")
    func spiderProps() {
        let v = GameVariant.spider
        #expect(v.tableauCount == 10)
        #expect(v.foundationCount == 8)
        #expect(v.deckCount == 2)
        #expect(!v.hasFreeCells)
    }

    @Test("FreeCell properties")
    func freeCellProps() {
        let v = GameVariant.freeCell
        #expect(v.tableauCount == 8)
        #expect(v.foundationCount == 4)
        #expect(v.deckCount == 1)
        #expect(!v.hasWaste)
        #expect(!v.hasStock)
        #expect(v.hasFreeCells)
        #expect(v.freeCellCount == 4)
    }
}

@Suite("Rank Tests")
struct RankTests {

    @Test("Rank ordering")
    func rankOrder() {
        #expect(Rank.ace < Rank.two)
        #expect(Rank.queen < Rank.king)
        #expect(Rank.ace.rawValue == 1)
        #expect(Rank.king.rawValue == 13)
    }

    @Test("All 13 ranks exist")
    func allRanks() {
        #expect(Rank.allCases.count == 13)
    }

    @Test("File names for assets")
    func fileNames() {
        #expect(Rank.ace.fileName == "ace")
        #expect(Rank.two.fileName == "2")
        #expect(Rank.ten.fileName == "10")
        #expect(Rank.jack.fileName == "jack")
        #expect(Rank.queen.fileName == "queen")
        #expect(Rank.king.fileName == "king")
    }
}

@Suite("Suit Tests")
struct SuitTests {

    @Test("Red and black suits")
    func suitColors() {
        #expect(Suit.hearts.color == .red)
        #expect(Suit.diamonds.color == .red)
        #expect(Suit.spades.color == .black)
        #expect(Suit.clubs.color == .black)
    }

    @Test("All 4 suits exist")
    func allSuits() {
        #expect(Suit.allCases.count == 4)
    }

    @Test("Suit symbols")
    func symbols() {
        #expect(Suit.spades.symbol == "♠")
        #expect(Suit.hearts.symbol == "♥")
        #expect(Suit.diamonds.symbol == "♦")
        #expect(Suit.clubs.symbol == "♣")
    }
}
