package ru.yandex.webmaster3.api.queries2.action;

import com.google.common.collect.RangeSet;
import org.apache.commons.lang3.tuple.Pair;
import org.joda.time.LocalDate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import ru.yandex.autodoc.common.doc.annotation.Description;
import ru.yandex.webmaster3.api.http.auth.Permission;
import ru.yandex.webmaster3.api.http.rest.AbstractApiAction;
import ru.yandex.webmaster3.api.queries.data.ApiQueryIndicator;
import ru.yandex.webmaster3.api.queries2.action.util.QueriesUtil;
import ru.yandex.webmaster3.core.metrics.Category;
import ru.yandex.webmaster3.core.searchquery.QueryGroupId;
import ru.yandex.webmaster3.core.searchquery.SpecialGroup;
import ru.yandex.webmaster3.storage.searchquery.*;

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

/**
 * @author leonidrom
 */

/*
 * Путь: /user/{user_id}/hosts/{host_id}/search-queries/all/history/
 * Сводная история статистики по всем поисковым запросам
 */
@Description("Получить сводную историю статистики по всем поисковым запросам")
@Category("searchquery")
@Component
public class AllSearchQueriesHistoryAction extends AbstractApiAction<AllSearchQueriesHistoryRequest, AllSearchQueriesHistoryResponse> {
    private static final int PERIOD_DAYS = 7;

    private final GroupStatisticsService2 groupStatisticsService2;

    @Autowired
    public AllSearchQueriesHistoryAction(GroupStatisticsService2 groupStatisticsService2) {
        super(Permission.COMMON);
        this.groupStatisticsService2 = groupStatisticsService2;
    }

    @Override
    public AllSearchQueriesHistoryResponse process(AllSearchQueriesHistoryRequest request) {
        var dateTo = request.getDateToOrNow().toLocalDate();
        var dateFrom = request.getDateFrom() == null? dateTo.minusDays(PERIOD_DAYS) : request.getDateFrom().toLocalDate();
        var apiIndicators = request.getQueryIndicators();
        var coreIndicators = apiIndicators.stream()
                .map(ApiQueryIndicator::getCoreQueryIndicator)
                .collect(Collectors.toList());
        var hostId = request.getHostId();
        var deviceType = request.getDeviceTypeIndicator().getCoreDeviceType();

        // Получим статистику из базы.
        var queryGroupId = new QueryGroupId(hostId, SpecialGroup.ALL_QUERIES);
        Map<QueryGroupId, List<GroupStat>> queryGroupStatsMap = groupStatisticsService2.getStatistics(
                hostId,
                Pair.of(dateFrom, dateTo),
                RegionInclusion.INCLUDE_ALL,
                Collections.emptySet(),
                List.of(queryGroupId),
                coreIndicators,
                deviceType
        );

        // Аккумулируем полученную статистику. В отличии от интерфейса ВМ,
        // где можно выбирать период аккумуляции, в API всегда аккумулируем по дням
        List<GroupStat> statistics = queryGroupStatsMap.getOrDefault(queryGroupId, Collections.emptyList());
        RangeSet<LocalDate> rangeSet = RangeFactory.createRanges(dateFrom, dateTo, AggregatePeriod.DAY, false, false);
        var indicatorsHistory = QueriesUtil.accumulateIndicatorsHistory(apiIndicators, statistics, rangeSet);

        return new AllSearchQueriesHistoryResponse(indicatorsHistory);
    }
}
