package ru.yandex.webmaster3.viewer.http.searchurl.excluded;

import java.util.ArrayList;
import java.util.EnumMap;
import java.util.List;
import java.util.Map;
import java.util.NavigableMap;
import java.util.Set;
import java.util.stream.Collectors;

import lombok.RequiredArgsConstructor;
import org.joda.time.Instant;
import org.springframework.beans.factory.annotation.Autowired;

import ru.yandex.autodoc.common.doc.annotation.Description;
import ru.yandex.webmaster3.core.WebmasterException;
import ru.yandex.webmaster3.core.http.Action;
import ru.yandex.webmaster3.core.http.ReadAction;
import ru.yandex.webmaster3.core.link.DatePoint;
import ru.yandex.webmaster3.core.metrics.Category;
import ru.yandex.webmaster3.core.sitestructure.SearchUrlStatusEnum;
import ru.yandex.webmaster3.core.util.TimeUtils;
import ru.yandex.webmaster3.storage.searchurl.history.SearchUrlHistoryService;
import ru.yandex.webmaster3.storage.searchurl.history.data.ExcludedUrlHistoryPoint;

/**
 * @author avhaliullin
 */
@ReadAction
@Description("График истории количества исключенных страниц")
@Category("searchurl")
@RequiredArgsConstructor(onConstructor_ = @Autowired)
public class ExcludedUrlHistoryAction extends Action<ExcludedUrlHistoryRequest, ExcludedUrlHistoryResponse> {

    private final SearchUrlHistoryService searchUrlHistoryService;

    @Override
    public ExcludedUrlHistoryResponse process(ExcludedUrlHistoryRequest request) throws WebmasterException {
        NavigableMap<Instant, ExcludedUrlHistoryPoint> rawHistory = searchUrlHistoryService.getExcludedHistory(
                request.getHostId(),
                request.getNodeId(),
                request.getDateFrom(),
                request.getDateTo()
        );

        Set<SearchUrlStatusEnum> statuses = rawHistory.values()
                .stream()
                .flatMap(p -> p.getStatus2Value().keySet().stream())
                .collect(Collectors.toSet());

        Map<SearchUrlStatusEnum, List<DatePoint>> indicatorsMap = new EnumMap<>(SearchUrlStatusEnum.class);
        for (Map.Entry<Instant, ExcludedUrlHistoryPoint> pointEntry : rawHistory.entrySet()) {
            for (SearchUrlStatusEnum status : statuses) {
                long value = pointEntry.getValue().getStatus2Value().getOrDefault(status, 0L);
                indicatorsMap.computeIfAbsent(status, ign -> new ArrayList<>())
                        .add(new DatePoint(
                                pointEntry.getKey().toDateTime(TimeUtils.EUROPE_MOSCOW_ZONE).toLocalDate(),
                                value
                        ));
            }
        }
        List<ExcludedUrlHistoryResponse.ExcludedUrlHistory> result = new ArrayList<>();
        for (SearchUrlStatusEnum status : SearchUrlStatusEnum.values()) {
            List<DatePoint> points = indicatorsMap.get(status);
            if (points != null) {
                result.add(new ExcludedUrlHistoryResponse.ExcludedUrlHistory(status, points));
            }
        }
        return new ExcludedUrlHistoryResponse(result);
    }
}
