import XCTest

final class AuthenticationTests: BaseUITestCase {
    override var completeOnboarding: Bool { true }
    override var relaunchBetweenTests: Bool { true }

    func testF201_OnboardingLoginEntryShowsLoginScreen() {
        let login = TestFlows.navigateToLoginFromOnboarding(app: app)
        login.waitForLoad(timeout: defaultTimeout)
    }

    func testF202_LoginScreenCanTogglePasswordVisibility() {
        let login = TestFlows.navigateToLoginFromOnboarding(app: app)
        login.enterUsername("u")
        login.enterPassword("p")
        login.tapPasswordVisibilityToggle()
        login.assertPasswordFieldVisible()
    }

    func testF203_RegisterSheetCanOpenAndDismiss() {
        let login = TestFlows.navigateToLoginFromOnboarding(app: app)
        login.waitForLoad(timeout: defaultTimeout)
        login.tapSignUp()

        let register = RegisterScreenObject(app: app)
        register.waitForLoad(timeout: navigationTimeout)
        register.tapCancel()

        login.waitForLoad(timeout: navigationTimeout)
    }

    func testF204_RegisterFormAcceptsInput() {
        let login = TestFlows.navigateToLoginFromOnboarding(app: app)
        login.waitForLoad(timeout: defaultTimeout)
        login.tapSignUp()

        let register = RegisterScreenObject(app: app)
        register.waitForLoad(timeout: navigationTimeout)

        XCTAssertTrue(app.buttons[UITestID.Auth.registerButton].exists, "Register button should exist on register form")
    }

    func testF205_LoginButtonDisabledWhenCredentialsAreEmpty() {
        let login = TestFlows.navigateToLoginFromOnboarding(app: app)
        login.waitForLoad(timeout: defaultTimeout)

        let loginButton = app.buttons[UITestID.Auth.loginButton]
        loginButton.waitForExistenceOrFail(timeout: defaultTimeout)
        XCTAssertFalse(loginButton.isEnabled, "Login button should be disabled when username/password are empty")
    }

    func testF206_ForgotPasswordButtonIsAccessible() {
        let login = TestFlows.navigateToLoginFromOnboarding(app: app)
        login.waitForLoad(timeout: defaultTimeout)

        let forgotButton = app.buttons[UITestID.Auth.forgotPasswordButton]
        forgotButton.waitForExistenceOrFail(timeout: defaultTimeout)
        XCTAssertTrue(forgotButton.isHittable, "Forgot password button should be hittable on login screen")
    }

    func testF207_LoginScreenShowsAllExpectedElements() {
        let login = TestFlows.navigateToLoginFromOnboarding(app: app)
        login.waitForLoad(timeout: defaultTimeout)

        XCTAssertTrue(app.textFields[UITestID.Auth.usernameField].exists, "Username field should exist")
        XCTAssertTrue(
            app.secureTextFields[UITestID.Auth.passwordField].exists || app.textFields[UITestID.Auth.passwordField].exists,
            "Password field should exist"
        )
        XCTAssertTrue(app.buttons[UITestID.Auth.loginButton].exists, "Login button should exist")
        XCTAssertTrue(app.buttons[UITestID.Auth.signUpButton].exists, "Sign up button should exist")
        XCTAssertTrue(app.buttons[UITestID.Auth.forgotPasswordButton].exists, "Forgot password button should exist")
        XCTAssertTrue(app.buttons[UITestID.Auth.passwordVisibilityToggle].exists, "Password visibility toggle should exist")
    }

    func testF208_RegisterFormShowsAllRequiredFields() {
        let login = TestFlows.navigateToLoginFromOnboarding(app: app)
        login.waitForLoad(timeout: defaultTimeout)
        login.tapSignUp()

        let register = RegisterScreenObject(app: app)
        register.waitForLoad(timeout: navigationTimeout)

        XCTAssertTrue(app.textFields[UITestID.Auth.registerUsernameField].exists, "Register username field should exist")
        XCTAssertTrue(app.textFields[UITestID.Auth.registerEmailField].exists, "Register email field should exist")
        XCTAssertTrue(app.secureTextFields[UITestID.Auth.registerPasswordField].exists, "Register password field should exist")
        XCTAssertTrue(app.secureTextFields[UITestID.Auth.registerConfirmPasswordField].exists, "Register confirm password field should exist")
        XCTAssertTrue(app.buttons[UITestID.Auth.registerButton].exists, "Register button should exist")
        XCTAssertTrue(app.buttons[UITestID.Auth.registerCancelButton].exists, "Register cancel button should exist")
    }

    func testF209_ForgotPasswordNavigatesToResetFlow() {
        let login = TestFlows.navigateToLoginFromOnboarding(app: app)
        login.waitForLoad(timeout: defaultTimeout)
        login.tapForgotPassword()

        // Verify forgot password screen loaded by checking for its email field (accessibility ID, not label)
        let emailField = app.textFields[UITestID.PasswordReset.emailField]
        let sendCodeButton = app.buttons[UITestID.PasswordReset.sendCodeButton]
        let loaded = emailField.waitForExistence(timeout: navigationTimeout)
            || sendCodeButton.waitForExistence(timeout: navigationTimeout)
        XCTAssertTrue(loaded, "Forgot password screen should appear with email field or send code button")
    }
}
