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

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.function.Predicate;

import javax.annotation.Nullable;
import javax.annotation.ParametersAreNonnullByDefault;

import com.google.common.collect.ImmutableMap;
import com.yandex.direct.api.v5.ads.MobileAppAdFeatureGetItem;
import com.yandex.direct.api.v5.ads.MobileAppFeatureEnum;
import com.yandex.direct.api.v5.general.YesNoEnum;
import com.yandex.direct.api.v5.general.YesNoUnknownEnum;
import one.util.streamex.StreamEx;

import ru.yandex.direct.core.entity.banner.model.NewReflectedAttribute;
import ru.yandex.direct.core.entity.mobilecontent.model.MobileContent;

import static java.util.Comparator.comparing;

@ParametersAreNonnullByDefault
class MobileAppFeatureConverter {
    private static final Map<MobileAppFeatureEnum, NewReflectedAttribute> MOBILE_APP_FEATURE_TO_REFLECTED_ATTRIBUTE =
            ImmutableMap.<MobileAppFeatureEnum, NewReflectedAttribute>builder()
                    .put(MobileAppFeatureEnum.CUSTOMER_RATING, NewReflectedAttribute.RATING)
                    .put(MobileAppFeatureEnum.ICON, NewReflectedAttribute.ICON)
                    .put(MobileAppFeatureEnum.PRICE, NewReflectedAttribute.PRICE)
                    .put(MobileAppFeatureEnum.RATINGS, NewReflectedAttribute.RATING_VOTES)
                    .build();

    private static final Map<NewReflectedAttribute, Predicate<MobileContent>> REFLECTED_ATTRIBUTE_TO_HAS_VALUE_PREDICATE =
            ImmutableMap.<NewReflectedAttribute, Predicate<MobileContent>>builder()
                    .put(NewReflectedAttribute.RATING, mc -> mc.getRating() != null)
                    .put(NewReflectedAttribute.ICON, mc -> mc.getIconHash() != null)
                    .put(NewReflectedAttribute.PRICE, mc -> mc.getPrices() != null && !mc.getPrices().isEmpty())
                    .put(NewReflectedAttribute.RATING_VOTES, mc -> mc.getRatingVotes() != null)
                    .build();

    private MobileAppFeatureConverter() {
        // no instantiation
    }

    static Collection<MobileAppAdFeatureGetItem> convertMobileAppFeatures(
            Map<NewReflectedAttribute, Boolean> reflectedAttributes, @Nullable MobileContent mobileContent) {
        List<MobileAppAdFeatureGetItem> features = new ArrayList<>();

        List<MobileAppFeatureEnum> featuresList = StreamEx.of(MobileAppFeatureEnum.values())
                .sorted(comparing(MobileAppFeatureEnum::name, String.CASE_INSENSITIVE_ORDER)).toList();

        for (MobileAppFeatureEnum featureName : featuresList) {

            NewReflectedAttribute attr = MOBILE_APP_FEATURE_TO_REFLECTED_ATTRIBUTE.get(featureName);

            if (attr == null) {
                throw new IllegalArgumentException(
                        "can\'t guess ReflectedAttribute for MobileAppFeatureEnum: " + featureName);
            }

            MobileAppAdFeatureGetItem featureItem = new MobileAppAdFeatureGetItem()
                    .withFeature(featureName)
                    .withEnabled(reflectedAttributes.getOrDefault(attr, false) ? YesNoEnum.YES : YesNoEnum.NO)
                    .withIsAvailable(YesNoUnknownEnum.UNKNOWN);

            // пытались получить данные по приложению из ручки по извлечению данных из сторов
            if (mobileContent != null && mobileContent.getModifyTime() != null) {
                boolean hasValue = REFLECTED_ATTRIBUTE_TO_HAS_VALUE_PREDICATE.get(attr).test(mobileContent);
                featureItem.withIsAvailable(hasValue ? YesNoUnknownEnum.YES : YesNoUnknownEnum.NO);
            }

            features.add(featureItem);
        }

        return features;
    }
}
