package tests;

import com.google.common.collect.Comparators;
import core.BaseTest;
import core.Browser;
import core.BrowserArgumentProvider;
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.ArgumentsSource;
import pages.InboxPage;
import pages.RolesPage;

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 RolesIT extends BaseTest {

  private static final String ADMINISTRATION = "Администрирование";
  private static final String ROLES = "Роли";
  private static final String SAVE = "Сохранить";
  private static final String PART_FOR_NAME = "rolesTest";

  @AfterAll
  public static void afterAll() {
    EXECUTION_MANAGER.deleteGroupByName(PART_FOR_NAME);
    EXECUTION_MANAGER.deleteRoleByName(PART_FOR_NAME);
  }

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

    inboxPage.clickOnMenu(ADMINISTRATION);
    inboxPage.clickOnSubMenu(ROLES);
    RolesPage rolesPage = initElements(driver, RolesPage.class);
    assertTrue(rolesPage.pageLoadSuccessfully());
    assertTrue(rolesPage.isTitleVisible("Администрирование ролей"));

    //check create and search role:
    rolesPage.clickOnButton("Создать");
    assertTrue(rolesPage.pageLoadSuccessfully());

    String roleName = generateName(PART_FOR_NAME);
    rolesPage.editRoleName(roleName);
    rolesPage.clickOnButton(SAVE);
    assertTrue(rolesPage.pageLoadSuccessfully());

    rolesPage.editSearchField(roleName);
    rolesPage.waitGridProgressBarNotVisible();
    assertTrue(rolesPage.isRoleVisible(roleName));
    assertEquals(1, rolesPage.getNumberOfRolesRows());

    //check edit role:
    rolesPage.clickOnRole(roleName);
    rolesPage.clickOnButton("Редактировать");
    assertTrue(rolesPage.pageLoadSuccessfully());

    String newRoleName = generateName(PART_FOR_NAME);
    rolesPage.editRoleName(newRoleName);
    rolesPage.clickOnButton(SAVE);
    assertTrue(rolesPage.pageLoadSuccessfully());

    rolesPage.editSearchField(roleName);
    rolesPage.waitGridProgressBarNotVisible();
    assertEquals(0, rolesPage.getNumberOfRolesRows());

    rolesPage.editSearchField(newRoleName);
    rolesPage.waitGridProgressBarNotVisible();
    assertTrue(rolesPage.isRoleVisible(newRoleName));
    assertEquals(1, rolesPage.getNumberOfRolesRows());

    //check delete role:
    rolesPage.clickOnRole(newRoleName);
    rolesPage.clickOnButton("Удалить");
    assertTrue(rolesPage.isDialogOpened("Подтверждение действия"));

    rolesPage.clickOnButton("Да");
    assertTrue(rolesPage.pageLoadSuccessfully());
    assertEquals(0, rolesPage.getNumberOfRolesRows());
  }

  @ParameterizedTest
  @ArgumentsSource(BrowserArgumentProvider.class)
  public void checkLinkedGroups(Browser browser) {
    String generatedName = generateName(PART_FOR_NAME);
    EXECUTION_MANAGER.insertGroupAndLinkedRole(generatedName);

    InboxPage inboxPage = loginInAppByAdmin(browser);
    assertTrue(inboxPage.pageLoadSuccessfully());

    inboxPage.clickOnMenu(ADMINISTRATION);
    inboxPage.clickOnSubMenu(ROLES);
    RolesPage rolesPage = initElements(driver, RolesPage.class);
    assertTrue(rolesPage.pageLoadSuccessfully());

    rolesPage.editSearchField(generatedName);
    rolesPage.waitGridProgressBarNotVisible();
    rolesPage.clickOnRole(generatedName);
    rolesPage.waitGridProgressBarNotVisible();
    assertTrue(rolesPage.isGroupVisible(generatedName));
    assertEquals(1, rolesPage.getNumberOfGroupRows());
  }

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

    inboxPage.clickOnMenu(ADMINISTRATION);
    inboxPage.clickOnSubMenu(ROLES);
    RolesPage rolesPage = initElements(driver, RolesPage.class);
    assertTrue(rolesPage.pageLoadSuccessfully());
    assertTrue(Comparators.isInOrder(rolesPage.getListOfRolesNames(), String.CASE_INSENSITIVE_ORDER));

    rolesPage.clickOnRoleNameColumnHeader();
    //из-за бага(?) Selenium после сортировки список возвращается неверный (изначальный)
    //поэтому используем обновление страницы с включенным в гриде св-вом Save Column State:
    rolesPage.refreshPage();
    assertTrue(rolesPage.pageLoadSuccessfully());
    assertTrue(Comparators.isInOrder(rolesPage.getListOfRolesNames(), String.CASE_INSENSITIVE_ORDER.reversed()));

    //todo dev WEBBPMNEXT-9164
    /*rolesPage.clickOnRoleNameColumnHeader();
    //из-за бага(?) Selenium после сортировки список возвращается неверный (изначальный)
    //поэтому используем обновление страницы с включенным в гриде св-вом Save Column State:
    rolesPage.refreshPage();
    assertTrue(rolesPage.pageLoadSuccessfully());
    assertTrue(Comparators.isInOrder(rolesPage.getListOfRolesNames(), String.CASE_INSENSITIVE_ORDER));*/
  }
}