import XCTest

/// Page object for the login screen.
///
/// Uses accessibility identifiers from `AccessibilityIdentifiers.Authentication`
/// to locate elements. Provides typed actions for login flow interactions.
class LoginScreen: BaseScreen {

    // MARK: - Elements

    var emailField: XCUIElement {
        app.textFields[AccessibilityIdentifiers.Authentication.usernameField]
    }

    var passwordField: XCUIElement {
        // Password field may be a SecureTextField or regular TextField depending on visibility toggle
        let secure = app.secureTextFields[AccessibilityIdentifiers.Authentication.passwordField]
        if secure.exists { return secure }
        return app.textFields[AccessibilityIdentifiers.Authentication.passwordField]
    }

    var loginButton: XCUIElement {
        app.buttons[AccessibilityIdentifiers.Authentication.loginButton]
    }

    var appleSignInButton: XCUIElement {
        app.buttons[AccessibilityIdentifiers.Authentication.appleSignInButton]
    }

    var signUpButton: XCUIElement {
        app.buttons[AccessibilityIdentifiers.Authentication.signUpButton]
    }

    var forgotPasswordButton: XCUIElement {
        app.buttons[AccessibilityIdentifiers.Authentication.forgotPasswordButton]
    }

    var passwordVisibilityToggle: XCUIElement {
        app.buttons[AccessibilityIdentifiers.Authentication.passwordVisibilityToggle]
    }

    var welcomeText: XCUIElement {
        app.staticTexts["Welcome Back"]
    }

    override var isDisplayed: Bool {
        emailField.waitForExistence(timeout: timeout)
    }

    // MARK: - Actions

    /// Logs in with the provided credentials and returns a MainTabScreen.
    /// Waits for the email field to appear before typing.
    @discardableResult
    func login(email: String, password: String) -> MainTabScreen {
        let field = waitForHittable(emailField)
        field.focusAndType(email, app: app)

        passwordField.focusAndType(password, app: app)

        // Submit via keyboard Go/Return button (avoids keyboard-covers-button issue)
        let goButton = app.keyboards.buttons["Go"]
        let returnButton = app.keyboards.buttons["Return"]
        if goButton.waitForExistence(timeout: 3) && goButton.isHittable {
            goButton.tap()
        } else if returnButton.exists && returnButton.isHittable {
            returnButton.tap()
        } else {
            // Dismiss keyboard, then tap login button
            app.coordinate(withNormalizedOffset: CGVector(dx: 0.5, dy: 0.15)).tap()
            _ = app.keyboards.firstMatch.waitForNonExistence(timeout: 3)
            waitForHittable(loginButton).forceTap()
        }
        return MainTabScreen(app: app)
    }

    /// Taps the sign up / register link and returns a RegisterScreen.
    @discardableResult
    func tapSignUp() -> RegisterScreen {
        waitForElement(signUpButton).tap()
        return RegisterScreen(app: app)
    }

    /// Taps the forgot password link.
    func tapForgotPassword() {
        waitForElement(forgotPasswordButton).tap()
    }

    /// Toggles password visibility and returns whether the password is now visible.
    @discardableResult
    func togglePasswordVisibility() -> Bool {
        waitForElement(passwordVisibilityToggle).tap()
        // If a regular text field with the password identifier exists, password is visible
        return app.textFields[AccessibilityIdentifiers.Authentication.passwordField].exists
    }
}
