//
//  BlackjackUITests.swift
//  BlackjackUITests
//
//  Created by Matt Bruce on 12/17/25.
//

import XCTest

final class BlackjackUITests: XCTestCase {
    
    var app: XCUIApplication!

    override func setUpWithError() throws {
        // Put setup code here. This method is called before the invocation of each test method in the class.

        // In UI tests it is usually best to stop immediately when a failure occurs.
        continueAfterFailure = false
        
        app = XCUIApplication()
        app.launchArguments = ["UI-TESTING"]
        
        // In UI tests it's important to set the initial state - such as interface orientation - required for your tests before they run. The setUp method is a good place to do this.
    }

    override func tearDownWithError() throws {
        // Put teardown code here. This method is called after the invocation of each test method in the class.
        app = nil
    }

    @MainActor
    func testExample() throws {
        // UI tests must launch the application that they test.
        app.launch()

        // Use XCTAssert and related functions to verify your tests produce the correct results.
    }
    
    // MARK: - UI Navigation Tests
    
    @MainActor
    func testAppLaunches() throws {
        app.launch()
        XCTAssertTrue(app.exists, "App should launch successfully")
    }
    
    @MainActor
    func testTopBarElements() throws {
        app.launch()
        
        // Wait for the app to load
        let balanceText = app.staticTexts.matching(identifier: "balance").firstMatch
        XCTAssertTrue(balanceText.waitForExistence(timeout: 2), "Balance should be visible")
        
        // Check settings button exists
        let settingsButton = app.buttons.matching(identifier: "settings").firstMatch
        XCTAssertTrue(settingsButton.exists, "Settings button should exist")
        
        // Check help button exists
        let helpButton = app.buttons.matching(identifier: "help").firstMatch
        XCTAssertTrue(helpButton.exists, "Help button should exist")
        
        // Check stats button exists
        let statsButton = app.buttons.matching(identifier: "stats").firstMatch
        XCTAssertTrue(statsButton.exists, "Stats button should exist")
    }
    
    @MainActor
    func testSettingsSheet() throws {
        app.launch()
        
        // Find and tap settings button
        let settingsButton = app.buttons.matching(identifier: "settings").firstMatch
        XCTAssertTrue(settingsButton.waitForExistence(timeout: 2), "Settings button should exist")
        settingsButton.tap()
        
        // Wait for settings sheet to appear
        let settingsSheet = app.scrollViews.firstMatch
        XCTAssertTrue(settingsSheet.waitForExistence(timeout: 2), "Settings sheet should appear")
        
        // Check for some expected elements in settings
        XCTAssertTrue(app.staticTexts["Table Limits"].waitForExistence(timeout: 1) || 
                     app.staticTexts["Game Settings"].waitForExistence(timeout: 1), 
                     "Settings content should be visible")
        
        // Close settings (tap outside or dismiss button)
        if app.buttons["Done"].exists {
            app.buttons["Done"].tap()
        } else {
            // Tap outside to dismiss
            app.coordinate(withNormalizedOffset: CGVector(dx: 0.1, dy: 0.1)).tap()
        }
    }
    
    @MainActor
    func testHelpSheet() throws {
        app.launch()
        
        // Find and tap help button
        let helpButton = app.buttons.matching(identifier: "help").firstMatch
        XCTAssertTrue(helpButton.waitForExistence(timeout: 2), "Help button should exist")
        helpButton.tap()
        
        // Wait for help sheet to appear
        let helpSheet = app.scrollViews.firstMatch
        XCTAssertTrue(helpSheet.waitForExistence(timeout: 2), "Help sheet should appear")
        
        // Check for rules content
        XCTAssertTrue(app.staticTexts["Rules"].exists || 
                     app.staticTexts["How to Play"].exists,
                     "Rules content should be visible")
    }
    
    // MARK: - Betting Tests
    
    @MainActor
    func testChipSelector() throws {
        app.launch()
        
        // Wait for chip selector to appear
        let chipSelector = app.otherElements["chip-selector"]
        XCTAssertTrue(chipSelector.waitForExistence(timeout: 2) || 
                     app.buttons.matching(NSPredicate(format: "label CONTAINS '$'")).count > 0,
                     "Chip selector should be visible")
        
        // Find a chip button (they should have $ in the label)
        let chipButtons = app.buttons.matching(NSPredicate(format: "label CONTAINS '$'"))
        XCTAssertGreaterThan(chipButtons.count, 0, "Should have chip buttons")
    }
    
    @MainActor
    func testPlaceBet() throws {
        app.launch()
        
        // Wait for betting area
        sleep(1)
        
        // Find deal button (should be disabled initially)
        let dealButton = app.buttons["Deal"]
        XCTAssertTrue(dealButton.waitForExistence(timeout: 2), "Deal button should exist")
        
        // Initially deal button should be disabled
        XCTAssertFalse(dealButton.isEnabled, "Deal button should be disabled before bet")
        
        // Tap on betting zone
        let bettingZone = app.otherElements["betting-zone"]
        if bettingZone.exists {
            bettingZone.tap()
            
            // Deal button should now be enabled (or still disabled if bet is below minimum)
            // We can't reliably test this without knowing the bet amount vs minimum
        }
    }
    
    @MainActor
    func testClearButton() throws {
        app.launch()
        
        // Wait and place a bet by tapping betting zone
        sleep(1)
        let bettingZone = app.otherElements["betting-zone"]
        if bettingZone.exists {
            bettingZone.tap()
        }
        
        // Find clear button
        let clearButton = app.buttons["Clear"]
        if clearButton.exists {
            clearButton.tap()
            
            // After clearing, deal button should be disabled again
            let dealButton = app.buttons["Deal"]
            XCTAssertFalse(dealButton.isEnabled, "Deal button should be disabled after clear")
        }
    }
    
    // MARK: - Gameplay Tests
    
    @MainActor
    func testDealCards() throws {
        app.launch()
        
        sleep(1)
        
        // Place a bet by tapping betting zone multiple times to ensure we meet minimum
        let bettingZone = app.otherElements["betting-zone"]
        if bettingZone.exists {
            for _ in 1...5 {
                bettingZone.tap()
            }
        }
        
        // Find and tap deal button
        let dealButton = app.buttons["Deal"]
        if dealButton.waitForExistence(timeout: 2) && dealButton.isEnabled {
            dealButton.tap()
            
            // Wait for cards to be dealt
            sleep(2)
            
            // After dealing, we should see hit/stand buttons or a result
            let hitButton = app.buttons["Hit"]
            let standButton = app.buttons["Stand"]
            let newRoundButton = app.buttons["New Round"]
            
            XCTAssertTrue(hitButton.exists || standButton.exists || newRoundButton.exists,
                         "Should see action buttons after dealing")
        }
    }

    @MainActor
    func testLaunchPerformance() throws {
        // This measures how long it takes to launch your application.
        measure(metrics: [XCTApplicationLaunchMetric()]) {
            XCUIApplication().launch()
        }
    }
}
