package ru.yandex.webmaster3.viewer.http.niche;

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

import lombok.RequiredArgsConstructor;
import lombok.Setter;
import lombok.Value;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ObjectUtils;
import org.joda.time.DateTime;
import org.joda.time.LocalDate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import ru.yandex.autodoc.common.doc.annotation.Category;
import ru.yandex.autodoc.common.doc.annotation.Description;
import ru.yandex.webmaster3.core.data.WebmasterHostId;
import ru.yandex.webmaster3.core.http.ActionResponse;
import ru.yandex.webmaster3.core.http.ReadAction;
import ru.yandex.webmaster3.core.http.RequestQueryProperty;
import ru.yandex.webmaster3.storage.niche.NicheRivalQueriesReportCHDao;
import ru.yandex.webmaster3.storage.niche.NicheRivalQueriesReportCHDao.RivalDateInfo;
import ru.yandex.webmaster3.storage.niche.QuerySource;
import ru.yandex.webmaster3.storage.searchquery.DeviceType;
import ru.yandex.webmaster3.storage.searchquery.importing.dao.YtClickhouseDataLoadYDao;
import ru.yandex.webmaster3.viewer.http.AbstractUserVerifiedHostAction;
import ru.yandex.webmaster3.viewer.http.host.verification.UsersVerifiedHostRequest;

import static ru.yandex.webmaster3.storage.ytimport.YtClickhouseDataLoadType.NICHE_RIVAL_QUERIES_REPORT2;

/**
 * ishalaru
 * 28.06.2021
 **/
@Slf4j
@Component("/niche/rival_queries")
@RequiredArgsConstructor(onConstructor_ = {@Autowired})
@Category("niche")
@ReadAction
public class GetNicheRivalQueriesReportAction extends AbstractUserVerifiedHostAction<GetNicheRivalQueriesReportAction.Request, GetNicheRivalQueriesReportAction.Response> {

    private final NicheRivalQueriesReportCHDao nicheRivalQueriesReportCHDao;
    private final YtClickhouseDataLoadYDao ytClickhouseDataLoadYDao;

    @Override
    public Response process(Request request) {
        LocalDate startDate = request.dateFrom.toLocalDate();
        LocalDate endDate = ObjectUtils.min(request.dateTo.toLocalDate(), ytClickhouseDataLoadYDao.load(NICHE_RIVAL_QUERIES_REPORT2).getMaxProcessedDate());
        Map<WebmasterHostId, Map<LocalDate, Double>> visibilityMap = nicheRivalQueriesReportCHDao.getRivalHistory(request.getHostId(),
                startDate, endDate, request.rivals, request.regionId, request.deviceType, request.source).stream()
                .collect(Collectors.groupingBy(RivalDateInfo::getRivalHostId, Collectors.toMap(RivalDateInfo::getDate, RivalDateInfo::getVisibility)));
        // размножим недостающие данные (нулевая видимость)
        List<RivalHistoryPoint> result = new ArrayList<>();
        for (WebmasterHostId rival : request.rivals) {
            Map<LocalDate, Double> visibilities = visibilityMap.getOrDefault(rival, Collections.emptyMap());
            for (LocalDate date = startDate; !date.isAfter(endDate); date = date.plusDays(1)) {
                result.add(new RivalHistoryPoint(date, rival, visibilities.getOrDefault(date, 0.0)));
            }
        }
        return new Response(result);
    }

    public static class Request extends UsersVerifiedHostRequest {
        @Setter(onMethod_ = {@Description("Дата начала периода"), @RequestQueryProperty(required = true)})
        DateTime dateFrom;
        @Setter(onMethod_ = {@Description("Дата окончания периода"), @RequestQueryProperty(required = true)})
        DateTime dateTo;
        @Setter(onMethod_ = {@Description("Cписок конкурентов данного хоста"), @RequestQueryProperty(required = true)})
        List<WebmasterHostId> rivals;
        @Setter(onMethod_ = {@Description("Источник query"), @RequestQueryProperty(required = true)})
        QuerySource source;
        @Setter(onMethod_ = {@Description("Тип устройства"), @RequestQueryProperty(required = true)})
        DeviceType deviceType;
        @Setter(onMethod_ = {@Description("Регионы"), @RequestQueryProperty(required = false)})
        private Integer[] regionId;
    }

    @Value
    public static class RivalHistoryPoint {
        LocalDate date;
        WebmasterHostId rivalHostId;
        Double visibility;
    }

    @Value
    public static class Response implements ActionResponse, ActionResponse.NormalResponse {
        @Description("Информация по запросам конкурентов")
        List<RivalHistoryPoint> queriesInfo;
    }

}
