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

import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

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

import io.delphiplatform.api.v3.model.datahealth.AdsDataHealthStatusReport;
import io.delphiplatform.api.v3.model.datahealth.DataHealthStatusSummary;
import io.delphiplatform.api.v3.rdb.entity.AdsDataHealthStatusSummaryProjection;
import io.delphiplatform.api.v3.rdb.repository.AdsDataStatusDailyRepository;
import io.delphiplatform.api.v3.view.util.Params;

@Service
@Transactional(readOnly = true)
public class AdsDataHealthStatusService {

    private final AdsDataStatusDailyRepository adsDataStatusDailyRepository;

    public AdsDataHealthStatusService(
        AdsDataStatusDailyRepository repository) {
        this.adsDataStatusDailyRepository = repository;
    }

    public AdsDataHealthStatusReport<DataHealthStatusSummary> getAdsDataHealthStatusReport(Params params) {
        List<AdsDataHealthStatusSummaryProjection> items = adsDataStatusDailyRepository
            .getStatusSummary(params.getDataHealthStatusesAsString(),
                params.getDsp(), params.getAdsAccounts(), params.getParentRepOwnerKeys());

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

        Map<String, DataHealthStatusSummary> dspMap = items.stream()
            .filter(elem -> elem.getAccountId() == null && elem.getParentRepOwner() == null)
            .collect(Collectors.groupingBy(AdsDataHealthStatusSummaryProjection::getDsp, DataHealthSummaryCollector.get()));
        report.setDspMap(dspMap);

        Map<String, Map<String, DataHealthStatusSummary>> dspProMap =
            items.stream().filter(elem -> elem.getAccountId() == null && elem.getParentRepOwner() != null)
                    .collect(Collectors.groupingBy(AdsDataHealthStatusSummaryProjection::getDsp,
                        Collectors.groupingBy(AdsDataHealthStatusSummaryProjection::getParentRepOwner, DataHealthSummaryCollector.get())));
        report.setDspProMap(dspProMap);

        Map<String, Map<String, Map<String, DataHealthStatusSummary>>> dspProAdsMap =
            items.stream().filter(elem -> elem.getAccountId() != null && elem.getParentRepOwner() != null)
                    .collect(Collectors.groupingBy(AdsDataHealthStatusSummaryProjection::getDsp,
                        Collectors.groupingBy(AdsDataHealthStatusSummaryProjection::getParentRepOwner,
                            Collectors.groupingBy(AdsDataHealthStatusSummaryProjection::getAccountId, DataHealthSummaryCollector.get()))));

        report.setDspProAdsMap(dspProAdsMap);

        return report;
    }

}
