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

import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonProperty;
import org.jetbrains.annotations.Nullable;
import org.joda.time.DateTime;
import ru.yandex.autodoc.common.doc.annotation.Description;
import ru.yandex.webmaster3.core.data.HttpCodeInfo;
import ru.yandex.webmaster3.storage.searchurl.samples.data.UrlStatusInfo;
import ru.yandex.webmaster3.core.util.http.YandexMimeType;

/**
 * @author Oleg Bazdyrev
 */
public class ImportantUrlStatus {
    private final DateTime updateTime;
    @Nullable
    private final String title;

    // ВАЖНО: при добавлении/удалении флажка, поменять код ApiImportantUrlStatusChangeIndicator
    private final boolean titleChanged;
    private final boolean httpCodeChanged;
    private final boolean searchStatusChanged;
    private final boolean descriptionChanged;
    private final boolean relCanonicalTargetChanged;

    @Nullable
    private final IndexingInfo indexingInfo;

    @Nullable
    private final SearchInfo searchInfo;

    @JsonCreator
    public ImportantUrlStatus(DateTime updateTime, String title, boolean titleChanged, boolean httpCodeChanged,
                              boolean searchStatusChanged, boolean descriptionChanged,
                              boolean relCanonicalTargetChanged, IndexingInfo indexingInfo, SearchInfo searchInfo) {
        this.updateTime = updateTime;
        this.title = title;
        this.titleChanged = titleChanged;
        this.httpCodeChanged = httpCodeChanged;
        this.searchStatusChanged = searchStatusChanged;
        this.descriptionChanged = descriptionChanged;
        this.relCanonicalTargetChanged = relCanonicalTargetChanged;
        this.indexingInfo = indexingInfo;
        this.searchInfo = searchInfo;
    }

    public DateTime getUpdateTime() {
        return isHaveChange() ? updateTime : null;
    }

    @JsonIgnore
    public boolean isHaveChange() {
        return titleChanged || httpCodeChanged || searchStatusChanged
                            || descriptionChanged || relCanonicalTargetChanged;
    }

    @JsonIgnore
    public DateTime getRealUpdateTime() {
        return updateTime;
    }

    @Nullable
    public String getTitle() {
        return title;
    }

    @Description("Изменился ли заголовок страницы по сравнению с предыдущей записью в истории")
    public boolean isTitleChanged() {
        return titleChanged;
    }

    @Description("Изменился ли HTTP-код ответа сервера по сравнению с предыдущей записью в истории")
    public boolean isHttpCodeChanged() {
        return httpCodeChanged;
    }

    @Description("Изменился ли статус страницы в поиске по сравнению с предыдущей записью в истории")
    public boolean isSearchStatusChanged() {
        return searchStatusChanged;
    }

    public boolean isDescriptionChanged() {
        return descriptionChanged;
    }

    public boolean isRelCanonicalTargetChanged() {
        return relCanonicalTargetChanged;
    }

    @Nullable
    public IndexingInfo getIndexingInfo() {
        return indexingInfo;
    }

    @Nullable
    public SearchInfo getSearchInfo() {
        return searchInfo;
    }

    public static class IndexingInfo {
        private final HttpCodeInfo httpCode;

        private final DateTime lastAccess;
        private final YandexMimeType mimeType;

        public IndexingInfo(int httpCode, DateTime lastAccess, YandexMimeType mimeType) {
            this(new HttpCodeInfo(httpCode), lastAccess, mimeType);
        }

        public IndexingInfo(HttpCodeInfo httpCode, DateTime lastAccess, YandexMimeType mimeType) {
            this.httpCode = httpCode;
            this.lastAccess = lastAccess;
            this.mimeType = mimeType;
        }

        public HttpCodeInfo getHttpCode() {
            return httpCode;
        }

        public DateTime getLastAccess() {
            return lastAccess;
        }

        public YandexMimeType getMimeType() {
            return mimeType;
        }
    }

    public static class SearchInfo {
        private final HttpCodeInfo httpCode;
        private final YandexMimeType mimeType;
        private final UrlStatusInfo urlSearchInfo;

        @Nullable
        private final DateTime lastAccess;

        public SearchInfo(Integer httpCode, DateTime lastAccess, YandexMimeType mimeType,
                          UrlStatusInfo excludedStatus) {
            this(new HttpCodeInfo(httpCode), lastAccess, mimeType, excludedStatus);
        }

        @JsonCreator
        public SearchInfo(
                @JsonProperty("httpCode") HttpCodeInfo httpCode,
                @JsonProperty("lastAccess") DateTime lastAccess,
                @JsonProperty("mimeType") YandexMimeType mimeType,
                @JsonProperty("urlSearchInfo") UrlStatusInfo urlSearchInfo) {
            this.httpCode = httpCode;
            this.lastAccess = lastAccess;
            this.mimeType = mimeType;
            this.urlSearchInfo = urlSearchInfo;
        }

        public HttpCodeInfo getHttpCode() {
            return httpCode;
        }

        @Nullable
        public DateTime getLastAccess() {
            return lastAccess;
        }

        public YandexMimeType getMimeType() {
            return mimeType;
        }

        public UrlStatusInfo getUrlSearchInfo() {
            return urlSearchInfo;
        }
    }
}
