package pages;

import core.BasePage;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.Keys;
import org.openqa.selenium.support.FindBy;

import java.util.List;

/**
 * @author kote
 */
public class GroupsPage extends BasePage {

  private static final String TEXT_ON_PAGE = "//text//div[contains(.,'%s')]";
  private static final String GROUPS_GRID = "//in-memory-static-column-grid[@object-name='Grid']";
  private static final String ROLES_GRID = "//in-memory-static-column-grid[@object-name='RolesGrid']";
  private static final String ROWS = "//div[@role='row'][not(contains(@class,'ag-header'))]";
  private static final String ROW_BY_TEXT = "//div[@role='row'][.//span[contains(.,'%s')]]";
  private static final String GROUPS_ROWS = GROUPS_GRID + ROWS;
  private static final String ROLES_ROWS = ROLES_GRID + ROWS;
  private static final String GROUPS_ROW_BY_TEXT = GROUPS_GRID + ROW_BY_TEXT;
  private static final String ROLES_ROW_BY_TEXT = ROLES_GRID + ROW_BY_TEXT;

  private static final String TABLE_TO_ADD = "//in-memory-static-column-grid[@object-name='AvailableRecordsGrid']";
  private static final String TABLE_ADDED = "//static-column-link-field[@object-name='LinkFieldDialog']";
  private static final String ROLES = "//div[@col-id='role$name'][not(contains(@class,'ag-header'))]";
  private static final String ROLE_CELL_BY_NAME = "//div[@col-id='role$name'][.//div[contains(.,'%s')]]";
  private static final String ROLES_DATES_HEADER = TABLE_TO_ADD + "//div[@col-id='role$updated'][contains(@class,'ag-header')]";
  private static final String MOVE_BUTTON_BY_NAME = "//vbox[@class='many-to-many-move-buttons']//button[text()='%s']";
  private static final String CHECHBOX_BY_ROW_INDEX = "//div[@class='ag-pinned-left-cols-container']//div[@row-index='%s']";

  @FindBy(xpath = "//div[label[span[contains(.,'Наименование')]]]//input")
  private WebElement groupName;
  @FindBy(xpath = "//combo-box//div[contains(@class,'selectize-input')]")
  private WebElement accessLevel;
  @FindBy(xpath = "//*[@object-name='search']//input")
  private WebElement searchField;

  public GroupsPage(WebDriver browser) {
    super(browser, "/#/user-management/groups");
  }

  public boolean isTitleVisible(String title) {
    return isPresent(getBy(TEXT_ON_PAGE, title));
  }

  public boolean isGroupVisible(String name) {
    return isPresent(getBy(GROUPS_ROW_BY_TEXT, name));
  }

  public boolean isRoleVisible(String name) {
    return isPresent(getBy(ROLES_ROW_BY_TEXT, name));
  }

  public void clickOnGroup(String name) {
    waitForElementToBeClickable(getBy(GROUPS_ROW_BY_TEXT, name)).click();
  }

  public void clickOnRoleToAdd(String roleName) {
    waitForElementToBeClickable(getBy(TABLE_TO_ADD + ROLE_CELL_BY_NAME, roleName)).click();
  }

  public void clickOnRoleAdded(String roleName) {
    waitForElementToBeClickable(getBy(TABLE_ADDED + ROLE_CELL_BY_NAME, roleName)).click();
  }

  public void clickOnCheckboxNearRoleToAdd(int rowIndex) {
    waitForElementToBeClickable(getBy(TABLE_TO_ADD + CHECHBOX_BY_ROW_INDEX, rowIndex)).click();
  }

  public void clickOnRoleDateColumnHeader() {
    waitForElementToBeClickable(getBy(ROLES_DATES_HEADER)).click();
  }

  public void clickOnMoveButton(String name) {
    waitForElementToBeClickable(getBy(MOVE_BUTTON_BY_NAME, name)).click();
  }

  public void editGroupName(String value) {
    editField(groupName, value);
  }

  public void editSearchField(String value) {
    editField(searchField, value);
    searchField.sendKeys(Keys.ENTER);
  }

  public int getNumberOfGroupRows() {
    return findElements(getBy(GROUPS_ROWS)).size();
  }

  public int getNumberOfRolesRows() {
    return findElements(getBy(ROLES_ROWS)).size();
  }

  public List<String> getListOfRolesNamesToAdd() {
    return getTexts(getBy(TABLE_TO_ADD + ROLES));
  }

  public void selectAccessLevel(String value) {
    clickAndSelectValue(accessLevel, value);
  }

  public boolean hasRolesInTable(String tableName, List<String> expectedValues) {
    String table = tableName.equals("ADDED") ? TABLE_ADDED : TABLE_TO_ADD;
    return getElementsTexts(driver.findElements(By.xpath(table + ROLES)))
        .containsAll(expectedValues);
  }
}
