import Testing
import Foundation
@testable import nahbar

// MARK: - ThemeID Enum Tests

@Suite("ThemeID – Enum")
struct ThemeIDTests {

    @Test("Genau 15 Themes vorhanden")
    func allCasesCount() {
        #expect(ThemeID.allCases.count == 15)
    }

    @Test("rawValues sind einzigartig")
    func rawValuesAreUnique() {
        let values = ThemeID.allCases.map { $0.rawValue }
        #expect(Set(values).count == ThemeID.allCases.count)
    }

    @Test("displayNames sind einzigartig")
    func displayNamesAreUnique() {
        let names = ThemeID.allCases.map { $0.displayName }
        #expect(Set(names).count == ThemeID.allCases.count)
    }

    @Test("displayNames sind nicht leer")
    func displayNamesNotEmpty() {
        for id in ThemeID.allCases {
            #expect(!id.displayName.isEmpty, "displayName für \(id.rawValue) ist leer")
        }
    }

    @Test("Genau 5 kostenlose Themes")
    func freeThemesCount() {
        let free = ThemeID.allCases.filter { !$0.isPremium }
        #expect(free.count == 5)
    }

    @Test("Kostenlose Themes: linen, slate, mist, chalk, flint")
    func freeThemeIdentities() {
        let free = Set(ThemeID.allCases.filter { !$0.isPremium })
        #expect(free == [.linen, .slate, .mist, .chalk, .flint])
    }

    @Test("Genau 10 bezahlte Themes")
    func premiumThemesCount() {
        let premium = ThemeID.allCases.filter { $0.isPremium }
        #expect(premium.count == 10)
    }

    @Test("isDark: flint, copper, onyx, ember, abyss, dusk, basalt sind dunkel")
    func darkThemes() {
        let dark = Set(ThemeID.allCases.filter { $0.isDark })
        #expect(dark == [.flint, .copper, .onyx, .ember, .abyss, .dusk, .basalt])
    }

    @Test("isNeurodiverseFocused: nur abyss, dusk, basalt")
    func ndThemes() {
        let nd = Set(ThemeID.allCases.filter { $0.isNeurodiverseFocused })
        #expect(nd == [.abyss, .dusk, .basalt])
    }

    @Test("ND-Themes sind alle dunkel")
    func ndThemesAreDark() {
        for id in ThemeID.allCases where id.isNeurodiverseFocused {
            #expect(id.isDark, "\(id.rawValue) ist ND aber nicht dunkel")
        }
    }

    @Test("Neue Hochkontrast-Themes sind nicht ND-fokussiert")
    func highContrastThemesNotND() {
        let highContrast: [ThemeID] = [.chalk, .flint, .onyx, .ember, .birch, .vapor]
        for id in highContrast {
            #expect(!id.isNeurodiverseFocused, "\(id.rawValue) sollte nicht ND-fokussiert sein")
        }
    }
}

// MARK: - NahbarTheme Token Tests

@Suite("NahbarTheme – Tokens")
struct NahbarThemeTokenTests {

    @Test("theme(for:) gibt für jeden ThemeID ein Theme zurück")
    func themeForAllIDs() {
        for id in ThemeID.allCases {
            let t = NahbarTheme.theme(for: id)
            #expect(t.id == id, "theme(for: \(id.rawValue)).id stimmt nicht überein")
        }
    }

    @Test("sectionHeaderSize ist positiv für alle Themes")
    func sectionHeaderSizePositive() {
        for id in ThemeID.allCases {
            let t = NahbarTheme.theme(for: id)
            #expect(t.sectionHeaderSize > 0, "sectionHeaderSize für \(id.rawValue) ist nicht positiv")
        }
    }

    @Test("Alle Themes haben sectionHeaderSize 13")
    func allThemesHeaderSize() {
        for id in ThemeID.allCases {
            let t = NahbarTheme.theme(for: id)
            #expect(t.sectionHeaderSize == 13, "\(id.rawValue) sectionHeaderSize sollte 13 sein")
        }
    }

    @Test("radiusCard ist positiv für alle Themes")
    func radiusCardPositive() {
        for id in ThemeID.allCases {
            let t = NahbarTheme.theme(for: id)
            #expect(t.radiusCard > 0, "radiusCard für \(id.rawValue) ist nicht positiv")
        }
    }

    @Test("radiusTag ist positiv für alle Themes")
    func radiusTagPositive() {
        for id in ThemeID.allCases {
            let t = NahbarTheme.theme(for: id)
            #expect(t.radiusTag > 0, "radiusTag für \(id.rawValue) ist nicht positiv")
        }
    }
}
