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

import XCTest

/// 登录与多账号选择流程封装。
enum LoginFlow {
    /// 如当前在登录页则执行完整登录，否则直接返回。
    static func loginIfNeeded(
        app: SuixinkanApp,
        credentials: UITestCredentials,
        file: StaticString = #filePath,
        line: UInt = #line
    ) {
        guard app.isOnLoginScreen else { return }

        app.application.activate()
        app.waitForGlobalLoadingToDisappear()
        fillLoginForm(app: app, credentials: credentials)
        submitLogin(app: app)
        handleAccountSelectionIfNeeded(app: app, credentials: credentials)
        app.waitForGlobalLoadingToDisappear()

        XCTAssertTrue(
            app.isOnMainTabs,
            "登录后应进入主 Tab。",
            file: file,
            line: line
        )
    }

    /// 填写登录表单并勾选协议。
    static func fillLoginForm(app: SuixinkanApp, credentials: UITestCredentials) {
        let usernameField = app.application.textFields["login.username"]
        XCTAssertTrue(usernameField.waitForExistence(timeout: 12))

        let currentPhone = usernameField.value as? String
        if currentPhone != credentials.phone {
            tapWhenReady(usernameField)
            usernameField.clearAndType(credentials.phone)
        }

        let passwordField = preferredPasswordField(in: app.application)
        XCTAssertTrue(passwordField.waitForExistence(timeout: 4))
        tapWhenReady(passwordField)
        passwordField.clearAndType(credentials.password)

        let privacyToggle = app.application.buttons["login.privacy"]
        if privacyToggle.exists, privacyToggle.isHittable {
            privacyToggle.tap()
        }
    }

    /// 点击登录按钮。
    static func submitLogin(app: SuixinkanApp) {
        let submitButton = app.application.buttons["login.submit"]
        XCTAssertTrue(submitButton.waitForExistence(timeout: 4))
        tapWhenReady(submitButton)
        app.waitForGlobalLoadingToDisappear()
    }

    /// 处理 v9 多账号选择页。
    static func handleAccountSelectionIfNeeded(
        app: SuixinkanApp,
        credentials: UITestCredentials
    ) {
        let accountSelectionTitle = app.application.navigationBars["选择账号"]
        guard accountSelectionTitle.waitForExistence(timeout: 6) else { return }

        if let accountName = credentials.accountName {
            let accountCell = app.application.staticTexts[accountName]
            if accountCell.waitForExistence(timeout: 4) {
                accountCell.tap()
            }
        }

        let confirmButton = app.application.buttons["进入系统"]
        XCTAssertTrue(confirmButton.waitForExistence(timeout: 4))
        confirmButton.tap()
        app.waitForGlobalLoadingToDisappear()
    }

    /// 优先读取安全输入框，兼容调试构建下的普通文本框。
    private static func preferredPasswordField(in app: XCUIApplication) -> XCUIElement {
        let secureField = app.secureTextFields["login.password"]
        if secureField.exists {
            return secureField
        }
        return app.textFields["login.password"]
    }

    /// 等待元素可点后点击，不可点时退化为坐标点击。
    private static func tapWhenReady(_ element: XCUIElement) {
        let deadline = Date().addingTimeInterval(8)
        while Date() < deadline {
            if element.isHittable {
                element.tap()
                return
            }
            RunLoop.current.run(until: Date().addingTimeInterval(0.2))
        }

        element.coordinate(withNormalizedOffset: CGVector(dx: 0.5, dy: 0.5)).tap()
    }
}

private extension XCUIElement {
    /// 清空并重新输入文本。
    func clearAndType(_ text: String) {
        guard let currentValue = value as? String, !currentValue.isEmpty else {
            typeText(text)
            return
        }

        tap()
        let deleteString = String(repeating: XCUIKeyboardKey.delete.rawValue, count: currentValue.count)
        typeText(deleteString)
        typeText(text)
    }
}
