//
//  SportsTimeUITests.swift
//  SportsTimeUITests
//
//  Created by Trey Tartt on 1/6/26.
//

import XCTest

final class SportsTimeUITests: XCTestCase {

    override func setUpWithError() throws {
        // In UI tests it is usually best to stop immediately when a failure occurs.
        continueAfterFailure = false
    }

    override func tearDownWithError() throws {
        // Put teardown code here.
    }

    // MARK: - Accessibility Smoke Tests

    /// Verifies primary entry flow remains usable at a large accessibility text size.
    @MainActor
    func testAccessibilitySmoke_LargeDynamicTypeEntryFlow() throws {
        let app = XCUIApplication()
        app.launchArguments = [
            "-UIPreferredContentSizeCategoryName",
            "UICTContentSizeCategoryAccessibilityXXXL"
        ]
        app.launch()

        let startPlanningButton = app.buttons["home.startPlanningButton"]
        XCTAssertTrue(startPlanningButton.waitForExistence(timeout: 20), "Start Planning should exist at large Dynamic Type")
        XCTAssertTrue(startPlanningButton.isHittable, "Start Planning should remain hittable at large Dynamic Type")
        startPlanningButton.tap()

        let dateRangeMode = app.buttons["wizard.planningMode.dateRange"]
        XCTAssertTrue(dateRangeMode.waitForExistence(timeout: 10), "Planning mode options should load")
        XCTAssertTrue(dateRangeMode.isHittable, "Planning mode option should remain hittable at large Dynamic Type")
    }

    // MARK: - Demo Flow Test (Continuous Scroll Mode)

    /// Complete trip planning demo with continuous smooth scrolling.
    ///
    /// In demo mode, the app auto-selects each step as it appears on screen:
    /// - Planning Mode: "By Dates"
    /// - Dates: June 11-16, 2026
    /// - Sport: MLB
    /// - Region: Central US
    /// - Sort: Most Games
    /// - Trip: 4th option
    /// - Action: Auto-favorite
    ///
    /// The test just needs to:
    /// 1. Launch with -DemoMode argument
    /// 2. Tap "Start Planning"
    /// 3. Continuously scroll - items auto-select as they appear
    /// 4. Wait for transitions to complete
    @MainActor
    func testTripPlanningDemoFlow() throws {
        let app = XCUIApplication()
        app.launchArguments = ["-DemoMode"]
        app.launch()

        // Wait for app to fully load
        sleep(2)

        // MARK: Step 1 - Tap "Start Planning"
        let startPlanningButton = app.buttons["home.startPlanningButton"]
        XCTAssertTrue(startPlanningButton.waitForExistence(timeout: 10), "Start Planning button should exist")
        startPlanningButton.tap()

        // Wait for demo mode to auto-select planning mode
        sleep(2)

        // MARK: Step 2 - Continuous scroll through wizard
        // Demo mode auto-selects: Date Range → June 11-16 → MLB → Central
        // Each step auto-selects 0.5s after appearing, so we scroll slowly
        for _ in 1...8 {
            slowSwipeUp(app: app)
            sleep(2)  // Give time for auto-selections
        }

        // MARK: Step 3 - Click "Plan My Trip"
        let planTripButton = app.buttons["wizard.planTripButton"]
        XCTAssertTrue(planTripButton.waitForExistence(timeout: 5), "Plan My Trip button should exist")
        planTripButton.tap()

        // Wait for planning to complete
        sleep(6)

        // MARK: Step 4 - Demo mode auto-selects "Most Games" and navigates to 4th trip
        // Wait for TripOptionsView to load and auto-selections to complete
        let sortDropdown = app.buttons["tripOptions.sortDropdown"]
        XCTAssertTrue(sortDropdown.waitForExistence(timeout: 15), "Sort dropdown should exist")

        // Wait for demo mode to auto-select sort and navigate to trip detail
        sleep(3)

        // MARK: Step 5 - Scroll through trip detail (demo mode auto-favorites)
        // Wait for TripDetailView to appear
        let favoriteButton = app.buttons["tripDetail.favoriteButton"]
        if favoriteButton.waitForExistence(timeout: 10) {
            // Demo mode will auto-favorite, but we scroll to show the itinerary
            for _ in 1...6 {
                slowSwipeUp(app: app)
                sleep(2)
            }

            // Scroll back up to show the favorited state
            for _ in 1...4 {
                slowSwipeDown(app: app)
                sleep(1)
            }
        }

        // Wait to display final state
        sleep(3)

        // Test complete - demo flow finished with trip favorited
    }

    // MARK: - Manual Demo Flow Test (Original)

