package tests;

import core.BaseTest;
import core.Browser;
import core.BrowserArgumentProvider;
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.ArgumentsSource;
import pages.InboxPage;
import pages.LoginPage;
import pages.RegistrationPage;
import pages.ResetPasswordPage;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.openqa.selenium.support.PageFactory.initElements;

/**
 * @author kote
 */
public class LoginIT extends BaseTest {

  private static final String PART_FOR_NAME = "userForLogin";
  private static final String REG_EMAIL = "qa_new_account@mail.ru";
  private static final String RESET_EMAIL = "password_recovery_account@mail.ru";

  public LoginIT() {
    super();
  }

  @AfterAll
  public static void afterAll() {
    EXECUTION_MANAGER.deleteUserByEmail(REG_EMAIL);
    EXECUTION_MANAGER.deleteUserByEmail(RESET_EMAIL);
  }

  @ParameterizedTest
  @ArgumentsSource(BrowserArgumentProvider.class)
  public void checkLoginWithWrongData(Browser browser) {
    LoginPage loginPage = openApp(browser);
    assertTrue(loginPage.pageLoadSuccessfully());

    String wrongData = "wrong_test";
    loginPage.typeLoginPasswordAndEnter(wrongData, wrongData);
    assertEquals("Неправильный логин или пароль", loginPage.getLoginErrorText());
  }

  @ParameterizedTest
  @ArgumentsSource(BrowserArgumentProvider.class)
  public void checkDisplayUserFio(Browser browser) {
    InboxPage inboxPage = loginInApp(browser);
    assertTrue(inboxPage.pageLoadSuccessfully());

    inboxPage.clickOnMenu("Пользователь");
    assertEquals("Основной-Тестовый Пользователь", inboxPage.getUserFIO());
  }

  @ParameterizedTest
  @ArgumentsSource(BrowserArgumentProvider.class)
  public void checkTransitionsBetweenForms(Browser browser) {
    LoginPage loginPage = openApp(browser);
    assertTrue(loginPage.pageLoadSuccessfully());

    //check transition to registration page:
    loginPage.registrationLinkClick();
    RegistrationPage registrationPage = initElements(driver, RegistrationPage.class);
    assertTrue(registrationPage.pageLoadSuccessfully());
    assertTrue(registrationPage.isHeaderVisible());

    //check phone mask:
    assertEquals("+7 ", registrationPage.getMaskForPhone());
    registrationPage.selectCountry("Albania");
    assertEquals("+355 ", registrationPage.getMaskForPhone());

    //check password view:
    assertTrue(registrationPage.isPasswordDisplayedAsSymbols());
    registrationPage.passwordEyeButtonClick();
    assertTrue(registrationPage.isPasswordDisplayedAsText());

    //check transition to login page from registration page:
    registrationPage.loginLinkClick();
    assertTrue(loginPage.pageLoadSuccessfully());
    assertTrue(loginPage.isHeaderVisible());

    //check transition to password recovery page:
    loginPage.resetPasswordLinkClick();
    ResetPasswordPage resetPasswordPage = initElements(driver, ResetPasswordPage.class);
    assertTrue(resetPasswordPage.pageLoadSuccessfully());
    assertTrue(resetPasswordPage.isHeaderVisible());

    //check transition to login page from password recovery page:
    resetPasswordPage.loginLinkClick();
    assertTrue(loginPage.pageLoadSuccessfully());
    assertTrue(loginPage.isHeaderVisible());
  }

  @ParameterizedTest
  @ArgumentsSource(BrowserArgumentProvider.class)
  public void checkRegistration(Browser browser) {
    LoginPage loginPage = openApp(browser);
    assertTrue(loginPage.pageLoadSuccessfully());

    loginPage.registrationLinkClick();
    RegistrationPage registrationPage = initElements(driver, RegistrationPage.class);
    assertTrue(registrationPage.pageLoadSuccessfully());

    String logPas = generateName(PART_FOR_NAME);
    registrationPage.editUsername(logPas);
    registrationPage.editEmail("qa_test@micord.ru");
    registrationPage.editPhone("+79999999999");
    registrationPage.editPassword(logPas);
    registrationPage.registerButtonClick();
    registrationPage.waitForPageToLoad();
    assertEquals("Пользователь с данным почтовым адресом уже существует",
        registrationPage.getRegistrationErrorText());

    registrationPage.editEmail(REG_EMAIL);
    registrationPage.registerButtonClick();
    assertTrue(registrationPage.pageLoadSuccessfully());

    String id = EXECUTION_MANAGER.getUserAccountIdByLogin(logPas);
    String token = EXECUTION_MANAGER.getTokenByUserAccountId(id);
    String link = applicationUrl + "#confirm?link=" + token;
    driver.get(link);

    registrationPage.loginLinkClick();
    assertTrue(loginPage.pageLoadSuccessfully());

    loginPage.typeLoginPasswordAndEnter(logPas, logPas);
    InboxPage inboxPage = initElements(driver, InboxPage.class);
    assertTrue(inboxPage.pageLoadSuccessfully());
  }

  @ParameterizedTest
  @ArgumentsSource(BrowserArgumentProvider.class)
  public void checkPasswordRecovery(Browser browser) {
    LoginPage loginPage = openApp(browser);
    assertTrue(loginPage.pageLoadSuccessfully());

    String logPas = generateName(PART_FOR_NAME);
    EXECUTION_MANAGER.insertUser(logPas, RESET_EMAIL, logPas);
    //здесь создаем пользователя с незакодированным паролем, тк нам не нужно будет по нему логиниться

    loginPage.resetPasswordLinkClick();
    ResetPasswordPage resetPasswordPage = initElements(driver, ResetPasswordPage.class);
    assertTrue(resetPasswordPage.pageLoadSuccessfully());

    resetPasswordPage.editEmail(RESET_EMAIL);
    resetPasswordPage.resetButtonClick();
    assertTrue(resetPasswordPage.pageLoadSuccessfully());

    String id = EXECUTION_MANAGER.getUserAccountIdByLogin(logPas);
    String token = EXECUTION_MANAGER.getTokenByUserAccountId(id);
    String link = applicationUrl + "#new-password?token=" + token;
    driver.get(link);

    String newPass = generateName("NewPass");
    resetPasswordPage.editPassword(newPass);
    resetPasswordPage.editConfirmPassword(newPass);
    resetPasswordPage.changeButtonClick();
    assertTrue(resetPasswordPage.pageLoadSuccessfully());

    resetPasswordPage.loginLinkClick();
    loginPage.typeLoginPasswordAndEnter(RESET_EMAIL, newPass);
    InboxPage inboxPage = initElements(driver, InboxPage.class);
    assertTrue(inboxPage.pageLoadSuccessfully());
  }
}