package ru.yandex.webmaster3.worker.digest;

import java.util.Optional;
import java.util.UUID;

import lombok.AllArgsConstructor;
import org.apache.commons.lang3.tuple.Pair;
import org.joda.time.DateTime;
import org.joda.time.LocalDate;
import org.joda.time.LocalDateTime;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import ru.yandex.webmaster3.core.worker.task.PeriodicTaskState;
import ru.yandex.webmaster3.core.worker.task.PeriodicTaskType;
import ru.yandex.webmaster3.core.worker.task.TaskResult;
import ru.yandex.webmaster3.storage.digest.DigestAcceptance;
import ru.yandex.webmaster3.storage.digest.DigestAcceptanceYDao;
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.NotificationProgress;
import ru.yandex.webmaster3.storage.notifications.dao.NotificationProgressCypressDao;
import ru.yandex.webmaster3.storage.searchquery.importing.dao.YtClickhouseDataLoadYDao;
import ru.yandex.webmaster3.storage.settings.dao.CommonDataStateYDao;
import ru.yandex.webmaster3.storage.ytimport.YtClickhouseDataLoad;
import ru.yandex.webmaster3.storage.ytimport.YtClickhouseDataLoadState;
import ru.yandex.webmaster3.storage.ytimport.YtClickhouseDataLoadType;
import ru.yandex.webmaster3.worker.PeriodicTask;
import ru.yandex.webmaster3.worker.TaskSchedule;

/**
 * @author avhaliullin
 */
@AllArgsConstructor(onConstructor_ = @Autowired)
@Service
public class StartDigestNotificationTask extends PeriodicTask<PeriodicTaskState> {
    private static final Logger log = LoggerFactory.getLogger(StartDigestNotificationTask.class);

    private final CommonDataStateYDao commonDataStateYDao;
    private final YtClickhouseDataLoadYDao ytClickhouseDataLoadYDao;
    private final NotificationProgressCypressDao digestNotificationProgressCypressDao;
    private final DigestMessagesCHDao digestMessagesCHDao;
    private final DigestAcceptanceYDao digestAcceptanceYDao;
    private final DigestDevSenderService digestDevSenderService;

    @Override
    public Result run(UUID runId) throws Exception {
        LocalDate lastSentDigest = Optional.ofNullable(commonDataStateYDao.getValue(CommonDataType.LAST_SENT_DIGEST_DATE))
                .map(CommonDataState::getValue)
                .map(LocalDate::parse)
                .orElse(null);
        YtClickhouseDataLoad tableDataInfo = ytClickhouseDataLoadYDao.load(YtClickhouseDataLoadType.DIGEST_MESSAGES);
        if (tableDataInfo != null && tableDataInfo.getState() == YtClickhouseDataLoadState.DONE) {
            LocalDate currentTableDate = tableDataInfo.getDateTo();
            Optional<DigestAcceptance> acceptance = digestAcceptanceYDao.getAcceptanceByDate(currentTableDate);

            if (acceptance.isPresent() && acceptance.get().getApprove() && checkTimeToSend()){
                if (lastSentDigest == null || lastSentDigest.isBefore(currentTableDate)) {
                    UUID notificationId = DigestNotificationUtil.getNotificationId(currentTableDate);
                    log.info("Found loaded digest {} data for date {}", notificationId, currentTableDate);

                    Pair<NotificationProgress, Integer> progressAndVersion = digestNotificationProgressCypressDao.getRecordIfExists(notificationId);
                    if (progressAndVersion == null) {
                        int targetsCount = digestMessagesCHDao.countMessages(currentTableDate);
                        log.info("Digest {} for {} contains {} targets to send", notificationId, currentTableDate, targetsCount);

                        int chunkSize = Math.min(targetsCount, 1000);
                        digestNotificationProgressCypressDao.createRecord(
                                notificationId,
                                NotificationProgress.createInitial(chunkSize, targetsCount, 0)
                        );
                        log.info("Cypress record created for digest {} {}", notificationId, currentTableDate);
                    }

                    digestAcceptanceYDao.markAsSent(currentTableDate);
                    commonDataStateYDao.update(new CommonDataState(CommonDataType.LAST_SENT_DIGEST_DATE, currentTableDate.toString(), DateTime.now()));
                }
            } else {
                if (acceptance.isEmpty()){
                    digestDevSenderService.sendEmailsToApprove(currentTableDate);
                    digestAcceptanceYDao.insert(new DigestAcceptance(currentTableDate,false,false));
                }
            }
        }

        return new Result(TaskResult.SUCCESS);
    }

    private boolean checkTimeToSend(){
        return LocalDateTime.now().getHourOfDay() >= 7 && LocalDateTime.now().getHourOfDay() < 18;
    }

    @Override
    public PeriodicTaskType getType() {
        return PeriodicTaskType.START_DIGEST_NOTIFICATION;
    }

    @Override
    public TaskSchedule getSchedule() {
        return TaskSchedule.startByCron("0 0/10 * * * *");
    }
}
