package eu.dnetlib.uoanotificationservice.services;

import eu.dnetlib.uoanotificationservice.dao.NotificationDAO;
import eu.dnetlib.uoanotificationservice.dao.UserDAO;
import eu.dnetlib.uoanotificationservice.entities.Notification;
import eu.dnetlib.uoanotificationservice.entities.User;
import eu.dnetlib.uoanotificationservice.exception.ResourceNotFoundException;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;

import java.util.Calendar;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

@Service
public class NotificationService {

    Logger logger = Logger.getLogger(NotificationService.class);

    @Autowired
    private NotificationDAO notificationDAO;

    @Autowired
    private UserDAO userDAO;

    public List<Notification> getAllNotifications() {
        return notificationDAO.findByOrderByDateDesc();
    }

    public List<Notification> getMyNotifications(String userId, String email, String service, List<String> roles) {
        Set<String> services = new HashSet<>();
        services.add(service);
        services.add("all");
        Set<String> groups = new HashSet<>(roles);
        groups.add(email.toLowerCase());
        groups.add("all");
        List<Notification> notifications = notificationDAO.findByUserNotAndServicesInAndGroupsInOrderByDateDesc(userId, services, groups);
        userDAO.findById(userId).ifPresent(user -> notifications.forEach(notification -> {
            notification.setRead(user.getRead().contains(notification.getId()));
        }));
        return notifications;
    }

    public Notification save(Notification notification) {
        return notificationDAO.save(notification);
    }

    public User readNotification(String userId, String id) {
        Notification notification = notificationDAO.findById(id).orElseThrow(() -> new ResourceNotFoundException("Notification has not been found"));
        User user = userDAO.findById(userId).orElse(new User(userId, new HashSet<>()));
        user.getRead().add(notification.getId());
        return userDAO.save(user);
    }

    public User readAllNotifications(List<Notification> notifications, String userId) {
        User user = userDAO.findById(userId).orElse(new User(userId, new HashSet<>()));
        notifications.forEach(notification -> {
            user.getRead().add(notification.getId());
        });
        return userDAO.save(user);
    }

    public void delete(String id) {
        List<User> users = userDAO.findByReadContains(id);
        users.forEach(user -> {
            user.getRead().remove(id);
            userDAO.save(user);
        });
        notificationDAO.delete(id);
    }

    // every day at midnight
    @Scheduled(cron = "0 0 0 1/1 * ?")
    protected void deleteNotifications() {
        logger.info("Deleting notifications that have been created more than a month ago");
        Calendar calendar = Calendar.getInstance();
        calendar.add(Calendar.MONTH, -1);
        List<Notification> notifications = notificationDAO.findByDateBefore(calendar.getTime());
        notifications.forEach(notification -> {
            delete(notification.getId());
        });
    }
}
