package ru.yandex.canvas.model.presets;

import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.annotation.Nonnull;
import javax.annotation.Nullable;

import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonProperty;
import one.util.streamex.StreamEx;
import org.checkerframework.checker.nullness.qual.NonNull;

import static java.util.Collections.emptyList;
import static java.util.Collections.emptyMap;
import static java.util.Collections.emptySet;
import static java.util.function.Function.identity;
import static org.apache.commons.lang3.BooleanUtils.isTrue;
import static ru.yandex.direct.utils.CommonUtils.nvl;

/**
 * @author skirsanov
 */
public class Preset {
    @Nonnull
    @JsonProperty("id")
    private Integer id;
    /**
     * human-readable name
     */
    @JsonProperty("name")
    private String name;
    /**
     * picture of preview
     */
    @JsonProperty("thumbnail")
    private String thumbnail;

    @Nonnull
    @JsonProperty("tags")
    private Set<PresetTag> tags;

    /**
     * initial state of creative meta
     */
    @Nonnull
    @JsonProperty("items")
    private List<PresetItem> items;

    @Nonnull
    @JsonIgnore
    private Map<Integer, PresetItem> itemsById;

    public Preset(
            @JsonProperty("id") @NonNull Integer id,
            @JsonProperty("name") String name,
            @JsonProperty("thumbnail") String thumbnail,
            @JsonProperty("tags") @Nullable Set<PresetTag> tags,
            @JsonProperty("items") @Nullable List<PresetItem> items) {
        this.id = id;
        this.name = name;
        this.thumbnail = thumbnail;
        this.tags = nvl(tags, emptySet());
        this.items = nvl(items, emptyList());
        this.itemsById = items != null ? StreamEx.of(items).toMap(PresetItem::getId, identity()) : emptyMap();
    }

    @NonNull
    public Integer getId() {
        return id;
    }

    public void setId(@NonNull Integer id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getThumbnail() {
        return thumbnail;
    }

    public void setThumbnail(String thumbnail) {
        this.thumbnail = thumbnail;
    }

    @NonNull
    public List<PresetItem> getItems() {
        return items;
    }

    public void setItems(@NonNull List<PresetItem> items) {
        this.items = items;
    }

    @NonNull
    public Set<PresetTag> getTags() {
        return tags;
    }

    @Nullable
    public PresetItem getItemById(int id) {
        return itemsById.get(id);
    }

    public Boolean hasAdaptiveSupport() {
        return items.stream().anyMatch(i -> isTrue(i.getOptions().getIsAdaptive()));
    }

    @Override
    public String toString() {
        return "Preset{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", thumbnail='" + thumbnail + '\'' +
                ", tags=" + tags +
                ", items=" + items +
                '}';
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) {
            return true;
        }
        if (o == null || getClass() != o.getClass()) {
            return false;
        }

        Preset preset = (Preset) o;

        return id.equals(preset.id);
    }

    @Override
    public int hashCode() {
        return id.hashCode();
    }
}
