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

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

import lombok.RequiredArgsConstructor;
import lombok.Setter;
import lombok.Value;
import lombok.extern.slf4j.Slf4j;
import org.joda.time.DateTime;
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.core.http.request.PagerAware;
import ru.yandex.webmaster3.core.searchquery.OrderDirection;
import ru.yandex.webmaster3.core.util.PageUtils;
import ru.yandex.webmaster3.storage.niche.NicheRivalQueriesReportCHDao;
import ru.yandex.webmaster3.storage.niche.NicheRivalQueriesReportCHDao.RivalInfo;
import ru.yandex.webmaster3.storage.niche.NicheRivalQueriesReportCHDao.SortField;
import ru.yandex.webmaster3.storage.niche.QuerySource;
import ru.yandex.webmaster3.storage.searchquery.DeviceType;
import ru.yandex.webmaster3.viewer.http.AbstractUserVerifiedHostAction;
import ru.yandex.webmaster3.viewer.http.host.verification.UsersVerifiedHostRequest;

/**
 * ishalaru
 * 28.06.2021
 **/
@Slf4j
@Component("/niche/rivals")
@RequiredArgsConstructor(onConstructor_ = {@Autowired})
@Category("niche")
@ReadAction
public class GetNicheRivalListAction extends AbstractUserVerifiedHostAction<GetNicheRivalListAction.Request, GetNicheRivalListAction.Response> {
    private final NicheRivalQueriesReportCHDao nicheRivalQueriesReportCHDao;

    @Override
    public Response process(Request request) {
        WebmasterHostId hostId = request.getHostId();
        var rivals = nicheRivalQueriesReportCHDao.getRivals(hostId, request.dateFrom.toLocalDate(), request.dateTo.toLocalDate(),
                request.regionId, request.deviceType, request.source, request.orderBy, request.orderDirection);
        // search for THIS rival
        Optional<RivalInfo> thisRival = rivals.stream().filter(rivalInfo -> rivalInfo.getHostId().equals(hostId)).findAny();
        PageUtils.Pager pager = PageUtils.getPage(request.p, request.pSize);
        var rivalsToDisplay = rivals.stream()
                .filter(rivalInfo -> !rivalInfo.getHostId().equals(hostId))
                .skip(pager.toRangeStart())
                .limit(pager.getPageSize())
                .collect(Collectors.toList());
        if (thisRival.isPresent()) {
            rivalsToDisplay.add(0, thisRival.get());
        } else {
            rivalsToDisplay.add(0, new RivalInfo(hostId, 0.0, 0.0));
        }
        return new Response(rivalsToDisplay, rivals.size() - (thisRival.isPresent() ? 1 : 0));
    }

    public static class Request extends UsersVerifiedHostRequest implements PagerAware {
        @Setter(onMethod_ = {@Description("Начало периода"), @RequestQueryProperty(required = true)})
        DateTime dateFrom;
        @Setter(onMethod_ = {@Description("Конец периода"), @RequestQueryProperty(required = true)})
        DateTime dateTo;
        @Setter(onMethod_ = {@Description("Фильтр по регионам"), @RequestQueryProperty})
        Integer[] regionId;
        @Setter(onMethod_ = {@Description("Источник query"), @RequestQueryProperty})
        QuerySource source = QuerySource.MINED;
        @Setter(onMethod_ = {@Description("Фильтр по устройству"), @RequestQueryProperty})
        DeviceType deviceType = DeviceType.ALL_DEVICES;
        @Setter(onMethod_ = {@Description("Сортировка по"), @RequestQueryProperty})
        SortField orderBy = SortField.VISIBILITY;
        @Setter(onMethod_ = {@Description("Порядок сортировки"), @RequestQueryProperty})
        OrderDirection orderDirection = OrderDirection.DESC;
        @Setter(onMethod_ = {@Description("Страница"), @RequestQueryProperty})
        int p = 0;
        @Setter(onMethod_ = {@Description("Размер страницы"), @RequestQueryProperty})
        int pSize = 20;

    }

    @Value
    public static class Response implements ActionResponse, ActionResponse.NormalResponse {
        @Description("Список конкурентов для данного хоста")
        List<RivalInfo> rivals;
        @Description("Количество конкурентов")
        long totalCount;
    }

}
