package ru.yandex.autotests.direct.web.pages.banners;

import java.util.List;

import org.hamcrest.Matcher;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.FindBy;

import ru.yandex.autotests.direct.web.data.BannerPreviewType;
import ru.yandex.autotests.direct.web.data.banners.BannersGroupErrorResource;
import ru.yandex.autotests.direct.web.data.banners.ImageLoadType;
import ru.yandex.autotests.direct.web.data.banners.MobileGroupChangesBlockTabs;
import ru.yandex.autotests.direct.web.data.banners.MobileGroupChangesInfo;
import ru.yandex.autotests.direct.web.objects.adjustment.rates.HierarchicalMultipliersWeb;
import ru.yandex.autotests.direct.web.objects.banners.BannerInfoWeb;
import ru.yandex.autotests.direct.web.objects.banners.MobileAppBannerInfoWeb;
import ru.yandex.autotests.direct.web.objects.banners.OptimizedPhraseInfoWeb;
import ru.yandex.autotests.direct.web.objects.retargeting.RetargetingConditionWeb;
import ru.yandex.autotests.direct.web.pages.banners.blocks.edit.bem.EditMobileGroupWithBannerBlockBEM;
import ru.yandex.autotests.direct.web.pages.banners.blocks.edit.bem.MobileGroupChangesBlockBEM;
import ru.yandex.autotests.direct.web.pages.retargeting.blocks.bem.RetargetingPopupBlockBEM;
import ru.yandex.autotests.direct.web.util.DirectWebError;
import ru.yandex.autotests.direct.web.util.JavaScriptActions;
import ru.yandex.qatools.allure.webdriver.annotations.NamedUrl;
import ru.yandex.qatools.allure.webdriver.annotations.NamedUrls;
import ru.yandex.qatools.allure.webdriver.pages.BasePageObject;
import ru.yandex.qatools.htmlelements.annotations.Name;
import ru.yandex.qatools.htmlelements.element.Button;

import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.equalTo;

/**
 * Created by aleran on 11.09.2015.
 */
@NamedUrls({
        @NamedUrl(name = "edit.banner.mobile", url =
                "/registered/main.pl?cmd=editAdGroupsMobileContent&bids={2}&cid={1}" +
                        "&adgroup_ids={3}"),
        @NamedUrl(name = "edit.banner.mobile.for.client",
                url = "/registered/main.pl?cmd=editAdGroupsMobileContent&bids={2}&cid={1}&ulogin={3}&adgroup_ids={4}"),
        @NamedUrl(name = "edit.bannergroup.mobile", url = "/registered/main.pl?cmd=editAdGroupsMobileContent&cid={1}" +
                "&adgroup_ids={2}"),
        @NamedUrl(name = "edit.bannergroup.mobile.for.client",
                url = "/registered/main.pl?cmd=editAdGroupsMobileContent&cid={1}&ulogin={2}&adgroup_ids={3}"),
        @NamedUrl(name = "edit.banner.mobile.texts",
                url = "/registered/main.pl?cmd=editAdGroupsMobileContentLight&bids={2}&cid={1}&ulogin={3}&adgroup_ids={4}"),
        @NamedUrl(name = "new.banner.mobile",
                url = "/registered/main.pl?cid={1}&cmd=addAdGroupsMobileContent&from_newCamp=1&ulogin={2}")
})
public class AddAdGroupsMobileContentPage extends BasePageObject {

    private Long bannerId;
    private Long adGroupId;

    public void forBannerId(Long bannerId) {
        this.bannerId = bannerId;
    }

    public void forAdGroupId(Long adGroupId) {
        this.adGroupId = adGroupId;
    }

    //region Fields

    private MobileGroupChangesBlockBEM mobileGroupChangesBlock;

    private List<RetargetingPopupBlockBEM> retargetingPopupBlockList;

    private List<EditMobileGroupWithBannerBlockBEM> mobileGroupBlockList;

    @Name("Групповые изменения")
    @FindBy(xpath = ".//button[contains(@class, 'b-edit-groups-mass-actions-toggle__popup-toggle-link')]")
    private Button groupChangesButton;

    @Name("Кнопка '< Назад'")
    @FindBy(xpath = ".//button[contains(@class, 'p-multiedit') and contains(@class, 'back-button')]")
    private Button backButton;

    @Name("Кнопка 'Вперед >'")
    @FindBy(xpath = ".//button[contains(@class, 'p-multiedit')" +
            " and (contains(@class, 'submit-button') or contains(@class, 'next-button'))]")
    private Button nextButton;

    @Name("Кнопка 'Добавить объявление'")
    @FindBy(xpath = ".//button[contains(@class, 'b-edit-banner-add2__add-button')]")
    private Button addBannerButton;

    @Name("Сообщение об ошибке")
    @FindBy(css = ".b-edit-groups-error-header__message")
    private WebElement errorMessage;

    @Name("Кнопки раскрытия настроек группы")
    @FindBy(css = "div.b-edit-group__group-properties")
    private List<WebElement> groupsSettings;

    //endregion

