//
//  BaccaratUITests.swift
//  BaccaratUITests
//
//  Created by Matt Bruce on 12/16/25.
//

import XCTest

final class BaccaratUITests: 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 testBettingZones() throws {
        app.launch()
        
        // Wait for betting table
        sleep(1)
        
        // Check for Player, Banker, and Tie betting zones
        let playerZone = app.staticTexts["PLAYER"]
        let bankerZone = app.staticTexts["BANKER"]
        let tieZone = app.staticTexts["TIE"]
        
        XCTAssertTrue(playerZone.exists, "Player betting zone should exist")
        XCTAssertTrue(bankerZone.exists, "Banker betting zone should exist")
        XCTAssertTrue(tieZone.exists, "Tie betting zone should exist")
    }
    
    @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 Player betting zone
        let playerZone = app.staticTexts["PLAYER"]
        if playerZone.exists {
            // Tap multiple times to ensure we meet minimum bet
            for _ in 1...5 {
                playerZone.tap()
            }
            
            // Deal button should now be enabled after placing sufficient bet
            sleep(1)
            // Note: Button might still be disabled if bet is below minimum
        }
    }
    
    @MainActor
    func testClearButton() throws {
        app.launch()
        
        // Wait and place a bet
        sleep(1)
        let playerZone = app.staticTexts["PLAYER"]
        if playerZone.exists {
            playerZone.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 on Player by tapping multiple times
        let playerZone = app.staticTexts["PLAYER"]
        if playerZone.exists {
            for _ in 1...5 {
                playerZone.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(3)
            
            // After dealing, we should see hand value badges or a result
            // Check for the PLAYER and BANKER labels which should still be visible
            let playerLabel = app.staticTexts["PLAYER"]
            let bankerLabel = app.staticTexts["BANKER"]
            
            XCTAssertTrue(playerLabel.exists, "Player label should be visible after deal")
            XCTAssertTrue(bankerLabel.exists, "Banker label should be visible after deal")
            
            // Eventually a New Round button should appear
            let newRoundButton = app.buttons["New Round"]
            XCTAssertTrue(newRoundButton.waitForExistence(timeout: 5), "New Round button should appear")
        }
    }
    
    @MainActor
    func testRoadMapExists() throws {
        app.launch()
        
        // Road map might not be visible on small screens or in portrait mode
        // This is an optional test that checks if enabled in settings
        sleep(1)
        
        // Look for history text or road map elements
        let historyText = app.staticTexts["HISTORY"]
        // Road map is conditional, so this is not a required assertion
        // Just checking it doesn't crash
        _ = historyText.exists
    }

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