package ru.yandex.webmaster3.worker.notifications.sending;

import java.util.EnumSet;
import java.util.List;
import java.util.Optional;
import java.util.Set;
import java.util.UUID;

import org.joda.time.Duration;
import org.joda.time.LocalDate;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;

import ru.yandex.webmaster3.core.data.WebmasterHostId;
import ru.yandex.webmaster3.storage.util.ydb.exception.WebmasterYdbException;
import ru.yandex.webmaster3.storage.digest.DigestMessage;
import ru.yandex.webmaster3.storage.digest.DigestMessagesCHDao;
import ru.yandex.webmaster3.storage.host.CommonDataState;
import ru.yandex.webmaster3.storage.host.CommonDataType;
import ru.yandex.webmaster3.storage.notifications.NotificationChannel;
import ru.yandex.webmaster3.storage.notifications.NotificationRecListId;
import ru.yandex.webmaster3.storage.settings.dao.CommonDataStateYDao;
import ru.yandex.webmaster3.storage.util.clickhouse2.ClickhouseException;
import ru.yandex.webmaster3.worker.digest.DigestNotificationService;
import ru.yandex.webmaster3.worker.digest.DigestNotificationUtil;

/**
 * @author avhaliullin
 */
public class SendDigestTask extends AbstractSendNotificationsTask<LocalDate, DigestMessage> {
    private static final Logger log = LoggerFactory.getLogger(SendDigestTask.class);

    private static final Duration TTL = Duration.standardDays(7);

    @Autowired
    private CommonDataStateYDao commonDataStateYDao;
    @Autowired
    private DigestMessagesCHDao digestMessagesCHDao;
    @Autowired
    private DigestNotificationService digestNotificationService;

    public SendDigestTask() {
        super("digest");
    }

    @Override
    protected boolean sendToTargetByChannel(LocalDate date, DigestMessage digestMessage, NotificationChannel channel) {
        return digestNotificationService.sendDigest(digestMessage, digestMessage.getEmail());
    }

    @Override
    protected List<DigestMessage> listTargets(NotificationRecListId listId, int fromOffset, int limit) throws ClickhouseException {
        return digestMessagesCHDao.getMessages(digestDateFromNotificationId(listId.getNotificationId()), fromOffset, limit);
    }

    @Override
    protected LocalDate getNotificationMarkStarted(UUID notificationId, int revisionId)  {
        return digestDateFromNotificationId(notificationId);
    }

    @Override
    protected boolean canBeDeleted(UUID notificationId) {
        LocalDate lastSentDigest = Optional.ofNullable(commonDataStateYDao.getValue(CommonDataType.LAST_SENT_DIGEST_DATE))
                .map(CommonDataState::getValue)
                .map(LocalDate::parse)
                .orElse(null);
        LocalDate digestDate = DigestNotificationUtil.getDigestDate(notificationId);
        // lastSentDigest >= digestDate
        return lastSentDigest != null && !lastSentDigest.isBefore(digestDate);
    }

    @Override
    protected UUID getRecListId(LocalDate date) {
        return DigestNotificationUtil.getNotificationId(date);
    }

    @Override
    protected void finishNotification(UUID notificationId)  {
    }

    private static LocalDate digestDateFromNotificationId(UUID notificationId) {
        return DigestNotificationUtil.getDigestDate(notificationId);
    }

    @Override
    protected String extractTargetId(DigestMessage target) {
        return targetId(target.getUserId(), target.getHostId());
    }

    @Override
    protected Set<NotificationChannel> extractTargetChannels(DigestMessage target) {
        return EnumSet.of(NotificationChannel.EMAIL);
    }

    private static String targetId(long userId, WebmasterHostId hostId) {
        return String.format("%d;%s", userId, hostId.toString());
    }
}
