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

import java.net.IDN;
import java.util.Collection;
import java.util.Map;
import java.util.function.Consumer;

import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.tuple.Pair;
import org.joda.time.DateTime;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;

import ru.yandex.webmaster3.core.turbo.model.TurboLogo;
import ru.yandex.webmaster3.core.turbo.model.app.TurboAppSettings;
import ru.yandex.webmaster3.core.turbo.model.commerce.TurboColorScheme;
import ru.yandex.webmaster3.core.util.W3Collectors;
import ru.yandex.webmaster3.core.util.json.JsonMapping;
import ru.yandex.webmaster3.storage.turbo.dao.logo.DefaultTurboLogoYDao;
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 23/04/2020.
 */
@Repository
public class TurboAppSettingsYDao extends AbstractYDao {

    @Autowired
    private DefaultTurboLogoYDao defaultTurboLogoYDao;


    private static final String DEFAULT_COLOR_SCHEME =
            JsonMapping.writeValueAsString(TurboColorScheme.builder().type(TurboColorScheme.Type.BLUE).build());
    private static final String DEFAULT_DESCRIPTION = "Интернет-магазин";

    private static final DataMapper<TurboAppSettings> MAPPER = DataMapper.create(F.ENABLED, F.TITLE, F.DESCRIPTION, F.LOGO, F.THEME, F.SCC_CHECK_START_DATE,
            TurboAppSettings::new);
    private static final DataMapper<Pair<String, TurboAppSettings>> PAIR_MAPPER = DataMapper.create(F.DOMAIN, MAPPER, Pair::of);

    protected TurboAppSettingsYDao() {
        super(PREFIX_TURBO, "turbo_app_settings");
    }

    public void updateSettings(String domain, TurboAppSettings settings) {
        upsert(F.DOMAIN.value(domain),
                F.ENABLED.value(settings.getEnabled()),
                F.TITLE.value(settings.getTitle()),
                F.DESCRIPTION.value(settings.getDescription()),
                F.LOGO.value(settings.getLogoInfo()),
                F.THEME.value(settings.getTheme()),
                F.SCC_CHECK_START_DATE.value(settings.getSccCheckStartDate())
        ).execute();
    }

    public void updateLogo(String domain, TurboLogo logo) {
        update().with(F.LOGO.set(logo)).where(F.DOMAIN.eq(domain)).execute();
    }

    public void updateSccLaunchTime(String domain, DateTime launch) {
        TurboAppSettings settings = getSettings(domain);
        if (settings == null) {
            settings = getDefaultSettings(domain);
        }
        settings = settings.toBuilder()
                .sccCheckStartDate(launch)
                .build();
        updateSettings(domain, settings);
    }

    TurboAppSettings getDefaultSettings(String domain) {
        String unicodeDomain = IDN.toUnicode(domain);
        return TurboAppSettings.builder()
                .logoInfo(defaultTurboLogoYDao.getLogo(unicodeDomain.substring(0, 1), "blue"))
                .theme(DEFAULT_COLOR_SCHEME)
                .description(DEFAULT_DESCRIPTION)
                .title(StringUtils.capitalize(unicodeDomain))
                .build();
    }

    public TurboAppSettings getSettings(String domain) {
        return select(MAPPER).where(F.DOMAIN.eq(domain)).queryOne();
    }

    public Map<String, TurboAppSettings> getSettings(Collection<String> domains) {
        return select(PAIR_MAPPER).where(F.DOMAIN.in(domains)).queryForList().stream().collect(W3Collectors.toHashMap());
    }

    public void forEachDomain(Consumer<String> consumer) {
        streamReader(F.DOMAIN, consumer);
    }

    private interface F {
        Field<String> DOMAIN = Fields.stringField("domain");
        Field<Boolean> ENABLED = Fields.boolField("enabled").makeOptional();
        Field<String> TITLE = Fields.stringField("title").makeOptional();
        Field<String> DESCRIPTION = Fields.stringField("description").makeOptional();
        Field<TurboLogo> LOGO = Fields.jsonField2("logo", TurboLogo.class).makeOptional();
        Field<String> THEME = Fields.stringField("theme").makeOptional();
        Field<DateTime> SCC_CHECK_START_DATE = Fields.jodaDateTimeField("scc_check_start_date").makeOptional();
    }
}
