package ru.ulstu.paper.service;

import com.google.common.collect.ImmutableMap;
import org.springframework.stereotype.Service;
import ru.ulstu.core.util.DateUtils;
import ru.ulstu.paper.model.Paper;
import ru.ulstu.user.service.MailService;

import java.util.Date;
import java.util.List;
import java.util.Map;

@Service
public class PaperNotificationService {
    private final static int DAYS_TO_DEADLINE_NOTIFICATION = 7;
    private final static String TEMPLATE_DEADLINE = "paperDeadlineNotification";
    private final static String TEMPLATE_CREATE = "paperCreateNotification";
    private final static String TEMPLATE_STATUS_CHANGED = "paperStatusChangeNotification";
    private final static String TEMPLATE_FAILED = "paperFailedNotification";

    private final static String TITLE_DEADLINE = "Приближается дедлайн статьи";
    private final static String TITLE_CREATE = "Создана статья";
    private final static String TITLE_STATUS_CHANGED = "Изменился статус статьи";
    private final static String TITLE_FAILED = "Статья провалена";


    private final MailService mailService;

    public PaperNotificationService(MailService mailService) {
        this.mailService = mailService;
    }

    public void sendDeadlineNotifications(List<Paper> papers, boolean isDeadlineBeforeWeek) {
        Date now = DateUtils.addDays(new Date(), DAYS_TO_DEADLINE_NOTIFICATION);
        papers
                .stream()
                .filter(paper -> needToSendDeadlineNotification(paper, now, isDeadlineBeforeWeek))
                .forEach(paper -> sendMessageDeadline(paper));
    }

    private boolean needToSendDeadlineNotification(Paper paper, Date compareDate, boolean isDeadlineBeforeWeek) {
        return (paper.getNextDeadline().isPresent())
                && (compareDate.before(paper.getNextDeadline().get().getDate()) && isDeadlineBeforeWeek
                || compareDate.after(paper.getNextDeadline().get().getDate()) && !isDeadlineBeforeWeek)
                && paper.getNextDeadline().get().getDate().after(new Date());
    }

    private void sendMessageDeadline(Paper paper) {
        Map<String, Object> variables = ImmutableMap.of("paper", paper);
        sendForAllAuhtors(variables, paper, TEMPLATE_DEADLINE, TITLE_DEADLINE);
    }

    public void sendCreateNotification(Paper paper) {
        Map<String, Object> variables = ImmutableMap.of("paper", paper);
        sendForAllAuhtors(variables, paper, TEMPLATE_CREATE, TITLE_CREATE);
    }

    public void statusChangeNotification(Paper paper, Paper.PaperStatus oldStatus) {
        Map<String, Object> variables = ImmutableMap.of("paper", paper, "oldStatus", oldStatus);
        sendForAllAuhtors(variables, paper, TEMPLATE_STATUS_CHANGED, TITLE_STATUS_CHANGED);
    }

    public void sendFailedNotification(Paper paper, Paper.PaperStatus oldStatus) {
        Map<String, Object> variables = ImmutableMap.of("paper", paper, "oldStatus", oldStatus);
        sendForAllAuhtors(variables, paper, TEMPLATE_FAILED, TITLE_FAILED);
    }

    private void sendForAllAuhtors(Map<String, Object> variables, Paper paper, String template, String title) {
        paper.getAuthors().forEach(author -> mailService.sendEmailFromTemplate(variables, author, template, title));
    }
}