    //region Field getters

    private MobileGroupChangesBlockBEM getMobileGroupChangesBlock() {
        mobileGroupChangesBlock.setConfig(config);
        return mobileGroupChangesBlock;
    }

    private List<EditMobileGroupWithBannerBlockBEM> getMobileGroupBlockList() {
        return mobileGroupBlockList;
    }

    private List<RetargetingPopupBlockBEM> getRetargetingPopupBlockList() {
        return retargetingPopupBlockList;
    }

    private EditMobileGroupWithBannerBlockBEM getEditGroupWithBannerBlock(Long adGroupId, Long bannerId) {
        groupsSettings.stream().forEach(WebElement::click);
        EditMobileGroupWithBannerBlockBEM block = getMobileGroupBlockList().stream()
                .filter(t -> t.getAdGroupID().equals(adGroupId))
                .findFirst().get();
        if (block != null) {
            block.forBannerId(bannerId);
            block.setConfig(config);
        } else {
            throw new DirectWebError("Не найден баннер " + bannerId + " в группе " + adGroupId);
        }
        return block;
    }

    //endregion

    //region Actions

    public void clickNext() {
        nextButton.click();
    }

    public void clickBack() {
        backButton.click();
    }

    public void clickGroupChangesButton() {
        groupChangesButton.click();
    }

    public void editPhraseText(OptimizedPhraseInfoWeb phrase, String newPhraseText) {
        EditMobileGroupWithBannerBlockBEM block = getEditGroupWithBannerBlock(adGroupId, bannerId);
        block.editPhraseText(phrase.getPhrase(), newPhraseText);
    }

    public void addRetargetingCondition(RetargetingConditionWeb conditionWeb) {
        EditMobileGroupWithBannerBlockBEM bannerBlock = getEditGroupWithBannerBlock(adGroupId, bannerId);
        bannerBlock.clickAddRetargetingCondition();
        bannerBlock.addNewRetargetingCondition(conditionWeb);
    }

    public void editRetargetingCondition(RetargetingConditionWeb conditionWeb) {
        EditMobileGroupWithBannerBlockBEM bannerBlock = getEditGroupWithBannerBlock(adGroupId, bannerId);
        bannerBlock.clickEditCondition(conditionWeb.getRetargetingConditionName());
        bannerBlock.addNewRetargetingCondition(conditionWeb);
    }

    public void editSavedRetargetingCondition(String conditionName, RetargetingConditionWeb conditionWeb) {
        EditMobileGroupWithBannerBlockBEM bannerBlock = getEditGroupWithBannerBlock(adGroupId, bannerId);
        bannerBlock.clickAddRetargetingCondition();
        bannerBlock.editSavedRetargetingCondition(conditionName, conditionWeb);
    }

    public void deleteRetargetingCondition(String conditionName) {
        EditMobileGroupWithBannerBlockBEM bannerBlock = getEditGroupWithBannerBlock(adGroupId, bannerId);
        bannerBlock.deleteCondition(conditionName);
    }

    public void checkRetargetingConditionParameters(RetargetingConditionWeb conditionWeb) {
        EditMobileGroupWithBannerBlockBEM bannerBlock = getEditGroupWithBannerBlock(adGroupId, bannerId);
        bannerBlock.checkRetargetingConditionParameters(conditionWeb);
    }

    public void checkHierarchicalMultipliersParameters(HierarchicalMultipliersWeb hierarchicalMultipliers) {
        EditMobileGroupWithBannerBlockBEM bannerBlock = getEditGroupWithBannerBlock(adGroupId, bannerId);
        bannerBlock.checkHierarchicalMultipliersParameters(hierarchicalMultipliers);
    }

    public void checkRetargetingConditionsList(Matcher matcher) {
        assertThat("неправильные парамерты списка условий ретаргетинга", getRetargetingPopupBlockList(), matcher);
    }

    public void clickAddNewBanner() {
        addBannerButton.click();
    }

    public void fillBannerParameters(MobileAppBannerInfoWeb bannerInfo) {
        EditMobileGroupWithBannerBlockBEM bannerBlock = getEditGroupWithBannerBlock(adGroupId, bannerId);
        bannerBlock.fillParameters(bannerInfo);
    }

    public void fillRegions(MobileAppBannerInfoWeb bannerInfo) {
        getGroupBlock(bannerInfo.getAdGroupID()).fillRegions(bannerInfo.getGeo());
    }

    public void fillGroupMinusKeywords(MobileAppBannerInfoWeb bannerInfo) {
        EditMobileGroupWithBannerBlockBEM bannerBlock = getEditGroupWithBannerBlock(adGroupId, bannerId);
        if (bannerBlock == null) {
            throw new DirectWebError("Не найден баннер " + bannerId + " в группе " + adGroupId);
        } else {
            bannerBlock.fillMinusKeyWords(bannerInfo.getMinusKeywords());
        }
    }

    public void fillMaxPrice(Long groupId, Float maxPrice) {
        getGroupBlock(groupId).fillMaxPrice(maxPrice);
    }

