package ru.yandex.direct.web.entity.useractionlog;

import java.util.Collection;
import java.util.Objects;
import java.util.Optional;

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

import com.google.common.collect.ImmutableList;
import io.leangen.graphql.annotations.GraphQLNonNull;
import io.leangen.graphql.annotations.GraphQLQuery;
import io.leangen.graphql.annotations.types.GraphQLType;

import ru.yandex.direct.core.entity.retargeting.model.Goal;

@GraphQLType(name = "Goal")
@ParametersAreNonnullByDefault
public class GoalView {
    /**
     * Магическая константа. Везде в Директе принято, что null означает "нет цели"
     */
    public static final GoalView NO_GOAL = new GoalView(null, "no_goal");

    /**
     * Магическая константа. Везде в Директе принято, что 0 означает "все цели"
     */
    private static final GoalView ALL_GOALS = new GoalView(0L, "all_goals");

    /**
     * Специальная уличная магия. DIRECT-78459 DIRECT-56901
     * <p>
     * Используется только в рекламе мобильных приложений в стратегии "Недельный бюджет".
     * Неизвестно, как так вышло, но наличие этой цели в стратегии означает "Получать максимальное количество
     * установок", а её отсутствие означает "Получать максимум кликов".
     * <p>
     * И вот так оно и хранится в mysql. При этом никаких целей стратегия, на самом деле, не поддерживает.
     * <p>
     * На фронтенде тоже стоит костыль, который корректно обрабатывает это значение.
     */
    private static final GoalView MOBILE_AUTOBUDGET_STRATEGY_KLUDGE = new GoalView(4100000000L, "kludge");
    private static final GoalView MOBILE_AUTOBUDGET_STRATEGY_KLUDGE2 = new GoalView(4L, "kludge2");

    private static final Collection<GoalView> SPECIAL_GOALS = ImmutableList.of(
            NO_GOAL,
            ALL_GOALS,
            MOBILE_AUTOBUDGET_STRATEGY_KLUDGE,
            MOBILE_AUTOBUDGET_STRATEGY_KLUDGE2
    );

    @GraphQLQuery
    public final Long id;

    @GraphQLQuery
    @GraphQLNonNull
    @Nonnull
    public final String name;

    public GoalView(@Nullable Long id, String name) {
        this.id = id;
        this.name = name;
    }

    public GoalView(Goal goalModel) {
        this(goalModel.getId(), goalModel.getName());
    }

    public static Optional<GoalView> specialGoalView(@Nullable Long goalId) {
        return SPECIAL_GOALS.stream().filter(g -> Objects.equals(g.id, goalId)).findAny();
    }
}
