package ru.yandex.direct.api.v5.entity.creatives.delegate;

import java.util.Map;
import java.util.Optional;
import java.util.function.Function;

import com.yandex.direct.api.v5.creatives.CpcVideoCreativeFieldEnum;
import com.yandex.direct.api.v5.creatives.CpmVideoCreativeFieldEnum;
import com.yandex.direct.api.v5.creatives.CreativeFieldEnum;
import com.yandex.direct.api.v5.creatives.SmartCreativeFieldEnum;
import com.yandex.direct.api.v5.creatives.VideoExtensionCreativeFieldEnum;
import one.util.streamex.StreamEx;

public enum CreativeAnyFieldEnum {

    CREATIVE_ID(CreativeFieldEnum.class, CreativeFieldEnum.ID),
    CREATIVE_TYPE(CreativeFieldEnum.class, CreativeFieldEnum.TYPE),
    CREATIVE_NAME(CreativeFieldEnum.class, CreativeFieldEnum.NAME),
    CREATIVE_PREVIEW_URL(CreativeFieldEnum.class, CreativeFieldEnum.PREVIEW_URL),
    CREATIVE_WIDTH(CreativeFieldEnum.class, CreativeFieldEnum.WIDTH),
    CREATIVE_HEIGHT(CreativeFieldEnum.class, CreativeFieldEnum.HEIGHT),
    CREATIVE_THUMBNAIL_URL(CreativeFieldEnum.class, CreativeFieldEnum.THUMBNAIL_URL),
    CREATIVE_ASSOCIATED(CreativeFieldEnum.class, CreativeFieldEnum.ASSOCIATED),
    CREATIVE_IS_ADAPTIVE(CreativeFieldEnum.class, CreativeFieldEnum.IS_ADAPTIVE),

    VIDEO_EXTENSION_CREATIVE_DURATION(VideoExtensionCreativeFieldEnum.class, VideoExtensionCreativeFieldEnum.DURATION),

    CPC_VIDEO_CREATIVE_DURATION(CpcVideoCreativeFieldEnum.class, CpcVideoCreativeFieldEnum.DURATION),

    CPM_VIDEO_CREATIVE_DURATION(CpmVideoCreativeFieldEnum.class, CpmVideoCreativeFieldEnum.DURATION),

    CREATIVE_GROUP_ID(SmartCreativeFieldEnum.class, SmartCreativeFieldEnum.CREATIVE_GROUP_ID),
    CREATIVE_GROUP_NAME(SmartCreativeFieldEnum.class, SmartCreativeFieldEnum.CREATIVE_GROUP_NAME),
    BUSINESS_TYPE(SmartCreativeFieldEnum.class, SmartCreativeFieldEnum.BUSINESS_TYPE);

    private final Class<?> enumClazz;
    private final Enum value;

    private static final Map<Enum, CreativeAnyFieldEnum> FIELD_ENUM =
            StreamEx.of(CreativeAnyFieldEnum.values()).toMap(CreativeAnyFieldEnum::getValue, Function.identity());

    CreativeAnyFieldEnum(Class<?> enumClazz, Enum value) {
        this.enumClazz = enumClazz;
        this.value = value;
    }

    public Class<?> getEnumClass() {
        return enumClazz;
    }

    public Enum getValue() {
        return value;
    }


    private static CreativeAnyFieldEnum fromEnum(Enum enumValue) {
        return Optional.ofNullable(FIELD_ENUM.get(enumValue)).orElseThrow(IllegalArgumentException::new);
    }

    public static CreativeAnyFieldEnum fromCreativeFieldEnum(CreativeFieldEnum creativeFieldEnum) {
        return fromEnum(creativeFieldEnum);
    }

    public static CreativeAnyFieldEnum fromVideoExtensionCreativeFieldEnum(
            VideoExtensionCreativeFieldEnum videoExtensionCreativeFieldEnum) {
        return fromEnum(videoExtensionCreativeFieldEnum);
    }

    public static CreativeAnyFieldEnum fromCpcVideoCreativeFieldEnum(
            CpcVideoCreativeFieldEnum cpcVideoCreativeFieldEnum) {
        return fromEnum(cpcVideoCreativeFieldEnum);

    }

    public static CreativeAnyFieldEnum fromCpmVideoCreativeFieldEnum(
            CpmVideoCreativeFieldEnum cpmVideoCreativeFieldEnum) {
        return fromEnum(cpmVideoCreativeFieldEnum);
    }

    public static CreativeAnyFieldEnum fromSmartCreativeFieldEnum(
            SmartCreativeFieldEnum smartCreativeFieldEnum) {
        return fromEnum(smartCreativeFieldEnum);
    }
}

