package ru.yandex.webmaster3.storage.turbo.dao.logo;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.function.Supplier;
import java.util.stream.Collectors;

import com.google.common.base.Suppliers;
import org.apache.commons.lang3.tuple.Pair;
import org.apache.commons.lang3.tuple.Triple;
import org.jetbrains.annotations.NotNull;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Repository;

import ru.yandex.webmaster3.core.turbo.model.TurboHostHeaderType;
import ru.yandex.webmaster3.core.turbo.model.TurboLogo;
import ru.yandex.webmaster3.storage.turbo.logo.TurboLogoData;
import ru.yandex.webmaster3.storage.util.ydb.AbstractYDao;
import ru.yandex.webmaster3.storage.util.ydb.querybuilder.typesafe.DataMapper;
import ru.yandex.webmaster3.storage.util.ydb.querybuilder.typesafe.Field;
import ru.yandex.webmaster3.storage.util.ydb.querybuilder.typesafe.Fields;

/**
 * Created by Oleg Bazdyrev on 17/06/2020.
 */
@Repository
public class DefaultTurboLogoYDao extends AbstractYDao {

    protected DefaultTurboLogoYDao() {
        super(PREFIX_TURBO, "default_turbo_logos");
    }

    private static final String DEFAULT_PREFIX = "a";
    private static final String DEFAULT_COLOR = "blue";

    @Value("${webmaster3.storage.mds.avatars.turbo.viewer}")
    private String avatarsHost;

    private static final List<TurboHostHeaderType> TURBO_HOST_HEADER_TYPES = List.of(TurboHostHeaderType.SQUARE, TurboHostHeaderType.HORIZONTAL, TurboHostHeaderType.ECOMMERCE);

    private static final DataMapper<Triple<String, String, TurboLogo>> MAPPER = DataMapper.create(F.PREFIX, F.COLOR, F.LOGO, Triple::of);

    private Supplier<Map<String, Map<String, TurboLogo>>> defaultLogosSupplier = Suppliers.memoize(this::getAll);

    public void add(String prefix, String color, TurboLogo logo) {
        upsert(F.PREFIX.value(prefix), F.COLOR.value(color), F.LOGO.value(logo)).execute();
    }

    public @NotNull TurboLogo getLogo(String prefix) {
        return defaultLogosSupplier.get().getOrDefault(prefix, defaultLogosSupplier.get().get(DEFAULT_PREFIX)).get(DEFAULT_COLOR);
    }

    public @NotNull TurboLogo getLogo(String prefix, String color) {
        return defaultLogosSupplier.get().getOrDefault(prefix, defaultLogosSupplier.get().get(DEFAULT_PREFIX)).get(color);
    }

    public Map<String, TurboLogo> getLogosByColors(String prefix) {
        return defaultLogosSupplier.get().get(prefix);
    }

    public Map<String, Map<String, TurboLogo>> getAll() {
        var triples = select(MAPPER).queryForList();
        Map<String, Map<String, TurboLogo>> result = new HashMap<>();
        for (var triple : triples) {
            final TurboLogo turboLogo = triple.getRight();
            final Pair<String, Long> parsedLogoId = TurboLogoData.parseFrontLogoId(turboLogo.getLogoId());
            final String avatarPrefixUrl = avatarsHost + "/get-turbo/" + parsedLogoId.getRight() + "/" + parsedLogoId.getLeft() + "/";
            final Map<TurboHostHeaderType, String> logoUrls = TURBO_HOST_HEADER_TYPES.stream()
                    .collect(Collectors.toMap(k -> k, v -> avatarPrefixUrl + v.getLogoSize()));
            result.computeIfAbsent(triple.getLeft(), k -> new HashMap<>()).put(triple.getMiddle(), turboLogo.withLogoUrls(logoUrls));
        }
        return result;
    }

    private interface F {
        Field<String> PREFIX = Fields.stringField("prefix");
        Field<String> COLOR = Fields.stringField("color");
        Field<TurboLogo> LOGO = Fields.jsonField2("logo", TurboLogo.class);
    }
}
