//
//  TeamTests.swift
//  SportsTimeTests
//
//  TDD specification tests for Team model.
//

import Testing
import Foundation
@testable import SportsTime

@Suite("Team")
@MainActor
struct TeamTests {

    // MARK: - Specification Tests: fullName

    @Test("fullName: returns 'city name' when city is non-empty")
    func fullName_withCity() {
        let team = Team(
            id: "team1",
            name: "Red Sox",
            abbreviation: "BOS",
            sport: .mlb,
            city: "Boston",
            stadiumId: "stadium1"
        )

        #expect(team.fullName == "Boston Red Sox")
    }

    @Test("fullName: returns just name when city is empty")
    func fullName_emptyCity() {
        let team = Team(
            id: "team1",
            name: "Guardians",
            abbreviation: "CLE",
            sport: .mlb,
            city: "",
            stadiumId: "stadium1"
        )

        #expect(team.fullName == "Guardians")
    }

    @Test("fullName: handles city with spaces")
    func fullName_cityWithSpaces() {
        let team = Team(
            id: "team1",
            name: "Lakers",
            abbreviation: "LAL",
            sport: .nba,
            city: "Los Angeles",
            stadiumId: "stadium1"
        )

        #expect(team.fullName == "Los Angeles Lakers")
    }

    @Test("fullName: handles team name with spaces")
    func fullName_teamNameWithSpaces() {
        let team = Team(
            id: "team1",
            name: "Red Sox",
            abbreviation: "BOS",
            sport: .mlb,
            city: "Boston",
            stadiumId: "stadium1"
        )

        #expect(team.fullName == "Boston Red Sox")
    }

    // MARK: - Specification Tests: Equality

    @Test("equality based on id only")
    func equality_basedOnId() {
        let team1 = Team(
            id: "team1",
            name: "Name A",
            abbreviation: "AAA",
            sport: .mlb,
            city: "City A",
            stadiumId: "stadium1"
        )

        let team2 = Team(
            id: "team1",
            name: "Different Name",
            abbreviation: "BBB",
            sport: .nba,
            city: "Different City",
            stadiumId: "different-stadium"
        )

        #expect(team1 == team2, "Teams with same id should be equal")
    }

    @Test("inequality when ids differ")
    func inequality_differentIds() {
        let team1 = Team(
            id: "team1",
            name: "Same Name",
            abbreviation: "AAA",
            sport: .mlb,
            city: "Same City",
            stadiumId: "stadium1"
        )

        let team2 = Team(
            id: "team2",
            name: "Same Name",
            abbreviation: "AAA",
            sport: .mlb,
            city: "Same City",
            stadiumId: "stadium1"
        )

        #expect(team1 != team2, "Teams with different ids should not be equal")
    }

    // MARK: - Invariant Tests

    @Test("Invariant: fullName is never empty")
    func invariant_fullNameNeverEmpty() {
        // Team with name only
        let team1 = Team(
            id: "team1",
            name: "Team",
            abbreviation: "TM",
            sport: .mlb,
            city: "",
            stadiumId: "stadium1"
        )
        #expect(!team1.fullName.isEmpty)

        // Team with city and name
        let team2 = Team(
            id: "team2",
            name: "Team",
            abbreviation: "TM",
            sport: .mlb,
            city: "City",
            stadiumId: "stadium1"
        )
        #expect(!team2.fullName.isEmpty)
    }

    // MARK: - Property Tests

    @Test("Property: id is Identifiable conformance")
    func property_identifiable() {
        let team = Team(
            id: "unique-id",
            name: "Team",
            abbreviation: "TM",
            sport: .mlb,
            city: "City",
            stadiumId: "stadium1"
        )

        #expect(team.id == "unique-id")
    }

    @Test("Property: optional fields can be nil")
    func property_optionalFieldsNil() {
        let team = Team(
            id: "team1",
            name: "Team",
            abbreviation: "TM",
            sport: .mlb,
            city: "City",
            stadiumId: "stadium1",
            logoURL: nil,
            primaryColor: nil,
            secondaryColor: nil
        )

        #expect(team.logoURL == nil)
        #expect(team.primaryColor == nil)
        #expect(team.secondaryColor == nil)
    }

    @Test("Property: optional fields can have values")
    func property_optionalFieldsWithValues() {
        let team = Team(
            id: "team1",
            name: "Team",
            abbreviation: "TM",
            sport: .mlb,
            city: "City",
            stadiumId: "stadium1",
            logoURL: URL(string: "https://example.com/logo.png"),
            primaryColor: "#FF0000",
            secondaryColor: "#0000FF"
        )

        #expect(team.logoURL?.absoluteString == "https://example.com/logo.png")
        #expect(team.primaryColor == "#FF0000")
        #expect(team.secondaryColor == "#0000FF")
    }
}
