import XCTest
import SwiftData
@testable import SportsTime

@MainActor
final class VisitListTests: XCTestCase {
    var modelContainer: ModelContainer!
    var modelContext: ModelContext!

    override func setUp() async throws {
        let config = ModelConfiguration(isStoredInMemoryOnly: true)
        modelContainer = try ModelContainer(
            for: StadiumVisit.self, Achievement.self, UserPreferences.self,
            configurations: config
        )
        modelContext = modelContainer.mainContext
    }

    override func tearDown() async throws {
        modelContainer = nil
        modelContext = nil
    }

    func test_VisitsForStadium_ReturnsAllVisitsSortedByDate() async throws {
        // Given: Multiple visits to the same stadium
        let stadiumId = "yankee-stadium"

        let visit1 = StadiumVisit(
            stadiumId: stadiumId,
            stadiumNameAtVisit: "Yankee Stadium",
            visitDate: Date().addingTimeInterval(-86400 * 30), // 30 days ago
            sport: .mlb,
            visitType: .game,
            dataSource: .fullyManual
        )

        let visit2 = StadiumVisit(
            stadiumId: stadiumId,
            stadiumNameAtVisit: "Yankee Stadium",
            visitDate: Date().addingTimeInterval(-86400 * 7), // 7 days ago
            sport: .mlb,
            visitType: .game,
            dataSource: .fullyManual
        )

        let visit3 = StadiumVisit(
            stadiumId: stadiumId,
            stadiumNameAtVisit: "Yankee Stadium",
            visitDate: Date(), // today
            sport: .mlb,
            visitType: .tour,
            dataSource: .fullyManual
        )

        modelContext.insert(visit1)
        modelContext.insert(visit2)
        modelContext.insert(visit3)
        try modelContext.save()

        // When: Fetching visits for that stadium
        let descriptor = FetchDescriptor<StadiumVisit>(
            predicate: #Predicate { $0.stadiumId == stadiumId },
            sortBy: [SortDescriptor(\.visitDate, order: .reverse)]
        )
        let visits = try modelContext.fetch(descriptor)

        // Then: All visits returned, most recent first
        XCTAssertEqual(visits.count, 3, "Should return all 3 visits")
        XCTAssertEqual(visits[0].visitType, .tour, "Most recent visit should be first")
        XCTAssertEqual(visits[2].visitType, .game, "Oldest visit should be last")
    }

    func test_VisitCountForStadium_ReturnsCorrectCount() async throws {
        // Given: 3 visits to one stadium, 1 to another
        let stadium1 = "yankee-stadium"
        let stadium2 = "fenway-park"

        for i in 0..<3 {
            let visit = StadiumVisit(
                stadiumId: stadium1,
                stadiumNameAtVisit: "Yankee Stadium",
                visitDate: Date().addingTimeInterval(Double(-i * 86400)),
                sport: .mlb,
                visitType: .game,
                dataSource: .fullyManual
            )
            modelContext.insert(visit)
        }

        let fenwayVisit = StadiumVisit(
            stadiumId: stadium2,
            stadiumNameAtVisit: "Fenway Park",
            visitDate: Date(),
            sport: .mlb,
            visitType: .game,
            dataSource: .fullyManual
        )
        modelContext.insert(fenwayVisit)
        try modelContext.save()

        // When: Counting visits per stadium
        let yankeeDescriptor = FetchDescriptor<StadiumVisit>(
            predicate: #Predicate { $0.stadiumId == stadium1 }
        )
        let fenwayDescriptor = FetchDescriptor<StadiumVisit>(
            predicate: #Predicate { $0.stadiumId == stadium2 }
        )

        let yankeeCount = try modelContext.fetchCount(yankeeDescriptor)
        let fenwayCount = try modelContext.fetchCount(fenwayDescriptor)

        // Then: Correct counts
        XCTAssertEqual(yankeeCount, 3)
        XCTAssertEqual(fenwayCount, 1)
    }
}
