package ru.yandex.webmaster3.viewer.http.host.verification;

import org.joda.time.DateTime;
import org.joda.time.base.AbstractInstant;

import ru.yandex.autodoc.common.doc.annotation.Description;
import ru.yandex.webmaster3.core.host.verification.UinUtil;
import ru.yandex.webmaster3.core.host.verification.UserHostVerificationInfo;
import ru.yandex.webmaster3.core.host.verification.VerificationFailInfo;
import ru.yandex.webmaster3.core.host.verification.VerificationStatus;
import ru.yandex.webmaster3.core.host.verification.VerificationType;
import ru.yandex.webmaster3.core.http.ActionResponse;
import ru.yandex.webmaster3.core.user.UserVerifiedHost;

/**
 * @author avhaliullin
 */
public class HostVerificationInfoResponse implements ActionResponse.NormalResponse {
    private final VerificationStatus verificationStatus;
    private final VerificationType verificationType;
    private final String verificationUin;
    private final DateTime lastVerificationAttemptTime;
    private final DateTime nextVerificationAttemptTime;
    private final VerificationFailInfo lastVerificationFailInfo;
    private final DateTime verifiedDate;
    private final Long delegatedByUserId;
    private final boolean canDelegate;
    private final boolean canReset;

    public HostVerificationInfoResponse(VerificationStatus verificationStatus, VerificationType verificationType,
                                        String verificationUin, AbstractInstant nextVerificationAttemptTime, AbstractInstant lastVerificationAttemptTime,
                                        VerificationFailInfo lastVerificationFailInfo, AbstractInstant verifiedDate,
                                        Long delegatedByUserId, boolean canDelegate) {
        this.verificationStatus = verificationStatus;
        this.verificationType = verificationType;
        this.verificationUin = verificationUin;
        this.nextVerificationAttemptTime = toDateTime(nextVerificationAttemptTime);
        this.lastVerificationAttemptTime = toDateTime(lastVerificationAttemptTime);
        this.lastVerificationFailInfo = lastVerificationFailInfo;
        this.verifiedDate = toDateTime(verifiedDate);
        this.delegatedByUserId = delegatedByUserId;

        // Пока у на нет запрета на переделигирование, эти флаги совпадают
        this.canDelegate = canDelegate;
        this.canReset = canDelegate;
    }

    @Description("null, если подтверждение прав не производилось")
    public VerificationStatus getVerificationStatus() {
        return verificationStatus;
    }

    public VerificationType getVerificationType() {
        return verificationType;
    }

    @Description("код для подтверждения прав")
    public String getVerificationUin() {
        return verificationUin;
    }

    @Description("дата следующей проверки")
    public DateTime getNextVerificationAttemptTime() {
        return nextVerificationAttemptTime;
    }

    @Description("дата последней проверки")
    public DateTime getLastVerificationAttemptTime() {
        return lastVerificationAttemptTime;
    }

    @Description("результат последней неудачной проверки")
    public VerificationFailInfo getLastVerificationFailInfo() {
        return lastVerificationFailInfo;
    }

    @Description("дата подтверждения прав (если подтверждены)")
    public DateTime getVerifiedDate() {
        return verifiedDate;
    }

    @Description("uid пользователя, делегировавшего права (если права делегированы)")
    public Long getDelegatedByUserId() {
        return delegatedByUserId;
    }

    @Description("может ли пользователь делегировать права")
    public boolean isCanDelegate() {
        return canDelegate;
    }

    @Description("может ли пользователь сбрасывать права другим пользователям")
    public boolean isCanReset() {
        return canReset;
    }

    private static DateTime toDateTime(AbstractInstant instant) {
        if (instant == null) {
            return null;
        }
        return instant.toDateTime();
    }

    public static HostVerificationInfoResponse createVerified(UserVerifiedHost userVerifiedHost) {
        return new HostVerificationInfoResponse(VerificationStatus.VERIFIED, userVerifiedHost.getVerificationType(),
                UinUtil.getUinString(userVerifiedHost.getVerificationUin()), null, null, null,
                userVerifiedHost.getVerificationDate(),
                null, userVerifiedHost.getVerificationType().isCanBeDelegated());
    }

    public static HostVerificationInfoResponse createDelegated(UserVerifiedHost userVerifiedHost, Long delegatedByUserId) {
        return new HostVerificationInfoResponse(VerificationStatus.VERIFIED, userVerifiedHost.getVerificationType(),
                UinUtil.getUinString(userVerifiedHost.getVerificationUin()), null, null, null,
                userVerifiedHost.getVerificationDate(),
                delegatedByUserId, VerificationType.DELEGATED.isCanBeDelegated());
    }

    public static HostVerificationInfoResponse createNeverVerified(UserHostVerificationInfo verificationInfo) {
        return new HostVerificationInfoResponse(null, null,
                UinUtil.getUinString(verificationInfo.getVerificationUin()), null, null, null, null, null, false);
    }

    public static HostVerificationInfoResponse createNotVerified(UserHostVerificationInfo verificationInfo) {
        return new HostVerificationInfoResponse(verificationInfo.getVerificationStatus(),
                verificationInfo.getVerificationType(),
                UinUtil.getUinString(verificationInfo.getVerificationUin()),
                verificationInfo.getNextAttempt(), verificationInfo.getLastAttempt(), verificationInfo.getVerificationFailInfo(),
                null, null, false);
    }

    public static HostVerificationInfoResponse createExpired(UserHostVerificationInfo verificationInfo) {
        return new HostVerificationInfoResponse(VerificationStatus.INTERNAL_ERROR,
                verificationInfo.getVerificationType(),
                UinUtil.getUinString(verificationInfo.getVerificationUin()),
                null, verificationInfo.getLastAttempt(), verificationInfo.getVerificationFailInfo(),
                null, null, false);
    }
}
