package ru.yandex.autotests.directapi.darkside.steps;

import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

import ru.yandex.autotests.direct.db.models.jooq.ppc.enums.BannersPhoneflag;
import ru.yandex.autotests.direct.db.models.jooq.ppc.enums.CampaignsPlatform;
import ru.yandex.autotests.direct.db.models.jooq.ppc.tables.records.AdditionsItemCalloutsRecord;
import ru.yandex.autotests.direct.db.models.jooq.ppc.tables.records.BannersAdditionsRecord;
import ru.yandex.autotests.direct.db.models.jooq.ppc.tables.records.BannersRecord;
import ru.yandex.autotests.direct.db.models.jooq.ppc.tables.records.CampOptionsRecord;
import ru.yandex.autotests.direct.db.models.jooq.ppc.tables.records.CampaignsRecord;
import ru.yandex.autotests.direct.db.models.jooq.ppc.tables.records.PhrasesRecord;
import ru.yandex.autotests.direct.db.models.jooq.ppc.tables.records.UsersRecord;
import ru.yandex.autotests.direct.db.models.jooq.ppc.tables.records.VcardsRecord;
import ru.yandex.autotests.direct.db.steps.DirectJooqDbSteps;
import ru.yandex.autotests.directapi.darkside.datacontainers.jsonrpc.bannersearch.BannerSearchRequestData;
import ru.yandex.autotests.directapi.darkside.datacontainers.jsonrpc.bannersearch.BannerSearchResponseData;
import ru.yandex.autotests.directapi.darkside.datacontainers.jsonrpc.bannersearch.BannerSearchService;
import ru.yandex.autotests.directapi.darkside.steps.base.BaseJsonRpcSteps;
import ru.yandex.qatools.allure.annotations.Step;

public class BannerSearchSteps extends BaseJsonRpcSteps<BannerSearchService> {
    private static final SimpleDateFormat startTimeFormat = new SimpleDateFormat("yyyyMMddHHmmss");
    private static final SimpleDateFormat dateBudgetStopTimeFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

    @Step("[BannerSearch]")
    public BannerSearchResponseData advancedSearch(BannerSearchRequestData request) {
        Object s = service().advanced_search(request);
        return (BannerSearchResponseData) s;
    }

    @Override
    protected BannerSearchService initService() {
        return client().getServiceWithOneComplexParam(getServiceName(), getClazz());
    }

    @Override
    protected String getServiceName() {
        return BannerSearchService.SERVICE_NAME;
    }

    @Override
    protected Class<BannerSearchService> getClazz() {
        return BannerSearchService.class;
    }

