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

import com.google.common.collect.RangeSet;
import lombok.extern.slf4j.Slf4j;
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.SpecialGroup;
import ru.yandex.webmaster3.storage.searchquery.*;

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

/**
 * @author leonidrom
 */

/*
 * Путь: /user/{user_id}/hosts/{host_id}/search-queries/{query_id}/history/
 * История статистики для конкретного поискового запроса, как на графике раздела "Статистика запросов"
 */
@Slf4j
@Description("Получить историю статистики для конкретного поискового запроса")
@Category("searchquery")
@Component
public class SearchQueryHistoryAction extends AbstractApiAction<SearchQueryHistoryRequest, SearchQueryHistoryResponse> {
    private static final int PERIOD_DAYS = 7;
    private final QueryStatisticsService2 queryStatisticsService2;

    @Autowired
    public SearchQueryHistoryAction(QueryStatisticsService2 queryStatisticsService2) {
        super(Permission.COMMON);
        this.queryStatisticsService2 = queryStatisticsService2;
    }

    @Override
    public SearchQueryHistoryResponse process(SearchQueryHistoryRequest 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 queryId = request.getLocator().getQueryId();
        var hostId = request.getHostId();
        var deviceType = request.getDeviceTypeIndicator().getCoreDeviceType();

        // Проверим queryId на валидность
        if (!queryStatisticsService2.isValidQueryId(SpecialGroup.TOP_3000_QUERIES, hostId, queryId)) {
            return new SearchQueryHistoryResponse.InvalidQueryIdResponse(queryId);
        }

        // Получим статистику из базы
        List<QueryStat> statistics = queryStatisticsService2.getStatistics(
                SpecialGroup.TOP_3000_QUERIES,
                hostId,
                coreIndicators,
                List.of(queryId),
                Collections.emptySet(),
                RegionInclusion.INCLUDE_ALL,
                dateFrom,
                dateTo,
                deviceType);

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

        var queryTextsMap = queryStatisticsService2.getQueryTexts(hostId, SpecialGroup.TOP_3000_QUERIES, List.of(queryId));
        String queryText = queryTextsMap.get(queryId);

        return new SearchQueryHistoryResponse.NormalResponse(queryId, queryText, indicatorsHistory);
    }
}
