package ru.yandex.direct.api.v5.entity.smartadtargets.converter;

import java.util.Map;
import java.util.Objects;
import java.util.function.Predicate;

import com.yandex.direct.api.v5.general.StringConditionOperatorEnum;
import com.yandex.direct.api.v5.smartadtargets.AudienceEnum;
import com.yandex.direct.api.v5.smartadtargets.ConditionsItem;
import com.yandex.direct.api.v5.smartadtargets.ObjectFactory;
import one.util.streamex.EntryStream;

import ru.yandex.direct.core.entity.performancefilter.model.Operator;
import ru.yandex.direct.core.entity.performancefilter.model.PerformanceFilterCondition;
import ru.yandex.direct.core.entity.performancefilter.model.TargetFunnel;
import ru.yandex.direct.core.entity.performancefilter.schema.FilterSchema;

public class CommonConverters {
    public static final Predicate<PerformanceFilterCondition> IS_AVAILABLE_CONDITION =
            condition -> Objects.equals(condition.getFieldName(), FilterSchema.AVAILABLE);
    public static final Predicate<PerformanceFilterCondition> IS_NOT_AVAILABLE_CONDITION =
            Predicate.not(IS_AVAILABLE_CONDITION);
    public static final ObjectFactory FACTORY = new ObjectFactory();
    static final Map<AudienceEnum, TargetFunnel> FUNNEL_BY_AUDIENCE = getFunnelByAudience();
    public static final Map<TargetFunnel, AudienceEnum> AUDIENCE_BY_FUNNEL = invert(FUNNEL_BY_AUDIENCE);
    private static final Map<StringConditionOperatorEnum, Operator> CORE_OPERATOR_BY_API_OPERATOR =
            getCoreOperatorByApiOperator();
    public static final Map<Operator, StringConditionOperatorEnum> API_OPERATOR_BY_CORE_OPERATOR =
            invert(CORE_OPERATOR_BY_API_OPERATOR);
    static final long PRICE_OFF = 0L;

    private CommonConverters() {
    }

    private static Map<AudienceEnum, TargetFunnel> getFunnelByAudience() {
        return Map.of(
                AudienceEnum.INTERESTED_IN_SIMILAR_PRODUCTS, TargetFunnel.NEW_AUDITORY,
                AudienceEnum.VISITED_PRODUCT_PAGE, TargetFunnel.PRODUCT_PAGE_VISIT,
                AudienceEnum.ALL_SEGMENTS, TargetFunnel.SAME_PRODUCTS);
    }

    private static <T, U> Map<U, T> invert(Map<T, U> src) {
        return EntryStream.of(src)
                .invert()
                .toMap();
    }

    private static Map<StringConditionOperatorEnum, Operator> getCoreOperatorByApiOperator() {
        return Map.of(
                StringConditionOperatorEnum.GREATER_THAN, Operator.GREATER,
                StringConditionOperatorEnum.LESS_THAN, Operator.LESS,
                StringConditionOperatorEnum.IN_RANGE, Operator.RANGE,
                StringConditionOperatorEnum.EXISTS, Operator.EXISTS,
                StringConditionOperatorEnum.EQUALS_ANY, Operator.EQUALS,
                StringConditionOperatorEnum.CONTAINS_ANY, Operator.CONTAINS,
                StringConditionOperatorEnum.NOT_CONTAINS_ALL, Operator.NOT_CONTAINS);
    }

    static PerformanceFilterCondition convertCondition(ConditionsItem conditionsItem) {
        Operator operator = CORE_OPERATOR_BY_API_OPERATOR.get(conditionsItem.getOperator());
        String stringValue = "[\"" + String.join("\",\"", conditionsItem.getArguments()) + "\"]";
        return new PerformanceFilterCondition(conditionsItem.getOperand(), operator, stringValue);
    }

}
