package io.delphiplatform.api.v3.bigtable.processing;

import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.function.LongConsumer;
import java.util.function.Supplier;
import java.util.stream.Collector;

import io.delphiplatform.api.v3.model.tiktok.TikTokTrackAnalyticsMetrics;
import io.delphiplatform.api.v3.model.tiktok.TikTokTrackAnalyticsRangeMetrics;
import lombok.Getter;

@Getter
public class CountryTotalsCollector {

    private TikTokTrackAnalyticsMetrics data;

    public CountryTotalsCollector() {
        this.data = new TikTokTrackAnalyticsMetrics();
    }

    public void accumulate(Map.Entry<String, TikTokTrackAnalyticsRangeMetrics> model) {
        updateValue(() -> data.getCreations(), () -> model.getValue().getCreations(), val -> data.setCreations(val));
        updateValue(() -> data.getLikes(), () -> model.getValue().getLikes(), val -> data.setLikes(val));
        updateValue(() -> data.getShares(), () -> model.getValue().getShares(), val -> data.setShares(val));
        updateValue(() -> data.getFavorites(), () -> model.getValue().getFavorites(), val -> data.setFavorites(val));
        updateValue(() -> data.getComments(), () -> model.getValue().getComments(), val -> data.setComments(val));
        updateValue(() -> data.getVideoViews(), () -> model.getValue().getVideoViews(), val -> data.setVideoViews(val));
    }

    public void updateValue(Supplier<Long> getPrevValue, Supplier<List<Long>> newValues, LongConsumer setNewValue) {
        Long prevValue = getPrevValue.get();
        if (newValues.get() != null) {
            Long addition = newValues.get().stream().filter(Objects::nonNull).mapToLong(Long::longValue).sum();
            setNewValue.accept(prevValue == null ? addition : prevValue + addition);
        }
    }

    public CountryTotalsCollector merge(CountryTotalsCollector another) {
        return this;
    }

    public TikTokTrackAnalyticsMetrics finish() {
        return data;
    }

    public static Collector<Map.Entry<String, TikTokTrackAnalyticsRangeMetrics>, CountryTotalsCollector,
        TikTokTrackAnalyticsMetrics> get() {
        return Collector.of(
            CountryTotalsCollector::new,
            CountryTotalsCollector::accumulate,
            CountryTotalsCollector::merge,
            CountryTotalsCollector::finish);
    }
}
