//
//  TripWizardViewModelTests.swift
//  SportsTimeTests
//

import XCTest
@testable import SportsTime

final class TripWizardViewModelTests: XCTestCase {

    // MARK: - Visibility Tests

    func test_initialState_stepsNotVisible() {
        let viewModel = TripWizardViewModel()

        XCTAssertFalse(viewModel.areStepsVisible)
    }

    func test_selectingPlanningMode_revealsAllSteps() {
        let viewModel = TripWizardViewModel()

        viewModel.planningMode = .dateRange

        XCTAssertTrue(viewModel.areStepsVisible)
    }

    // MARK: - canPlanTrip Validation Tests

    func test_canPlanTrip_initiallyFalse() {
        let viewModel = TripWizardViewModel()

        XCTAssertFalse(viewModel.canPlanTrip)
    }

    func test_canPlanTrip_requiresAllFields() {
        let viewModel = TripWizardViewModel()

        // None set
        XCTAssertFalse(viewModel.canPlanTrip)

        // Only planning mode
        viewModel.planningMode = .dateRange
        XCTAssertFalse(viewModel.canPlanTrip)

        // Add dates
        viewModel.hasSetDates = true
        XCTAssertFalse(viewModel.canPlanTrip)

        // Add sports
        viewModel.selectedSports = [.mlb]
        XCTAssertFalse(viewModel.canPlanTrip)

        // Add regions
        viewModel.selectedRegions = [.east]
        XCTAssertFalse(viewModel.canPlanTrip)

        // Add route preference
        viewModel.hasSetRoutePreference = true
        XCTAssertFalse(viewModel.canPlanTrip)

        // Add repeat cities - now all required fields are set
        viewModel.hasSetRepeatCities = true
        XCTAssertTrue(viewModel.canPlanTrip)
    }

    func test_canPlanTrip_trueWhenAllFieldsSet() {
        let viewModel = TripWizardViewModel()
        viewModel.planningMode = .dateRange
        viewModel.hasSetDates = true
        viewModel.selectedSports = [.mlb, .nba]
        viewModel.selectedRegions = [.east, .central]
        viewModel.hasSetRoutePreference = true
        viewModel.hasSetRepeatCities = true

        XCTAssertTrue(viewModel.canPlanTrip)
    }

    func test_canPlanTrip_mustStopsOptional() {
        let viewModel = TripWizardViewModel()
        viewModel.planningMode = .dateRange
        viewModel.hasSetDates = true
        viewModel.selectedSports = [.nba]
        viewModel.selectedRegions = [.west]
        viewModel.hasSetRoutePreference = true
        viewModel.hasSetRepeatCities = true

        // canPlanTrip should be true even without must stops
        XCTAssertTrue(viewModel.canPlanTrip)
        XCTAssertTrue(viewModel.mustStopLocations.isEmpty)
    }

    // MARK: - Reset Behavior Tests

    func test_changingPlanningMode_resetsAllSelections() {
        let viewModel = TripWizardViewModel()

        // Set up full wizard state
        viewModel.planningMode = .dateRange
        viewModel.selectedSports = [.mlb, .nba]
        viewModel.hasSetDates = true
        viewModel.selectedRegions = [.east, .central]
        viewModel.hasSetRoutePreference = true
        viewModel.hasSetRepeatCities = true
        viewModel.mustStopLocations = [LocationInput(name: "Test", coordinates: nil)]

        // Change planning mode
        viewModel.planningMode = .locations

        // Verify all state is reset
        XCTAssertTrue(viewModel.selectedSports.isEmpty)
        XCTAssertFalse(viewModel.hasSetDates)
        XCTAssertTrue(viewModel.selectedRegions.isEmpty)
        XCTAssertFalse(viewModel.hasSetRoutePreference)
        XCTAssertFalse(viewModel.hasSetRepeatCities)
        XCTAssertTrue(viewModel.mustStopLocations.isEmpty)
    }

    func test_settingSamePlanningMode_doesNotResetState() {
        let viewModel = TripWizardViewModel()
        viewModel.planningMode = .dateRange
        viewModel.selectedSports = [.mlb]
        viewModel.hasSetDates = true

        // Re-set the same mode
        viewModel.planningMode = .dateRange

        // State should NOT be reset
        XCTAssertEqual(viewModel.selectedSports, [.mlb])
        XCTAssertTrue(viewModel.hasSetDates)
    }

    // MARK: - Sport Availability Tests

    func test_canSelectSport_defaultsToTrue() {
        let viewModel = TripWizardViewModel()

        XCTAssertTrue(viewModel.canSelectSport(.mlb))
        XCTAssertTrue(viewModel.canSelectSport(.nba))
        XCTAssertTrue(viewModel.canSelectSport(.nhl))
    }

    func test_canSelectSport_respectsAvailability() {
        let viewModel = TripWizardViewModel()
        viewModel.sportAvailability = [.mlb: true, .nba: false, .nhl: true]

        XCTAssertTrue(viewModel.canSelectSport(.mlb))
        XCTAssertFalse(viewModel.canSelectSport(.nba))
        XCTAssertTrue(viewModel.canSelectSport(.nhl))
    }

    // MARK: - Multi-Selection Tests

    func test_multipleSports_canBeSelected() {
        let viewModel = TripWizardViewModel()

        viewModel.selectedSports = [.mlb, .nba, .nhl]

        XCTAssertEqual(viewModel.selectedSports.count, 3)
    }

    func test_multipleRegions_canBeSelected() {
        let viewModel = TripWizardViewModel()

        viewModel.selectedRegions = [.east, .central, .west]

        XCTAssertEqual(viewModel.selectedRegions.count, 3)
    }

    // MARK: - Planning State Tests

    func test_isPlanning_defaultsToFalse() {
        let viewModel = TripWizardViewModel()

        XCTAssertFalse(viewModel.isPlanning)
    }

    func test_mustStopLocations_canBeAdded() {
        let viewModel = TripWizardViewModel()
        let location = LocationInput(name: "Chicago, IL", coordinates: nil)

        viewModel.mustStopLocations.append(location)

        XCTAssertEqual(viewModel.mustStopLocations.count, 1)
        XCTAssertEqual(viewModel.mustStopLocations.first?.name, "Chicago, IL")
    }
}
