package ru.yandex.autotests.direct.web.steps.campaigns;

import org.hamcrest.Matcher;
import org.hamcrest.core.IsNot;
import org.openqa.selenium.WebElement;
import ru.yandex.autotests.direct.utils.beans.IBeanWrapper;
import ru.yandex.autotests.direct.utils.textresource.TextResourceFormatter;
import ru.yandex.autotests.direct.web.data.contactinfo.Regions;
import ru.yandex.autotests.direct.web.objects.banners.commons.ContactInfoWeb;
import ru.yandex.autotests.direct.web.objects.campaigns.CampaignInfoWeb;
import ru.yandex.autotests.direct.web.pages.campaigns.EditCampPage;
import ru.yandex.autotests.direct.web.pages.campaigns.ShowContactInfoPage;
import ru.yandex.autotests.direct.web.pages.regionselectpopup.GeoCorrectionWeb;
import ru.yandex.autotests.direct.web.pages.showcampbem.blocks.strategy.StrategiesEnum;
import ru.yandex.autotests.direct.web.pages.showcampbem.blocks.strategy.StrategyWeb;
import ru.yandex.autotests.direct.web.steps.campaigns.strategy.StrategySteps;
import ru.yandex.autotests.irt.testutils.allure.AllureUtils;
import ru.yandex.qatools.allure.annotations.Step;
import ru.yandex.qatools.allure.webdriver.steps.BaseSteps;
import ru.yandex.qatools.htmlelements.matchers.WebElementMatchers;

import java.util.List;
import java.util.concurrent.TimeUnit;

import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.containsString;
import static org.hamcrest.Matchers.not;
import static ru.yandex.autotests.direct.utils.beans.BeanWrapper.wrap;
import static ru.yandex.autotests.direct.utils.matchers.TextResourceMatcher.textResourceMatcher;
import static ru.yandex.qatools.htmlelements.matchers.MatcherDecorators.should;
import static ru.yandex.qatools.htmlelements.matchers.common.HasTextMatcher.hasText;
import static ru.yandex.qatools.htmlelements.matchers.decorators.TimeoutWaiter.timeoutHasExpired;

public class EditCampPageSteps extends BaseSteps {

    private EditCampPage onEditCampPage() {
        return EditCampPage.getInstance(EditCampPage.class, config);
    }

    public ShowContactInfoPage onShowContactInfoPage() {
        return ShowContactInfoPage.getInstance(ShowContactInfoPage.class, config);
    }

    public StrategySteps onStrategyBlock() {
        StrategySteps steps = getInstance(StrategySteps.class, config, this);
        steps.forPage(onEditCampPage());
        return steps;
    }

    @Step("Заполняем параметры кампании")
    public void fillCampaignFieldsWith(IBeanWrapper<CampaignInfoWeb> campInfo) {
        AllureUtils.addJsonAttachment("Параметры кампании", campInfo.toString());
        onEditCampPage().fillParameters(campInfo.getBean());
    }

    @Step("Заполняем минус слова кампании")
    public void fillCampaignMinusKeywords(IBeanWrapper<CampaignInfoWeb> campInfo) {
        onEditCampPage().fillMinusWords(campInfo.getBean().getMinusKeywords());
    }

    @Step("Проверяем, что нельзя сохранить минус слова с длиной, больше допустимой")
    public void cannotSaveTooLongMinusWords(String[] minusWords) {
        onEditCampPage().fillMinusKeyWordsAndCheckSaveButton(minusWords, IsNot.not(WebElementMatchers.isEnabled()));
    }

    @Step("Заполняем контактную информацию")
    public void fillContactInfoWith(IBeanWrapper<ContactInfoWeb> contactInfo) {
        AllureUtils.addJsonAttachment("Контактная информация", contactInfo.toString());
        onEditCampPage().fillContactInfo(contactInfo.getBean());
    }

    @Step("Проверяем параметры кампании")
    public void shouldSeeCampaignParameters(IBeanWrapper<CampaignInfoWeb> expectedCampInfo) {
        AllureUtils.addJsonAttachment("Параметры кампании", expectedCampInfo.toString());
        onEditCampPage().checkCampaignParameters(expectedCampInfo.getBean());
    }