    public static BannerSearchResponseData getExpectedBannerSearchResponse(List<Long> bids, DirectJooqDbSteps dbSteps) {
        return new BannerSearchResponseData().withBanners(
                bids.stream().map(bid -> {
                            BannersRecord banner = dbSteps.bannersSteps().getBanner(bid);
                            PhrasesRecord adGroup = dbSteps.adGroupsSteps().getPhrases(banner.getPid());
                            CampaignsRecord campaign = dbSteps.campaignsSteps().getCampaignById(adGroup.getCid());
                            CampOptionsRecord campOptions = dbSteps.campaignsSteps().getCampOptionsById(adGroup.getCid());
                            UsersRecord user = dbSteps.usersSteps().getUsers(campaign.getUid());

                            BannerSearchResponseData.Banner responseBanner = new BannerSearchResponseData.Banner()
                                    .withLogin(user.getLogin())
                                    .withUserPhone(user.getPhone())
                                    .withDayBudgetDailyChangeCount(String.valueOf(campOptions.getDayBudgetDailyChangeCount()))
                                    .withAdType(banner.getBannerType().getLiteral())
                                    .withMediaType(campaign.getType().getLiteral())
                                    .withFio(user.getFio())
                                    .withAdgroupType(adGroup.getAdgroupType().getLiteral())
                                    .withDontShowYacontext(campaign.getPlatform() == null
                                            || campaign.getPlatform() == CampaignsPlatform.context
                                            || campaign.getPlatform() == CampaignsPlatform.both ? null : "Yes")
                                    .withPhoneFlag(banner.getPhoneflag() == null ||
                                            banner.getPhoneflag() == BannersPhoneflag.New ?
                                            null :
                                            banner.getPhoneflag().getLiteral())
                                    .withHref(banner.getHref())
                                    .withClientID(user.getClientid())
                                    .withBannerID(banner.getBannerid() == 0 ? null : banner.getBannerid())
                                    .withPhraseID(adGroup.getContextid() == 0 ? null : adGroup.getContextid())
                                    .withPid(adGroup.getPid())
                                    .withSumSpent(campaign.getSumSpent())
                                    .withDayBudgetStopTime(campOptions.getDayBudgetStopTime() == null ?
                                            "0000-00-00 00:00:00" :
                                            dateBudgetStopTimeFormat.format(campOptions.getDayBudgetStopTime()))
                                    .withStatusShow(banner.getStatusshow().getLiteral())
                                    .withSum(campaign.getSum())
                                    .withTimeTarget(campaign.getTimetarget())
                                    .withGeo(adGroup.getGeo() == null ? "0" : adGroup.getGeo())
                                    .withUid(campaign.getUid())
                                    .withStartTime(startTimeFormat.format(campaign.getStartTime()))
                                    .withTimeZoneId(campaign.getTimezoneId())
                                    .withWalletCid(campaign.getWalletCid())
                                    .withStatusBySynced(banner.getStatusbssynced().getLiteral())
                                    .withDayBudget(campaign.getDayBudget())
                                    .withCid(campaign.getCid())
                                    .withTitle(banner.getTitle())
                                    .withCurrency(campaign.getCurrency().getLiteral())
                                    .withBody(banner.getBody())
                                    .withDomain(banner.getDomain())
                                    .withDayBudgetShowMode(campaign.getDayBudgetShowMode().getLiteral())
                                    .withCampName(campaign.getName())
                                    .withManagerUid(campaign.getManageruid())
                                    .withBid(bid)
                                    .withSiteLinksSetId(banner.getSitelinksSetId())
                                    .withStatusModerate(campaign.getStatusmoderate().getLiteral())
                                    .withStatusActive(banner.getStatusactive().getLiteral())
                                    .withArchived(banner.getStatusarch().getLiteral())
                                    .withYaContextCategories(banner.getYacontextcategories())
                                    .withType(campaign.getType().getLiteral())
                                    .withAgencyUid(campaign.getAgencyuid())
                                    .withFinishTime(campOptions.getStoptime() == null ?
                                            "0000-00-00" :
                                            dateBudgetStopTimeFormat.format(campOptions.getStoptime()))
                                    .withOrderId(campaign.getOrderid())
                                    .withFlags(banner.getFlags())
                                    .withStatusPostModerate(campOptions.getStatuspostmoderate().getLiteral())
                                    .withCurrencyConverted(campaign.getCurrencyconverted().getLiteral());
//Данные кошелька
                            if (campaign.getWalletCid() != 0) {
                                CampaignsRecord wallet = dbSteps.campaignsSteps()
                                        .getCampaignById(campaign.getWalletCid());
                                responseBanner
                                        .withWalletSum(wallet.getSum())
                                        .withWalletSumSpent(wallet.getSumSpent());
                            } else {
                                responseBanner
                                        .withWalletSum(BigDecimal.ZERO.setScale(6))
                                        .withWalletSumSpent(BigDecimal.ZERO.setScale(6));
                            }
//Данные менеджера
                            if (campaign.getManageruid() != null) {
                                UsersRecord manager = dbSteps.usersSteps().getUsers(campaign.getManageruid());
                                responseBanner.withMemail(manager.getEmail())
                                        .withMfio(manager.getFio())
                                        .withMlogin(manager.getLogin());
                            }
//Данные агентства
                            if (campaign.getAgencyuid() != null) {
                                UsersRecord agency = dbSteps.usersSteps().getUsers(campaign.getAgencyuid());
                                responseBanner.withAlogin(agency.getLogin())
                                        .withAemail(agency.getEmail())
                                        .withAfio(agency.getFio());

                            }
//Визитка
                            VcardsRecord vcard = dbSteps.vCardSteps().getVCardsByCid(campaign.getCid());
                            if (vcard != null) {
                                responseBanner
                                        .withVcardId(vcard.getVcardId())
                                        .withMetro(String.valueOf(vcard.getMetro()))
                                        .withApart(vcard.getApart())
                                        .withWorkTime(vcard.getWorktime())
                                        .withCountry(vcard.getCountry())
                                        .withHouse(vcard.getHouse())
                                        .withBuild(vcard.getBuild())
                                        .withExtraMessage(vcard.getExtraMessage())
                                        .withContactEmail(vcard.getContactEmail())
                                        .withImLogin(vcard.getImLogin())
                                        .withOrgDetailsId(vcard.getOrgDetailsId())
                                        .withStreet(vcard.getStreet())
                                        .withImClient(vcard.getImClient())
                                        .withContactPerson(vcard.getContactperson())
                                        .withCity(vcard.getCity())
                                        .withPhone(vcard.getPhone());
                            }
//Сайтлинки
                            if (banner.getSitelinksSetId() != null && banner.getSitelinksSetId() != 0) {
                                List<BannerSearchResponseData.Banner.SiteLink> sitelinks = new ArrayList();
                                dbSteps.sitelinksSteps().getSitelinksBySetId(banner.getSitelinksSetId())
                                        .forEach(sitelinksLinksRecord -> {
                                            sitelinks.add(new BannerSearchResponseData.Banner.SiteLink()
                                                    .withDescription(sitelinksLinksRecord.getDescription())
                                                    .withHash(String.valueOf(sitelinksLinksRecord.getHash()))
                                                    .withSlId(sitelinksLinksRecord.getSlId())
                                                    .withTitle(sitelinksLinksRecord.getTitle())
                                                    .withHref(sitelinksLinksRecord.getHref()));
                                        });
                                responseBanner.withSitelinks(sitelinks);
                            }
//Коллауты
                            List<BannersAdditionsRecord> additionsRecords
                                    = dbSteps.bannerAdditionsSteps().getBannersAdditionsRecordsByBids(new Long[]{bid});
                            if (additionsRecords != null) {
                                List<BannerSearchResponseData.Banner.Callout> callouts = new ArrayList();
                                additionsRecords.forEach(bannersAdditionsRecord -> {
                                    AdditionsItemCalloutsRecord calloutsRecord = dbSteps.bannerAdditionsSteps()
                                            .getCallout(bannersAdditionsRecord.getAdditionsItemId());
                                    callouts.add(new BannerSearchResponseData.Banner.Callout()
                                            .withAdditionsItemId(calloutsRecord.getAdditionsItemId())
                                            .withCalloutText(calloutsRecord.getCalloutText())
                                            .withStatusModerate(calloutsRecord.getStatusmoderate().getLiteral())
                                    );
                                });
                                responseBanner.withCallouts(callouts);
                            }
                            return responseBanner;
                        }
                ).collect(Collectors.toList()));
    }
}