    public void fillGroupHierarchicalMultipliers(HierarchicalMultipliersWeb multiplier) {
        EditMobileGroupWithBannerBlockBEM bannerBlock = getEditGroupWithBannerBlock(adGroupId, bannerId);
        if (bannerBlock == null) {
            throw new DirectWebError("Не найден баннер " + bannerId + " в группе " + adGroupId);
        } else {
            bannerBlock.fillHierarchicalMultipliers(multiplier);
        }
    }

    public void checkBannerPhraseList(Matcher matcher) {
        EditMobileGroupWithBannerBlockBEM block = getEditGroupWithBannerBlock(adGroupId, bannerId);
        block.checkPhraseList(matcher);
    }

    public void checkBannerParameters(MobileAppBannerInfoWeb expectedBannerInfo) {
        EditMobileGroupWithBannerBlockBEM bannerBlock = getEditGroupWithBannerBlock(adGroupId, bannerId);
        new JavaScriptActions(config).scrollToElement(bannerBlock.getWrappedElement());
        bannerBlock.checkParameters(expectedBannerInfo);
    }

    public void checkMobileAppBannerPreviewParameters(MobileAppBannerInfoWeb expectedBannerInfo) {
        EditMobileGroupWithBannerBlockBEM bannerBlock = getEditGroupWithBannerBlock(adGroupId, bannerId);
        bannerBlock.checkMobileAppBannerPreviewParameters(expectedBannerInfo);
    }

    public void checkBannersCount(int count) {
        assertThat("кол-во баннеров соответствует",
                getEditGroupWithBannerBlock(adGroupId, bannerId).getMobileAppBannerBlockBEMs().size(),
                equalTo(count));
    }

    public void checkErrorTextPresent(BannersGroupErrorResource error) {
        assertThat("ошибка соответствует ожидаемой", errorMessage.getText(), equalTo(error.toString()));
    }

    public void clickRefinePhraseButton(String phraseText) {
        EditMobileGroupWithBannerBlockBEM bannerBlock = getEditGroupWithBannerBlock(adGroupId, bannerId);
        bannerBlock.clickRefineButtonForPhrase(phraseText);
    }

    public void fillGroupEditParameters(MobileGroupChangesInfo groupChangesInfo) {
        groupChangesButton.click();
        getMobileGroupChangesBlock().fill(groupChangesInfo);
    }

    public void openGroupChangesTab(MobileGroupChangesBlockTabs mobileGroupChangesBlockTabs) {
        groupChangesButton.click();
        getMobileGroupChangesBlock().openGroupChangesTab(mobileGroupChangesBlockTabs);
    }

    public void choosePreviewTypeForBanner(Long adGroupId, Long bannerId, BannerPreviewType type) {
        getGroupBlock(adGroupId).chooseBannerPreviewType(bannerId, type);
    }

    public void fillImageAndSave(ImageLoadType type, String img) {
        EditMobileGroupWithBannerBlockBEM bannerBlock = getEditGroupWithBannerBlock(adGroupId, bannerId);
        bannerBlock.fillImageAndSave(type, img);
    }

    public void checkImage(Matcher matcher) {
        EditMobileGroupWithBannerBlockBEM bannerBlock = getEditGroupWithBannerBlock(adGroupId, bannerId);
        bannerBlock.checkImageOnPopup(matcher);
    }

    public WebElement getBannerBlock(Long adGroupId, Long bannerId) {
        return getGroupBlock(adGroupId).getEditBannerBlock(bannerId);
    }

    public WebElement getBannerPreview(Long adGroupId, Long bannerId) {
        return getGroupBlock(adGroupId).getBannerPreview(bannerId);
    }

    public EditMobileGroupWithBannerBlockBEM getGroupBlock(Long adGroupId) {
        groupsSettings.stream().forEach(WebElement::click);
        EditMobileGroupWithBannerBlockBEM block = getMobileGroupBlockList().stream()
                .filter(t -> t.getAdGroupID().equals(adGroupId))
                .findFirst().orElseThrow(() -> new DirectWebError("Не найдена группа " + adGroupId));
        block.setConfig(config);
        return block;
    }

    public WebElement getGroupSettingsBlock(Long adgroupId) {
        return getGroupBlock(adgroupId).getGroupSettingsBlock();
    }

    public void openRetargetingPopupInGroup(Long adgroupId) {
        getGroupBlock(adgroupId).openRetargetingPopup();
    }

    public void openRegionsPopupInGroup(Long adgroupId) {
        getGroupBlock(adgroupId).openRegionsPopup();
    }

    public void openAdjustmentRatesPopupInGroup(Long adgroupId) {
        getGroupBlock(adgroupId).openAdjustmentRatesPopup();
    }

    public void openMinusWordsPopupInGroup(Long adgroupId) {
        getGroupBlock(adgroupId).openMinusWordsPopup();
    }

    public void openImagePopupInBanner(Long adgroupId, Long bannerId) {
        getGroupBlock(adgroupId).getEditBannerBlock(bannerId).openImagePopop();
    }
    //endregion

}