    /// Original manual test flow for comparison or when demo mode is not desired
    @MainActor
    func testTripPlanningManualFlow() throws {
        let app = XCUIApplication()
        app.launch()

        // Wait for app to fully load
        sleep(2)

        // MARK: Step 1 - Tap "Start Planning"
        let startPlanningButton = app.buttons["home.startPlanningButton"]
        XCTAssertTrue(startPlanningButton.waitForExistence(timeout: 10), "Start Planning button should exist")
        startPlanningButton.tap()
        sleep(1)

        // MARK: Step 2 - Choose "By Dates" mode
        let dateRangeMode = app.buttons["wizard.planningMode.dateRange"]
        XCTAssertTrue(dateRangeMode.waitForExistence(timeout: 5), "Date Range mode should exist")
        dateRangeMode.tap()
        sleep(1)

        // Scroll down to see dates step
        app.swipeUp()
        sleep(1)

        // MARK: Step 3 - Select June 11-16, 2026
        // Navigate to June 2026
        let nextMonthButton = app.buttons["wizard.dates.nextMonth"]
        XCTAssertTrue(nextMonthButton.waitForExistence(timeout: 5), "Next month button should exist")

        let monthLabel = app.staticTexts["wizard.dates.monthLabel"]
        var attempts = 0
        while !monthLabel.label.contains("June 2026") && attempts < 12 {
            nextMonthButton.tap()
            Thread.sleep(forTimeInterval: 0.3)
            attempts += 1
        }

        // Select June 11
        let june11 = app.buttons["wizard.dates.day.2026-06-11"]
        XCTAssertTrue(june11.waitForExistence(timeout: 5), "June 11 should exist")
        june11.tap()
        Thread.sleep(forTimeInterval: 0.5)

        // Select June 16
        let june16 = app.buttons["wizard.dates.day.2026-06-16"]
        XCTAssertTrue(june16.waitForExistence(timeout: 5), "June 16 should exist")
        june16.tap()
        sleep(1)

        // Scroll down to see sports step
        app.swipeUp(velocity: .slow)
        sleep(1)

        // MARK: Step 4 - Pick MLB
        let mlbButton = app.buttons["wizard.sports.mlb"]
        XCTAssertTrue(mlbButton.waitForExistence(timeout: 5), "MLB button should exist")
        mlbButton.tap()
        sleep(1)

        // Scroll down to see regions step
        app.swipeUp(velocity: .slow)
        sleep(1)

        // MARK: Step 5 - Select Central US region
        let centralRegion = app.buttons["wizard.regions.central"]
        XCTAssertTrue(centralRegion.waitForExistence(timeout: 5), "Central region should exist")
        centralRegion.tap()
        sleep(1)

        // Scroll down to see remaining steps
        app.swipeUp(velocity: .slow)
        sleep(1)

        // Keep scrolling for defaults
        app.swipeUp(velocity: .slow)
        sleep(1)

        // MARK: Step 8 - Click "Plan My Trip"
        let planTripButton = app.buttons["wizard.planTripButton"]
        XCTAssertTrue(planTripButton.waitForExistence(timeout: 5), "Plan My Trip button should exist")
        planTripButton.tap()

        // Wait for planning to complete
        sleep(5)

        // MARK: Step 9 - Select "Most Games" from dropdown
        let sortDropdown = app.buttons["tripOptions.sortDropdown"]
        XCTAssertTrue(sortDropdown.waitForExistence(timeout: 15), "Sort dropdown should exist")
        sortDropdown.tap()
        Thread.sleep(forTimeInterval: 0.5)

        let mostGamesOption = app.buttons["tripOptions.sortOption.mostgames"]
        if mostGamesOption.waitForExistence(timeout: 3) {
            mostGamesOption.tap()
        } else {
            app.buttons["Most Games"].tap()
        }
        Thread.sleep(forTimeInterval: 1)

        // MARK: Step 10 - Scroll and select 4th trip
        for _ in 1...3 {
            slowSwipeUp(app: app)
            sleep(1)
        }

        let fourthTrip = app.buttons["tripOptions.trip.3"]
        if fourthTrip.waitForExistence(timeout: 5) {
            fourthTrip.tap()
        } else {
            slowSwipeUp(app: app)
            sleep(1)
            if fourthTrip.waitForExistence(timeout: 3) {
                fourthTrip.tap()
            } else {
                let anyTrip = app.buttons.matching(NSPredicate(format: "identifier BEGINSWITH 'tripOptions.trip.'")).firstMatch
                XCTAssertTrue(anyTrip.waitForExistence(timeout: 5), "At least one trip option should exist")
                anyTrip.tap()
            }
        }
        sleep(2)

        // MARK: Step 12 - Scroll through itinerary
        for _ in 1...5 {
            slowSwipeUp(app: app)
            Thread.sleep(forTimeInterval: 1.5)
        }

        // MARK: Step 13 - Favorite the trip
        for _ in 1...5 {
            slowSwipeDown(app: app)
            Thread.sleep(forTimeInterval: 0.5)
        }

        let favoriteButton = app.buttons["tripDetail.favoriteButton"]
        XCTAssertTrue(favoriteButton.waitForExistence(timeout: 5), "Favorite button should exist")
        favoriteButton.tap()
        sleep(2)
    }

    // MARK: - Helper Methods

    /// Performs a slow swipe up gesture for smooth scrolling
    private func slowSwipeUp(app: XCUIApplication) {
        let start = app.coordinate(withNormalizedOffset: CGVector(dx: 0.5, dy: 0.7))
        let end = app.coordinate(withNormalizedOffset: CGVector(dx: 0.5, dy: 0.3))
        start.press(forDuration: 0.1, thenDragTo: end, withVelocity: .slow, thenHoldForDuration: 0.1)
    }

    /// Performs a slow swipe down gesture for smooth scrolling
    private func slowSwipeDown(app: XCUIApplication) {
        let start = app.coordinate(withNormalizedOffset: CGVector(dx: 0.5, dy: 0.3))
        let end = app.coordinate(withNormalizedOffset: CGVector(dx: 0.5, dy: 0.7))
        start.press(forDuration: 0.1, thenDragTo: end, withVelocity: .slow, thenHoldForDuration: 0.1)
    }

    // MARK: - Basic Tests

    @MainActor
    func testExample() throws {
        let app = XCUIApplication()
        app.launch()
    }

    @MainActor
    func testLaunchPerformance() throws {
        measure(metrics: [XCTApplicationLaunchMetric()]) {
            XCUIApplication().launch()
        }
    }
}