    @Step("Проверяем контактную информацию")
    public void shouldSeeContactInfoParameters(IBeanWrapper<ContactInfoWeb> contactInfo) {
        AllureUtils.addJsonAttachment("Контактная информация", contactInfo.toString());
        onEditCampPage().checkContactInfo(contactInfo.getBean());
    }

    @Step("Проверяем присутствие временных периодов, удовлетворяющих условию {0}")
    public void shouldSeeTimePeriodsInContactInfoPreview(Matcher matcher) {
        onShowContactInfoPage().checkTimePeriods(matcher);
    }

    @Step("Добавляем неверные домены")
    public void attemptToSetInvalidDisabledDomains(List<String> disabledDomains) {
        AllureUtils.addJsonAttachment("Домены", wrap(disabledDomains).toString());
        onEditCampPage().fillInvalidDisabledDomain(disabledDomains);
    }

    @Step("Добавляем неверные ip")
    public void attemptToSetInvalidDisabledIps(List<String> disabledIps) {
        AllureUtils.addJsonAttachment("IP", wrap(disabledIps).toString());
        onEditCampPage().fillInvalidDisabledIps(disabledIps);
    }

    @Step("Проверяем сообщение валидации в попАПе добавления счетчика метрики")
    public void shouldSeeMetrikaCountersValidationMessage(Matcher<WebElement> checkMatcher) {
        onEditCampPage().checkMetrikaValidationMessage(checkMatcher);
    }

    @Step("Сохраняем кампанию")
    public void saveCampaignAndFillRegionIfNotPresent() {
        if (onEditCampPage().getRegionIDs() == null && onEditCampPage().getChangedPlusRegionIds().isEmpty()) {
            onEditCampPage().fillRegions(Regions.EUROPE.getRegionID(), false);
        }
        onEditCampPage().clickNext();
    }

    @Step("Сохраняем кампанию и заполняем регион показа, если он не заполнен")
    public void clickSave() {
        onEditCampPage().clickNext();
    }

    @Step("Сохраняем кампанию и проверяем, что текст алерта {0}")
    public void saveCampaignWithAlert(Matcher matcher) {
        onEditCampPage().clickNext();
        onEditCampPage().alert().acceptIfPresent(matcher);
    }

    @Step("Отрываем параметры временного тартегинга")
    public void clickChangeTimeTargetParameters() {
        onEditCampPage().getEditTimeTargetingButton().click();
    }

    @Step("Проверяем, что параметры временного таргетинга удовлетворяют условию {0}")
    public void shouldSeeTimeTargeting(Matcher<String> matcher) {
        assertThat("неверное резюме временного таргетинга",
                onEditCampPage().getTimeTargeting(),
                should(hasText(matcher)).whileWaitingUntil(timeoutHasExpired(TimeUnit.SECONDS.toMillis(5))));
    }

    @Step("Проверяем, что параметры временного таргетинга не содержат {0}")
    public void timeTargetingShouldNotContain(TextResourceFormatter str) {
        shouldSeeTimeTargeting(textResourceMatcher(str, not(containsString(str.toString()))));
    }

    @Step("Проверяем, текст контекстной стратегии {0}")
    public void shouldSeeContextStrategyText(Matcher matcher) {
        assertThat("текст параметров контекстной стратегии не соответствует ожиданиям",
                onEditCampPage().getContextStrategyParams(), matcher);
    }

    @Step("Проверяем, что текст дневного бюджета {0}")
    public void shouldSeeDayBudgetText(Matcher matcher) {
        assertThat("текст дневного бюджета не соответствует ожиданиям",
                onEditCampPage().getCurrentStrategyParams(), matcher);
    }

    @Step("Проверяем, что чекбокс о важности кампании {0}")
    public void shouldSeeFavoriteCampaign(Matcher matcher) {
        assertThat("состояние чекбокса важной кампании не соответствует ожиданиям",
                onEditCampPage().getFavoriteCampaign(),
                matcher);
    }

    @Step("Заполняем параметры стратегии")
    public void fillCampaignStrategy(StrategyWeb strategy) {
        onEditCampPage().fillCampaignStrategyWithSuccess(strategy);
    }

