//
//  SuixinkanUIApplication.swift
//  suixinkanUITests
//
//  Created by Codex on 2026/6/26.
//

import XCTest

/// 封装 XCUIApplication 的常用等待、权限弹窗和全局 Loading 处理。
final class SuixinkanApp {
    let application: XCUIApplication
    private let resetState: Bool
    private var hasLaunched = false

    /// 创建并配置 UI Test 启动参数的应用实例。
    init(
        resetState: Bool = false,
        openMenuTitle: String? = nil,
        openProfileRoute: String? = nil
    ) {
        self.resetState = resetState
        application = XCUIApplication()
        UITestLaunchConfiguration.apply(
            to: application,
            resetState: resetState,
            openMenu: openMenuTitle,
            openProfile: openProfileRoute
        )
    }

    /// 启动 App 并等待首屏稳定。
    @discardableResult
    func launch(waitForLoading: Bool = true) -> Self {
        if hasLaunched, application.state == .runningForeground {
            application.activate()
        } else {
            if application.state != .notRunning {
                application.terminate()
                Thread.sleep(forTimeInterval: 0.5)
            }
            application.launch()
            hasLaunched = true
        }
        dismissSystemAlertsIfNeeded()
        if waitForLoading {
            waitForGlobalLoadingToDisappear()
        }
        return self
    }

    /// 等待全局 Loading 层消失。
    func waitForGlobalLoadingToDisappear(timeout: TimeInterval = 45) {
        let loading = application.staticTexts["加载中"]
        guard loading.waitForExistence(timeout: 2) else { return }

        let predicate = NSPredicate(format: "exists == false")
        let expectation = XCTNSPredicateExpectation(predicate: predicate, object: loading)
        _ = XCTWaiter.wait(for: [expectation], timeout: timeout)
    }

    /// 处理系统权限弹窗，尽量点允许以便页面继续加载。
    func dismissSystemAlertsIfNeeded() {
        let springboard = XCUIApplication(bundleIdentifier: "com.apple.springboard")
        let allowButtons = ["允许", "好", "使用App时允许", "Allow", "Allow While Using App", "OK"]
        for title in allowButtons {
            let button = springboard.buttons[title]
            if button.waitForExistence(timeout: 1) {
                button.tap()
            }
        }
    }

    /// 判断当前是否仍在登录页。
    var isOnLoginScreen: Bool {
        application.staticTexts["login.title"].exists
    }

    /// 判断主 Tab 是否已出现。
    var isOnMainTabs: Bool {
        TabBarNavigator.isVisible(in: self)
    }

    /// 等待冷启动后进入登录页或主 Tab。
    func waitForInitialScreen(timeout: TimeInterval = 45) {
        if application.staticTexts["login.title"].waitForExistence(timeout: 2) {
            return
        }

        let deadline = Date().addingTimeInterval(timeout)
        while Date() < deadline {
            if isOnMainTabs {
                return
            }
            RunLoop.current.run(until: Date().addingTimeInterval(0.2))
        }
    }
}
