import XCTest

/// UI Tests for Portfolio Journal app
/// These tests verify the app's user interface and navigation flows
final class PortfolioJournalUITests: XCTestCase {

    var app: XCUIApplication!

    override func setUpWithError() throws {
        continueAfterFailure = false
        app = XCUIApplication()
        app.launchArguments = ["--uitesting"]
        app.launch()
    }

    override func tearDownWithError() throws {
        app = nil
    }

    // MARK: - App Launch Tests

    func testAppLaunches() throws {
        // Verify the app launches successfully
        XCTAssertTrue(app.exists)
    }

    func testTabBarExists() throws {
        // Wait for the tab bar to appear
        let tabBar = app.tabBars.firstMatch
        let exists = tabBar.waitForExistence(timeout: 5)
        XCTAssertTrue(exists, "Tab bar should exist after launch")
    }

    // MARK: - Navigation Tests

    func testDashboardTabIsSelected() throws {
        // Dashboard should be the default selected tab
        let tabBar = app.tabBars.firstMatch
        _ = tabBar.waitForExistence(timeout: 5)

        // Look for Dashboard tab button
        let dashboardTab = tabBar.buttons["Dashboard"]
        if dashboardTab.exists {
            XCTAssertTrue(dashboardTab.isSelected || dashboardTab.isHittable)
        }
    }

    func testNavigateToSourcesTab() throws {
        let tabBar = app.tabBars.firstMatch
        _ = tabBar.waitForExistence(timeout: 5)

        let sourcesTab = tabBar.buttons["Sources"]
        if sourcesTab.exists {
            sourcesTab.tap()
            // Verify we're on the Sources screen
            XCTAssertTrue(sourcesTab.isSelected || sourcesTab.isHittable)
        }
    }

    func testNavigateToGoalsTab() throws {
        let tabBar = app.tabBars.firstMatch
        _ = tabBar.waitForExistence(timeout: 5)

        let goalsTab = tabBar.buttons["Goals"]
        if goalsTab.exists {
            goalsTab.tap()
            XCTAssertTrue(goalsTab.isSelected || goalsTab.isHittable)
        }
    }

    func testNavigateToJournalTab() throws {
        let tabBar = app.tabBars.firstMatch
        _ = tabBar.waitForExistence(timeout: 5)

        let journalTab = tabBar.buttons["Journal"]
        if journalTab.exists {
            journalTab.tap()
            XCTAssertTrue(journalTab.isSelected || journalTab.isHittable)
        }
    }

    func testNavigateToSettingsTab() throws {
        let tabBar = app.tabBars.firstMatch
        _ = tabBar.waitForExistence(timeout: 5)

        let settingsTab = tabBar.buttons["Settings"]
        if settingsTab.exists {
            settingsTab.tap()
            XCTAssertTrue(settingsTab.isSelected || settingsTab.isHittable)
        }
    }

    // MARK: - All Tabs Navigation Test

    func testNavigateThroughAllTabs() throws {
        let tabBar = app.tabBars.firstMatch
        guard tabBar.waitForExistence(timeout: 5) else {
            XCTFail("Tab bar not found")
            return
        }

        let tabs = ["Dashboard", "Sources", "Goals", "Journal", "Settings"]

        for tabName in tabs {
            let tab = tabBar.buttons[tabName]
            if tab.exists && tab.isHittable {
                tab.tap()
                // Give time for navigation
                Thread.sleep(forTimeInterval: 0.3)
            }
        }

        // Return to Dashboard
        let dashboardTab = tabBar.buttons["Dashboard"]
        if dashboardTab.exists {
            dashboardTab.tap()
        }
    }

    // MARK: - App Store Screenshot Capture

