//
//  TripOptionsGroupingTests.swift
//  SportsTimeTests
//

import Testing
import Foundation
import CoreLocation
@testable import SportsTime

struct TripOptionsGroupingTests {

    // Helper to create mock ItineraryStop
    private func makeStop(city: String, games: [String] = []) -> ItineraryStop {
        ItineraryStop(
            city: city,
            state: "XX",
            coordinate: CLLocationCoordinate2D(latitude: 0, longitude: 0),
            games: games,
            arrivalDate: Date(),
            departureDate: Date(),
            location: LocationInput(name: city, coordinate: nil),
            firstGameStart: nil
        )
    }

    // Helper to create mock ItineraryOption
    private func makeOption(stops: [(city: String, games: [String])], totalMiles: Double = 500) -> ItineraryOption {
        let itineraryStops = stops.map { makeStop(city: $0.city, games: $0.games) }
        return ItineraryOption(
            rank: 1,
            stops: itineraryStops,
            travelSegments: [],
            totalDrivingHours: totalMiles / 60,
            totalDistanceMiles: totalMiles,
            geographicRationale: "Test"
        )
    }

    @Test func groupByCityCountDescending() {
        let options = [
            makeOption(stops: [("NYC", []), ("Boston", [])]),  // 2 cities
            makeOption(stops: [("LA", []), ("SF", []), ("Seattle", [])]),  // 3 cities
            makeOption(stops: [("Chicago", [])]),  // 1 city
        ]

        let grouped = TripOptionsGrouper.groupByCityCount(options, ascending: false)

        #expect(grouped.count == 3)
        #expect(grouped[0].header == "3 cities")
        #expect(grouped[1].header == "2 cities")
        #expect(grouped[2].header == "1 city")
    }

    @Test func groupByGameCountAscending() {
        let options = [
            makeOption(stops: [("NYC", ["g1", "g2", "g3"])]),  // 3 games
            makeOption(stops: [("LA", ["g1"])]),  // 1 game
            makeOption(stops: [("Chicago", ["g1", "g2"])]),  // 2 games
        ]

        let grouped = TripOptionsGrouper.groupByGameCount(options, ascending: true)

        #expect(grouped.count == 3)
        #expect(grouped[0].header == "1 game")
        #expect(grouped[1].header == "2 games")
        #expect(grouped[2].header == "3 games")
    }

    @Test func groupByMileageRangeDescending() {
        let options = [
            makeOption(stops: [("NYC", [])], totalMiles: 300),   // 0-500
            makeOption(stops: [("LA", [])], totalMiles: 1200),   // 1000-1500
            makeOption(stops: [("Chicago", [])], totalMiles: 2500),  // 2000+
        ]

        let grouped = TripOptionsGrouper.groupByMileageRange(options, ascending: false)

        #expect(grouped[0].header == "2000+ mi")
        #expect(grouped[1].header == "1000-1500 mi")
        #expect(grouped[2].header == "0-500 mi")
    }

    @Test func groupByMileageRangeAscending() {
        let options = [
            makeOption(stops: [("NYC", [])], totalMiles: 300),
            makeOption(stops: [("LA", [])], totalMiles: 1200),
            makeOption(stops: [("Chicago", [])], totalMiles: 2500),
        ]

        let grouped = TripOptionsGrouper.groupByMileageRange(options, ascending: true)

        #expect(grouped[0].header == "0-500 mi")
        #expect(grouped[1].header == "1000-1500 mi")
        #expect(grouped[2].header == "2000+ mi")
    }

    @Test func emptyOptionsReturnsEmptyGroups() {
        let grouped = TripOptionsGrouper.groupByCityCount([], ascending: false)
        #expect(grouped.isEmpty)
    }
}
