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

import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import io.delphiplatform.api.v3.model.datahealth.DataHealthStatusSummary;
import io.delphiplatform.api.v3.model.datahealth.SpotifyChartsDataHealthStatusReport;
import io.delphiplatform.api.v3.model.spotify.SpotifyChartBreakdown;
import io.delphiplatform.api.v3.model.spotify.SpotifyChartType;
import io.delphiplatform.api.v3.rdb.entity.spotify.SpotifyChartsDataHealthStatusSummaryProjection;
import io.delphiplatform.api.v3.rdb.repository.spotify.SpotifyChartsDataStatusDailyRepository;
import io.delphiplatform.api.v3.rdb.service.DataHealthSummaryCollector;
import io.delphiplatform.api.v3.view.util.Params;

@Service
public class SpotifyChartsDataHealthStatusService {

    private final SpotifyChartsDataStatusDailyRepository repository;

    public SpotifyChartsDataHealthStatusService(
        SpotifyChartsDataStatusDailyRepository repository) {
        this.repository = repository;
    }

    public SpotifyChartsDataHealthStatusReport<DataHealthStatusSummary> getSpotifyChartsDataHealthStatus(Params params) {
        List<SpotifyChartsDataHealthStatusSummaryProjection> items = repository.getStatusSummary(
            params.getDataHealthStatusesAsString(),
            params.getBreakdowns().stream()
                .map(SpotifyChartBreakdown::getValue).collect(Collectors.toSet()),
            params.getTypes().stream()
                .map(SpotifyChartType::getValue).collect(Collectors.toSet()),
            params.getCountryCode()
        );

        SpotifyChartsDataHealthStatusReport<DataHealthStatusSummary> report = new SpotifyChartsDataHealthStatusReport<>();

        Map<String, DataHealthStatusSummary> breakdownMap = items.stream()
            .filter(elem -> elem.getChartType() == null && elem.getCountryCode() == null)
            .collect(Collectors.groupingBy(SpotifyChartsDataHealthStatusSummaryProjection::getBreakdown, DataHealthSummaryCollector.get()));
        report.setBreakdown(breakdownMap);

        Map<String, Map<String, DataHealthStatusSummary>> breakdownChartTypeMap =
            items.stream().filter(elem -> elem.getChartType() != null && elem.getCountryCode() == null)
                    .collect(Collectors.groupingBy(SpotifyChartsDataHealthStatusSummaryProjection::getBreakdown,
                        Collectors.groupingBy(SpotifyChartsDataHealthStatusSummaryProjection::getChartType, DataHealthSummaryCollector.get())));
        report.setBreakdownChartType(breakdownChartTypeMap);

        Map<String, Map<String, Map<String, DataHealthStatusSummary>>> breakdownChartTypeCountryMap =
            items.stream().filter(elem -> elem.getChartType() != null && elem.getCountryCode() != null)
                    .collect(Collectors.groupingBy(SpotifyChartsDataHealthStatusSummaryProjection::getBreakdown,
                        Collectors.groupingBy(SpotifyChartsDataHealthStatusSummaryProjection::getChartType,
                            Collectors.groupingBy(SpotifyChartsDataHealthStatusSummaryProjection::getCountryCode, DataHealthSummaryCollector.get()))));

        report.setBreakdownChartTypeCountryCode(breakdownChartTypeCountryMap);

        return report;
    }
}