    /// Captures the redesigned iPad Charts screen (sidebar tiles + KPI header).
    /// Works on both iPad (sidebar buttons) and iPhone (tab bar).
    func testCaptureChartsScreen() throws {
        let capture = XCUIApplication()
        capture.launchArguments = ["--screenshots"]
        capture.launch()

        // Wait for main UI (tab bar on iPhone, sidebar on iPad)
        Thread.sleep(forTimeInterval: 4.0)

        // Dismiss the notification-permission system alert if it appears
        let springboard = XCUIApplication(bundleIdentifier: "com.apple.springboard")
        let denyButton = springboard.alerts.buttons["Don't Allow"]
        if denyButton.waitForExistence(timeout: 3) {
            denyButton.tap()
            Thread.sleep(forTimeInterval: 1.0)
        }

        // Try tab bar first (iPhone), then any button labeled Charts (iPad sidebar)
        let tabBar = capture.tabBars.firstMatch
        if tabBar.exists && tabBar.buttons["Charts"].exists {
            tabBar.buttons["Charts"].tap()
        } else {
            let chartsButton = capture.buttons["Charts"].firstMatch
            if chartsButton.waitForExistence(timeout: 5) {
                chartsButton.tap()
            } else {
                capture.staticTexts["Charts"].firstMatch.tap()
            }
        }
        Thread.sleep(forTimeInterval: 3.0)

        func snap(_ name: String) {
            let shot = XCTAttachment(screenshot: capture.screenshot())
            shot.name = name
            shot.lifetime = .keepAlways
            add(shot)
        }

        snap("01_Evolution_default")

        // Switch period to All (exercises the shared snapshot cache across ranges)
        let allSegment = capture.buttons["All"].firstMatch
        if allSegment.waitForExistence(timeout: 3) {
            allSegment.tap()
            Thread.sleep(forTimeInterval: 2.0)
            snap("02_Evolution_All")
        }

        // Switch chart type to a free multi-control chart and back (cache reuse path)
        let compareTile = capture.buttons["Compare"].firstMatch
        if compareTile.waitForExistence(timeout: 3) {
            compareTile.tap()
            Thread.sleep(forTimeInterval: 2.0)
            snap("03_Compare")
        }
        let periodTile = capture.buttons["Period vs Period"].firstMatch
        if periodTile.waitForExistence(timeout: 3) {
            periodTile.tap()
            Thread.sleep(forTimeInterval: 2.0)
            snap("04_PeriodVsPeriod")
        }
        let evolutionTile = capture.buttons["Evolution"].firstMatch
        if evolutionTile.waitForExistence(timeout: 3) {
            evolutionTile.tap()
            Thread.sleep(forTimeInterval: 2.0)
            snap("05_Evolution_back")
        }
    }

    /// Captures full-screen screenshots of the main tabs with demo data for App Store
    /// marketing. Launches the app in `--screenshots` mode (onboarding/lock skipped,
    /// SampleDataService seeded). Language can be driven via the SCREENSHOT_LANG env var
    /// (e.g. "es", "de"). Screenshots are attached to the test result and extracted from
    /// the .xcresult afterwards by the framing pipeline.
    func testCaptureScreenshots() throws {
        let capture = XCUIApplication()
        capture.launchArguments = ["--screenshots"]
        if let lang = ProcessInfo.processInfo.environment["SCREENSHOT_LANG"], !lang.isEmpty {
            capture.launchArguments += ["-AppleLanguages", "(\(lang))", "-AppleLocale", lang]
        }
        capture.launch()

        let tabBar = capture.tabBars.firstMatch
        guard tabBar.waitForExistence(timeout: 20) else {
            XCTFail("Tab bar not found in screenshot mode")
            return
        }
        // Let demo data seed and charts render.
        Thread.sleep(forTimeInterval: 3.0)

        func snap(_ name: String) {
            let shot = XCTAttachment(screenshot: capture.screenshot())
            shot.name = name
            shot.lifetime = .keepAlways
            add(shot)
        }

        // Dashboard is already selected on launch.
        snap("01_Dashboard")

        for (index, tabName) in ["Sources", "Goals", "Journal", "Settings"].enumerated() {
            let tab = tabBar.buttons[tabName]
            if tab.waitForExistence(timeout: 5), tab.isHittable {
                tab.tap()
                Thread.sleep(forTimeInterval: 1.5)
                snap(String(format: "%02d_%@", index + 2, tabName))
            }
        }
    }
}