    @Step("Заполняем параметры дефолтной стратегии для динамической кампании")
    public void fillDefaultDynamicCampaignStrategy() {
        StrategyWeb strategy = new StrategyWeb()
                .withAtributionModel(StrategiesEnum.AtributionModel.LAST_YANDEX_DIRECT_CLICK)
                .withStrategy(StrategiesEnum.Strategies.OPTIMIZE_CLICKS)
                .withShowsType(StrategiesEnum.StrategyShowsType.SEARCH)
                .withRestriction(StrategiesEnum.Restriction.WEEK_BUDGET)
                .withWeekBudget("70000");
        onEditCampPage().fillCampaignStrategyWithSuccess(strategy);
    }

    @Step("Заполняем параметры стратегии")
    public void checkCampaignStrategy(StrategyWeb expectedStrategy) {
        onEditCampPage().checkCampaignStrategy(expectedStrategy);
    }

    @Step("Устанавливаем чекбокс о переводе на обслуживание менеджером в {0}")
    public void setServiceByManager(Boolean state) {
        onEditCampPage().setServiceByManagerCheckBox(state);
    }

    @Step("Выставляем регион в попапе без сброса текущих регионов")
    public void fillRegionWithoutClearing(String region) {
        onEditCampPage().fillRegions(region, false);
    }

    @Step("Очищаем регионы показа, пробуем сохранить")
    public void clearRegionsAndSave() {
        onEditCampPage().clearRegionsSaveAndWaitErrorBlock();
    }

    @Step("Проверяем, что режим управления ставками удовлетворяет условию {0}")
    public void shouldSeeBidManagement(Matcher matcher) {
        onEditCampPage().checkBidManagement(matcher);
    }

    @Step("Открываем расширенные настройки")
    public void openExtendedProperties() {
        onEditCampPage().openExtendedProperties();
    }

    @Step("Открываем уведомления")
    public void openEmailNotifications() {
        onEditCampPage().clickOpenEmailNotifications();
    }

    @Step("Открываем СМС-уведомления")
    public void openSmsNotifications() {
        onEditCampPage().clickOpenSmsNotifications();
    }

    @Step("Открываем корректировки ставок")
    public void openAdjustmentRates() {
        onEditCampPage().clickOpenAdjustmentRates();
    }

    @Step("Открываем единый регион")
    public void openRegion() {
        onEditCampPage().clickOpenRegion();
    }

    @Step("Переключаем тумблер корректировок ставок по гео")
    public void setGeoBidsCorrectionsTumbler(Boolean status) {
        onEditCampPage().setTumblerGeoCorrections(status);
    }

    @Step("Открываем единые минус-слова")
    public void openMinusKeywords() {
        onEditCampPage().clickOpenMinusKeywords();
    }

    @Step("Открываем счетчики Метрики")
    public void openMetrikaCounters() {
        onEditCampPage().clickOpenMetrikaCounters();
    }

    @Step("Открываем запрещенные площадки и сети")
    public void openDisabledDomains() {
        onEditCampPage().clickOpenDisabledDomains();
    }

    @Step("Открываем запрещенные IP-адреса")
    public void openDisabledIPs() {
        onEditCampPage().clickOpenDisabledIPs();
    }

    @Step("Открываем настройки таргетинга на устройства")
    public void openDeviceTargeting() {
        onEditCampPage().clickOpenDeviceTargeting();
    }

    @Step("Открываем попап дополнительных релевантных фраз")
    public void openAdditionalRelevantPhrases() {
        onEditCampPage().clickOpenAdditionalRelevantPhrases();
    }

    @Step("Нажимаем кнопку сохранения в попапе регионов")
    public void saveRegion() {
        onEditCampPage().clickSaveInRegionPopup();
    }

    @Step("Включаем корректировку по гео, заполняем ее и сохраняем")
    public void switchOnGeoCorrectionFillParamAndSave(List<GeoCorrectionWeb> geoCorrectionInfo) {
        onEditCampPage().fillGeoCorrection(geoCorrectionInfo);
    }

    @Step("Открываем попап ключевых целей")
    public void openKeyGoals() {
        onEditCampPage().clickOpenKeyGoalsPopup();
    }

    @Step("Открываем попап ключевых целей и открываем список целей внутри него")
    public void openKeyGoalsAndOpenGoalsList() {
        onEditCampPage().openKeyGoalsPopupAndOpenGoals();
    }

}
