package io.delphiplatform.api.v3.rdb.service.tiktok;

import java.time.LocalDate;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collector;

import io.delphiplatform.api.util.model.ModelUtils;
import io.delphiplatform.api.v3.model.tiktok.top.TikTokChartTracksAnalyticsMetricGroup;
import io.delphiplatform.api.v3.model.tiktok.top.TikTokTopTracksAnalytics;
import io.delphiplatform.api.v3.rdb.entity.tiktok.FactTikTokTopTrackEntity;
import lombok.Getter;

@Getter
public class TikTokTopAnalyticCollector {

    private String isrc;

    private Integer minPosition;

    private Integer maxPosition;

    private LocalDate minDate;

    private LocalDate maxDate;

    private final Map<LocalDate, Integer> positions = new HashMap<>();

    public TikTokTopAnalyticCollector() {
    }

    public void accumulate(FactTikTokTopTrackEntity model) {
        if (this.isrc == null) {
            this.isrc = model.getId().getIsrc();
        }
        Integer currentPosition = model.getCurrentPosition();
        if (minPosition == null || currentPosition < minPosition) {
            minPosition = currentPosition;
        }
        if (maxPosition == null || currentPosition > maxPosition) {
            maxPosition = currentPosition;
        }
        LocalDate date = model.getId().getChartDate();
        if (minDate == null || date.isBefore(minDate)) {
            minDate = date;
        }
        if (maxDate == null || date.isAfter(maxDate)) {
            maxDate = date;
        }

        Integer existedPosition = positions.get(date);
        if (existedPosition == null || model.getCurrentPosition() < existedPosition) {
            positions.put(date, model.getCurrentPosition());
        }
    }

    private List<Integer> getPositions() {
        return ModelUtils.toRange(positions, minDate, maxDate);
    }

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

    public TikTokTopTracksAnalytics finish() {
        TikTokChartTracksAnalyticsMetricGroup tikTokChartTracksAnalyticsMetricGroup =
            TikTokChartTracksAnalyticsMetricGroup.builder()
                .positions(getPositions())
                .build();
        return
            TikTokTopTracksAnalytics.builder()
                .minPosition(minPosition)
                .maxPosition(maxPosition)
                .minDate(minDate)
                .maxDate(maxDate)
                .metrics(tikTokChartTracksAnalyticsMetricGroup)
                .isrc(isrc)
                .build();
    }

    public static Collector<FactTikTokTopTrackEntity, TikTokTopAnalyticCollector, TikTokTopTracksAnalytics> get() {
        return Collector.of(
            TikTokTopAnalyticCollector::new,
            TikTokTopAnalyticCollector::accumulate,
            TikTokTopAnalyticCollector::merge,
            TikTokTopAnalyticCollector::finish);
    }
}
