//
//  PDFGeneratorTests.swift
//  SportsTimeTests
//
//  TDD specification tests for PDFGenerator types.
//

import Testing
import Foundation
import UIKit
@testable import SportsTime

// MARK: - UIColor Hex Extension Tests

@Suite("UIColor Hex Extension")
struct UIColorHexExtensionTests {

    // MARK: - Specification Tests: Parsing

    /// - Expected Behavior: Parses 6-digit hex without #
    @Test("init(hex:): parses 6-digit hex without #")
    func initHex_sixDigitWithoutHash() {
        let color = UIColor(hex: "FF0000")
        #expect(color != nil)
    }

    /// - Expected Behavior: Parses 6-digit hex with #
    @Test("init(hex:): parses 6-digit hex with #")
    func initHex_sixDigitWithHash() {
        let color = UIColor(hex: "#FF0000")
        #expect(color != nil)
    }

    /// - Expected Behavior: Returns nil for invalid length
    @Test("init(hex:): returns nil for invalid length")
    func initHex_invalidLength() {
        let tooShort = UIColor(hex: "FF00")
        let tooLong = UIColor(hex: "FF00FF00")

        #expect(tooShort == nil)
        #expect(tooLong == nil)
    }

    /// - Expected Behavior: Handles whitespace
    @Test("init(hex:): handles whitespace")
    func initHex_whitespace() {
        let color = UIColor(hex: "  FF0000  ")
        #expect(color != nil)
    }

    // MARK: - Specification Tests: Color Values

    /// - Expected Behavior: Red hex produces red color
    @Test("init(hex:): FF0000 produces red")
    func initHex_redColor() {
        let color = UIColor(hex: "FF0000")!
        var r: CGFloat = 0, g: CGFloat = 0, b: CGFloat = 0, a: CGFloat = 0
        color.getRed(&r, green: &g, blue: &b, alpha: &a)

        #expect(abs(r - 1.0) < 0.01)
        #expect(abs(g - 0.0) < 0.01)
        #expect(abs(b - 0.0) < 0.01)
        #expect(abs(a - 1.0) < 0.01)
    }

    /// - Expected Behavior: Green hex produces green color
    @Test("init(hex:): 00FF00 produces green")
    func initHex_greenColor() {
        let color = UIColor(hex: "00FF00")!
        var r: CGFloat = 0, g: CGFloat = 0, b: CGFloat = 0, a: CGFloat = 0
        color.getRed(&r, green: &g, blue: &b, alpha: &a)

        #expect(abs(r - 0.0) < 0.01)
        #expect(abs(g - 1.0) < 0.01)
        #expect(abs(b - 0.0) < 0.01)
    }

    /// - Expected Behavior: Blue hex produces blue color
    @Test("init(hex:): 0000FF produces blue")
    func initHex_blueColor() {
        let color = UIColor(hex: "0000FF")!
        var r: CGFloat = 0, g: CGFloat = 0, b: CGFloat = 0, a: CGFloat = 0
        color.getRed(&r, green: &g, blue: &b, alpha: &a)

        #expect(abs(r - 0.0) < 0.01)
        #expect(abs(g - 0.0) < 0.01)
        #expect(abs(b - 1.0) < 0.01)
    }

    /// - Expected Behavior: Black hex produces black color
    @Test("init(hex:): 000000 produces black")
    func initHex_blackColor() {
        let color = UIColor(hex: "000000")!
        var r: CGFloat = 0, g: CGFloat = 0, b: CGFloat = 0, a: CGFloat = 0
        color.getRed(&r, green: &g, blue: &b, alpha: &a)

        #expect(abs(r - 0.0) < 0.01)
        #expect(abs(g - 0.0) < 0.01)
        #expect(abs(b - 0.0) < 0.01)
    }

    /// - Expected Behavior: White hex produces white color
    @Test("init(hex:): FFFFFF produces white")
    func initHex_whiteColor() {
        let color = UIColor(hex: "FFFFFF")!
        var r: CGFloat = 0, g: CGFloat = 0, b: CGFloat = 0, a: CGFloat = 0
        color.getRed(&r, green: &g, blue: &b, alpha: &a)

        #expect(abs(r - 1.0) < 0.01)
        #expect(abs(g - 1.0) < 0.01)
        #expect(abs(b - 1.0) < 0.01)
    }

    /// - Expected Behavior: Mixed hex produces correct color
    @Test("init(hex:): mixed color produces correct values")
    func initHex_mixedColor() {
        // 80 = 128 = 0.502 (50%)
        let color = UIColor(hex: "804020")!
        var r: CGFloat = 0, g: CGFloat = 0, b: CGFloat = 0, a: CGFloat = 0
        color.getRed(&r, green: &g, blue: &b, alpha: &a)

        // 0x80 = 128/255 = ~0.502
        // 0x40 = 64/255 = ~0.251
        // 0x20 = 32/255 = ~0.125
        #expect(abs(r - 0.502) < 0.01)
        #expect(abs(g - 0.251) < 0.01)
        #expect(abs(b - 0.125) < 0.01)
    }

    // MARK: - Edge Cases

    /// - Expected Behavior: Lowercase hex works
    @Test("init(hex:): lowercase hex works")
    func initHex_lowercase() {
        let color = UIColor(hex: "ff0000")
        #expect(color != nil)
    }

    /// - Expected Behavior: Mixed case hex works
    @Test("init(hex:): mixed case hex works")
    func initHex_mixedCase() {
        let color = UIColor(hex: "Ff00fF")
        #expect(color != nil)
    }

    /// - Expected Behavior: Empty string returns nil
    @Test("init(hex:): empty string returns nil")
    func initHex_emptyString() {
        let color = UIColor(hex: "")
        #expect(color == nil)
    }

    /// - Expected Behavior: Just # returns nil
    @Test("init(hex:): just # returns nil")
    func initHex_justHash() {
        let color = UIColor(hex: "#")
        #expect(color == nil)
    }

    // MARK: - Invariant Tests

    /// - Invariant: Alpha is always 1.0
    @Test("Invariant: alpha is always 1.0")
    func invariant_alphaIsOne() {
        let testHexes = ["FF0000", "00FF00", "0000FF", "123456", "ABCDEF"]

        for hex in testHexes {
            let color = UIColor(hex: hex)!
            var a: CGFloat = 0
            color.getRed(nil, green: nil, blue: nil, alpha: &a)
            #expect(abs(a - 1.0) < 0.001)
        }
    }

    /// - Invariant: Valid 6-digit hex always succeeds
    @Test("Invariant: valid 6-digit hex always succeeds")
    func invariant_validHexSucceeds() {
        let validHexes = ["000000", "FFFFFF", "123456", "ABCDEF", "abcdef", "#000000", "#FFFFFF"]

        for hex in validHexes {
            let color = UIColor(hex: hex)
            #expect(color != nil, "Failed for hex: \(hex)")
        }
    }
}
