package ru.yandex.webmaster3.storage.importanturls.data;

import java.util.Comparator;
import java.util.List;
import java.util.Objects;

import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty;
import org.joda.time.DateTime;

import ru.yandex.webmaster3.core.data.WebmasterHostId;
import ru.yandex.webmaster3.storage.user.message.MessageTypeEnum;
import ru.yandex.webmaster3.storage.user.message.content.MessageContent;

/**
 * Created by ifilippov5 on 02.10.18.
 */
public abstract class ImportantUrlsChange<T> extends MessageContent.HostMessageContent {
    private final List<T> changes;

    public ImportantUrlsChange(MessageTypeEnum messageType, WebmasterHostId hostId, List<T> changes) {
        super(messageType, hostId);
        this.changes = changes;
    }

    public List<T> getChanges() {
        return changes;
    }

    public static class TitleChangeAllHostPages extends ImportantUrlsChange<ImportantUrlChange.TitleChange> {
        @JsonCreator
        public TitleChangeAllHostPages(
                @JsonProperty("hostId") WebmasterHostId hostId,
                @JsonProperty("changes") List<ImportantUrlChange.TitleChange> changes) {
            super(MessageTypeEnum.URL_TITLE_CHANGE_ALL_HOST_PAGES, hostId, changes);
        }
    }

    public static class IndexingLastAccessChangeAllHostPages extends ImportantUrlsChange<ImportantUrlChange.IndexingLastAccessChange> {
        private final DateTime newLastAccess;

        @JsonCreator
        public IndexingLastAccessChangeAllHostPages(
                @JsonProperty("hostId") WebmasterHostId hostId,
                @JsonProperty("newLastAccess") DateTime newLastAccess,
                @JsonProperty("changes") List<ImportantUrlChange.IndexingLastAccessChange> changes) {
            super(MessageTypeEnum.URL_INDEXING_LAST_ACCESS_CHANGE_ALL_HOST_PAGES, hostId, changes);
            this.newLastAccess = newLastAccess;
        }

        public IndexingLastAccessChangeAllHostPages(
                WebmasterHostId hostId,
                List<ImportantUrlChange.IndexingLastAccessChange> changes) {
            super(MessageTypeEnum.URL_INDEXING_LAST_ACCESS_CHANGE_ALL_HOST_PAGES, hostId, changes);
            this.newLastAccess = changes.stream().map(ImportantUrlChange.IndexingLastAccessChange::getNewLastAccess).filter(Objects::nonNull)
                    .min(Comparator.naturalOrder()).orElse(null);
        }

        public DateTime getNewLastAccess() {
            return newLastAccess;
        }
    }

    public static class SearchLastAccessChangeAllHostPages extends ImportantUrlsChange<ImportantUrlChange.SearchLastAccessChange> {
        private final DateTime newLastAccess;

        @JsonCreator
        public SearchLastAccessChangeAllHostPages(
                @JsonProperty("hostId") WebmasterHostId hostId,
                @JsonProperty("newLastAccess") DateTime newLastAccess,
                @JsonProperty("changes") List<ImportantUrlChange.SearchLastAccessChange> changes) {
            super(MessageTypeEnum.URL_SEARCH_LAST_ACCESS_CHANGE_ALL_HOST_PAGES, hostId, changes);
            this.newLastAccess = newLastAccess;
        }

        public SearchLastAccessChangeAllHostPages(
                WebmasterHostId hostId,
                List<ImportantUrlChange.SearchLastAccessChange> changes) {
            super(MessageTypeEnum.URL_SEARCH_LAST_ACCESS_CHANGE_ALL_HOST_PAGES, hostId, changes);
            this.newLastAccess = changes.stream().map(ImportantUrlChange.SearchLastAccessChange::getNewLastAccess).filter(Objects::nonNull)
                    .min(Comparator.naturalOrder()).orElse(null);
        }

        public DateTime getNewLastAccess() {
            return newLastAccess;
        }
    }

    public static class HttpCodeChangeAllHostPages extends ImportantUrlsChange<ImportantUrlChange.HttpCodeChange> {
        @JsonCreator
        public HttpCodeChangeAllHostPages(
                @JsonProperty("hostId") WebmasterHostId hostId,
                @JsonProperty("changes") List<ImportantUrlChange.HttpCodeChange> changes) {
            super(MessageTypeEnum.URL_INDEXING_STATUS_CHANGE_ALL_HOST_PAGES, hostId, changes);
        }
    }

    public static class SearchUrlStatusChangeAllHostPages extends ImportantUrlsChange<ImportantUrlChange.SearchUrlStatusChange> {
        @JsonCreator
        public SearchUrlStatusChangeAllHostPages(
                @JsonProperty("hostId") WebmasterHostId hostId,
                @JsonProperty("changes") List<ImportantUrlChange.SearchUrlStatusChange> changes) {
            super(MessageTypeEnum.URL_SEARCH_STATUS_CHANGE_ALL_HOST_PAGES, hostId, changes);
        }
    }

    public static class DescriptionChangeAllHostPages extends ImportantUrlsChange<ImportantUrlChange.DescriptionChange> {
        @JsonCreator
        public DescriptionChangeAllHostPages(
                @JsonProperty("hostId") WebmasterHostId hostId,
                @JsonProperty("changes") List<ImportantUrlChange.DescriptionChange> changes) {
            super(MessageTypeEnum.URL_DESCRIPTION_CHANGE_ALL_HOST_PAGES, hostId, changes);
        }
    }

    public static class RelCanonicalTargetChangeAllHostPages extends ImportantUrlsChange<ImportantUrlChange.RelCanonicalTargetChange> {
        @JsonCreator
        public RelCanonicalTargetChangeAllHostPages(
                @JsonProperty("hostId") WebmasterHostId hostId,
                @JsonProperty("changes") List<ImportantUrlChange.RelCanonicalTargetChange> changes) {
            super(MessageTypeEnum.URL_REL_CANONICAL_TARGET_CHANGE_ALL_HOST_PAGES, hostId, changes);
        }
    }
}
