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.OrganizationsPage;

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

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

  private static final String CREATE = "Создать";
  private static final String EDIT = "Редактировать";
  private static final String SAVE = "Сохранить";
  private static final String PARENT_ORG_NAME = "Управление ЗАГС г. Казани";
  private static final String SUBSIDIARY_ORG_NAME = "ЗАГС Советского р-на";
  private static final String PART_FOR_CODE = "org_code_";

  public OrganizationsIT() {
    super();
  }

  @AfterAll
  public static void afterAll() {
    EXECUTION_MANAGER.deleteOrganizationByName(PARENT_ORG_NAME);
    EXECUTION_MANAGER.deleteOrganizationByName(SUBSIDIARY_ORG_NAME);
  }

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

    inboxPage.clickOnMenu("Администрирование");
    inboxPage.clickOnSubMenu("Организации");
    OrganizationsPage organizationsPage = initElements(driver, OrganizationsPage.class);
    assertTrue(organizationsPage.pageLoadSuccessfully());
    assertTrue(organizationsPage.isTitleVisible("Администрирование организаций"));

    //check create organization:
    organizationsPage.clickOnButton(CREATE);
    assertTrue(organizationsPage.pageLoadSuccessfully());

    organizationsPage.editOrgName(PARENT_ORG_NAME);
    String parentOrgCode = generateName(PART_FOR_CODE);
    organizationsPage.editOrgCode(parentOrgCode);
    organizationsPage.clickOnButton(SAVE);
    assertTrue(organizationsPage.pageLoadSuccessfully());
    assertTrue(organizationsPage.isOrganizationVisible(PARENT_ORG_NAME, parentOrgCode));

    //check create subsidiary:
    organizationsPage.clickOnButton(CREATE);
    assertTrue(organizationsPage.pageLoadSuccessfully());

    organizationsPage.editOrgName(SUBSIDIARY_ORG_NAME);
    String subsidiaryOrgCode = generateName(PART_FOR_CODE);
    organizationsPage.editOrgCode(subsidiaryOrgCode);
    organizationsPage.selectParentOrg(PARENT_ORG_NAME);
    organizationsPage.clickOnButton(SAVE);
    assertTrue(organizationsPage.pageLoadSuccessfully());

    organizationsPage.clickOnArrowInParentOrganization(PARENT_ORG_NAME, parentOrgCode);
    assertTrue(organizationsPage.isOrganizationVisible(SUBSIDIARY_ORG_NAME, subsidiaryOrgCode));

    //check that a subsidiary cannot be the same as an organization:
    organizationsPage.clickOnOrganization(SUBSIDIARY_ORG_NAME, subsidiaryOrgCode);
    organizationsPage.clickOnButton(EDIT);
    assertTrue(organizationsPage.pageLoadSuccessfully());

    organizationsPage.selectParentOrg(SUBSIDIARY_ORG_NAME);
    organizationsPage.clickOnButton(SAVE);
    organizationsPage.waitForPageToLoad();
    assertFalse(organizationsPage.thereIsNoError());
    assertTrue(organizationsPage.getErrorText().contains("Обнаружен цикл при попытке сменить родителя"));

    //check edit subsidiary:
    organizationsPage.selectParentOrg(PARENT_ORG_NAME);
    String newSubsidiaryOrgCode = generateName(PART_FOR_CODE);
    organizationsPage.editOrgCode(newSubsidiaryOrgCode);
    organizationsPage.clickOnButton(SAVE);
    assertTrue(organizationsPage.pageLoadSuccessfully());

    organizationsPage.clickOnArrowInParentOrganization(PARENT_ORG_NAME, parentOrgCode);
    assertTrue(organizationsPage.isOrganizationVisible(SUBSIDIARY_ORG_NAME, newSubsidiaryOrgCode));
    assertFalse(organizationsPage.isOrganizationVisible(PARENT_ORG_NAME, subsidiaryOrgCode));

    //check edit parent organization:
    organizationsPage.clickOnOrganization(PARENT_ORG_NAME, parentOrgCode);
    organizationsPage.clickOnButton(EDIT);
    assertTrue(organizationsPage.pageLoadSuccessfully());

    String newParentOrgCode = generateName(PART_FOR_CODE);
    organizationsPage.editOrgCode(newParentOrgCode);
    organizationsPage.clickOnButton(SAVE);
    assertTrue(organizationsPage.pageLoadSuccessfully());
    assertTrue(organizationsPage.isOrganizationVisible(PARENT_ORG_NAME, newParentOrgCode));
    assertFalse(organizationsPage.isOrganizationVisible(PARENT_ORG_NAME, parentOrgCode));

    organizationsPage.clickOnArrowInParentOrganization(PARENT_ORG_NAME, newParentOrgCode);
    assertTrue(organizationsPage.isOrganizationVisible(SUBSIDIARY_ORG_NAME, newSubsidiaryOrgCode));

    //check delete parent organization:
    organizationsPage.clickOnOrganization(PARENT_ORG_NAME, newParentOrgCode);
    organizationsPage.clickOnButton("Удалить");
    assertTrue(organizationsPage.isDialogOpened("Подтверждение действия"));

    organizationsPage.clickOnButton("Да");
    assertTrue(organizationsPage.pageLoadSuccessfully());
    assertFalse(organizationsPage.isOrganizationVisible(PARENT_ORG_NAME, newParentOrgCode));
    assertFalse(organizationsPage.isOrganizationVisible(SUBSIDIARY_ORG_NAME, newSubsidiaryOrgCode));
  }
}
