package ru.otus.mobile.screens;

import org.openqa.selenium.WebElement;
import ru.otus.mobile.ui.MobileUi;

public class LoginScreen {

    public boolean isVisible() {
        return MobileUi.existsById("username_text_input")
                || MobileUi.existsById("password_text_input");
    }

    public void loginOrRegister(String username, String password, boolean allowRegister) {
        if (!isVisible()) {
            return;
        }
        attemptLogin(username, password);
        if (!isVisible()) {
            return;
        }
        dismissDialogIfPresent();
        if (!isVisible()) {
            return;
        }
        if (allowRegister) {
            if (isRegistrationScreen()) {
                completeRegistration(username, password);
                ensureLoginCompleted();
                return;
            }
            if (openRegistrationScreen()) {
                completeRegistration(username, password);
                ensureLoginCompleted();
                return;
            }
        }
        if (isVisible()) {
            throw new IllegalStateException(
                    "Login did not complete. Provide valid credentials or enable registration."
            );
        }
    }

    private boolean isRegistrationScreen() {
        return MobileUi.existsById("email_text_input")
                || MobileUi.byTextContains("Регистрация").exists();
    }

    private boolean openRegistrationScreen() {
        if (clickRegisterLink()) {
            return MobileUi.existsById("email_text_input");
        }
        return false;
    }

    private boolean clickRegisterLink() {
        if (MobileUi.existsById("register_button")) {
            MobileUi.byIdOrAccessibility("register_button").click();
            return true;
        }
        if (MobileUi.byTextContains("Регистрац").exists()) {
            MobileUi.byTextContains("Регистрац").click();
            return true;
        }
        if (MobileUi.byTextContains("Зарегистр").exists()) {
            MobileUi.byTextContains("Зарегистр").click();
            return true;
        }
        MobileUi.hideKeyboard(); // hide keyboard to reveal link
        if (MobileUi.byTextContains("Регистрац").exists()) {
            MobileUi.byTextContains("Регистрац").click();
            return true;
        }
        if (MobileUi.byTextContains("Зарегистр").exists()) {
            MobileUi.byTextContains("Зарегистр").click();
            return true;
        }
        return false;
    }

    private void completeRegistration(String username, String password) {
        typeInto("username_text_input", username);
        if (MobileUi.existsById("email_text_input")) {
            typeInto("email_text_input", username + "@test.local");
        }
        if (MobileUi.existsById("password_text_input")) {
            typeInto("password_text_input", password);
        }
        fillRepeatPasswordIfPresent(password);
        MobileUi.hideKeyboard(); // hide keyboard so buttons are visible
        if (MobileUi.existsById("register_button")) {
            MobileUi.byIdOrAccessibility("register_button").click();
            dismissDialogIfPresent();
            finishLoginAfterRegistration(username, password);
            return;
        }
        if (MobileUi.byTextContains("ЗАРЕГИСТРИРОВАТЬСЯ").exists()) {
            MobileUi.byTextContains("ЗАРЕГИСТРИРОВАТЬСЯ").click();
            dismissDialogIfPresent();
            finishLoginAfterRegistration(username, password);
        }
    }

    private void finishLoginAfterRegistration(String username, String password) {
        if (MobileUi.existsById("log_in_button") || isLoginScreen()) {
            typeInto("username_text_input", username);
            if (MobileUi.existsById("password_text_input")) {
                typeInto("password_text_input", password);
            }
            MobileUi.hideKeyboard();
            if (MobileUi.existsById("log_in_button")) {
                MobileUi.byIdOrAccessibility("log_in_button").click();
            }
            return;
        }
        if (isRegistrationScreen()) {
            MobileUi.back();
            if (isLoginScreen()) {
                typeInto("username_text_input", username);
                if (MobileUi.existsById("password_text_input")) {
                    typeInto("password_text_input", password);
                }
            MobileUi.hideKeyboard();
            if (MobileUi.existsById("log_in_button")) {
                MobileUi.byIdOrAccessibility("log_in_button").click();
            }
        }
            if (isRegistrationScreen()) {
                throw new IllegalStateException("Registration did not complete. Check password rules and required fields.");
            }
        }
    }

    private boolean isLoginScreen() {
        return MobileUi.existsById("username_text_input")
                && !MobileUi.existsById("email_text_input");
    }

    private void typeInto(String id, String value) {
        WebElement input = MobileUi.byIdOrAccessibility(id)
                .toWebElement();
        input.click();
        input.clear();
        input.sendKeys(value);
    }

    private void attemptLogin(String username, String password) {
        if (!MobileUi.existsById("username_text_input")) {
            return;
        }
        typeInto("username_text_input", username);
        if (MobileUi.existsById("password_text_input")) {
            typeInto("password_text_input", password);
        }
        MobileUi.hideKeyboard();
        if (MobileUi.existsById("log_in_button")) {
            MobileUi.byIdOrAccessibility("log_in_button").click();
        }
        dismissDialogIfPresent();
    }

    private void fillRepeatPasswordIfPresent(String password) {
        String[] repeatIds = {
                "repeat_password_text_input",
                "password_repeat_text_input",
                "confirm_password_text_input",
                "password_confirm_text_input"
        };
        for (String id : repeatIds) {
            if (MobileUi.existsById(id)) {
                typeInto(id, password);
                return;
            }
        }
    }

    private void dismissDialogIfPresent() {
        if (MobileUi.existsById("android:id/button1")) {
            MobileUi.byIdOrAccessibility("android:id/button1").click();
            return;
        }
        if (MobileUi.byTextContains("OK").exists()) {
            MobileUi.byTextContains("OK").click();
            return;
        }
        if (MobileUi.byTextContains("ОК").exists()) {
            MobileUi.byTextContains("ОК").click();
        }
    }

    private void ensureLoginCompleted() {
        dismissDialogIfPresent();
    }
}
