package ru.yandex.direct.api.v5.entity.keywordbids.validation;

import ru.yandex.direct.api.v5.common.validation.DefectPresentationsHolder;
import ru.yandex.direct.api.v5.entity.bids.validation.BidsDefectPresentations;
import ru.yandex.direct.api.v5.entity.keywordbids.delegate.SetKeywordBidsDelegate;
import ru.yandex.direct.core.entity.bids.container.ExternalFieldsBidsMapping;
import ru.yandex.direct.core.entity.bids.container.SetAutoNetworkByCoverage;
import ru.yandex.direct.core.entity.bids.container.SetAutoSearchByTrafficVolume;
import ru.yandex.direct.core.entity.bids.container.SetBidItem;
import ru.yandex.direct.core.entity.bids.validation.BidsDefects;

import static ru.yandex.direct.api.v5.entity.bids.validation.BidsDefectTypes.bidNetworkWontBeAcceptedContextDependsOnSearch;
import static ru.yandex.direct.api.v5.entity.bids.validation.BidsDefectTypes.dependentFieldMissing;
import static ru.yandex.direct.api.v5.entity.bids.validation.BidsDefectTypes.fieldDoesNotMatchStrategy;
import static ru.yandex.direct.api.v5.entity.bids.validation.BidsDefectTypes.fieldRequiredForContextStrategy;
import static ru.yandex.direct.api.v5.entity.bids.validation.BidsDefectTypes.fieldRequiredForSearchStrategy;
import static ru.yandex.direct.api.v5.entity.bids.validation.BidsDefectTypes.keywordNotFound;
import static ru.yandex.direct.api.v5.entity.bids.validation.BidsDefectTypes.oneOfFieldsRequiredDetailed;
import static ru.yandex.direct.api.v5.entity.bids.validation.BidsDefectTypes.requiredAtLeastOneOfFields;
import static ru.yandex.direct.api.v5.entity.bids.validation.BidsDefectTypes.requiredAtLeastOneOfFieldsForAutobudgetStrategy;
import static ru.yandex.direct.api.v5.entity.bids.validation.BidsDefectTypes.requiredAtLeastOneOfFieldsForManualStrategy;
import static ru.yandex.direct.api.v5.entity.bids.validation.BidsDefectTypes.searchBidWontBeAcceptedSearchIsSwitchedOff;
import static ru.yandex.direct.api.v5.validation.DefectTypes.badStatusCampaignArchived;
import static ru.yandex.direct.api.v5.validation.DefectTypes.possibleOnlyOneField;

/**
 * Переопределён для {@link SetKeywordBidsDelegate}
 */
public class KeywordBidsDefectPresentations {
    static final ExternalFieldsBidsMapping BIDS_IDS_MAPPING =
            ExternalFieldsBidsMapping.builder(BidsDefectPresentations.BIDS_IDS_MAPPING)
                    .map(SetBidItem.PRICE_SEARCH, "SearchBid")
                    .map(SetBidItem.PRICE_CONTEXT, "NetworkBid")
                    .map(SetAutoSearchByTrafficVolume.MAX_BID, "BidCeiling")
                    .map(SetAutoNetworkByCoverage.MAX_BID, "BidCeiling")
                    .build();

    public static final DefectPresentationsHolder HOLDER = DefectPresentationsHolder
            .builderWithFallback(BidsDefectPresentations.HOLDER)
            // BidsDefects.Bids
            .register(BidsDefects.Bids.NOT_FOUND_SHOW_CONDITION_BY_PARAMETERS,
                    t -> keywordNotFound(BIDS_IDS_MAPPING.getBidsField(t.getField()), t.getId()))
            .register(BidsDefects.Bids.BAD_STATUS_CAMPAIGN_ARCHIVED_ON_UPDATE_BIDS,
                    t -> badStatusCampaignArchived())
            // BidsDefects.ModelDefects
            .register(BidsDefects.ModelDefects.REQUIRED_AT_LEAST_ONE_OF_FIELDS,
                    t -> requiredAtLeastOneOfFields(BIDS_IDS_MAPPING.getBidsFields(t)))
            .register(BidsDefects.ModelDefects.REQUIRED_AT_LEAST_ONE_OF_FIELDS_FOR_MANUAL_STRATEGY,
                    t -> requiredAtLeastOneOfFieldsForManualStrategy(BIDS_IDS_MAPPING.getBidsFields(t)))
            .register(BidsDefects.ModelDefects.REQUIRED_AT_LEAST_ONE_OF_FIELDS_FOR_AUTOBUDGET_STRATEGY,
                    t -> requiredAtLeastOneOfFieldsForAutobudgetStrategy(BIDS_IDS_MAPPING.getBidsFields(t)))
            .register(BidsDefects.ModelDefects.ONE_OF_FIELDS_SHOULD_BE_SPECIFIED,
                    t -> oneOfFieldsRequiredDetailed(BIDS_IDS_MAPPING.getBidsFields(t)))
            .register(BidsDefects.ModelDefects.POSSIBLE_ONLY_ONE_FIELD,
                    t -> possibleOnlyOneField(BIDS_IDS_MAPPING.getBidsFields(t)))
            .register(BidsDefects.Bids.FIELD_DOES_NOT_MATCH_STRATEGY,
                    t -> fieldDoesNotMatchStrategy(BIDS_IDS_MAPPING.getBidsField(t.getField())))
            .register(BidsDefects.Bids.FIELD_REQUIRED_FOR_SEARCH_STRATEGY,
                    t -> fieldRequiredForSearchStrategy(BIDS_IDS_MAPPING.getBidsField(t.getField())))
            .register(BidsDefects.Bids.FIELD_REQUIRED_FOR_CONTEXT_STRATEGY,
                    t -> fieldRequiredForContextStrategy(BIDS_IDS_MAPPING.getBidsField(t.getField())))
            .register(BidsDefects.BidsDefects2Fields.DEPENDENT_FIELD_MISSING,
                    t -> dependentFieldMissing(BIDS_IDS_MAPPING.getBidsField(t.getField()),
                            BIDS_IDS_MAPPING.getBidsField(t.getField2())))
            .register(BidsDefects.Ids.BID_FOR_SEARCH_WONT_BE_ACCEPTED_SEARCH_IS_SWITCHED_OFF,
                    t -> searchBidWontBeAcceptedSearchIsSwitchedOff())
            .register(BidsDefects.Ids.BID_FOR_CONTEXT_WONT_BE_ACCEPTED_NOT_DIFFERENT_PLACES,
                    t -> bidNetworkWontBeAcceptedContextDependsOnSearch())
            .build();
}
