package com.agendaestudantil.servico; import com.agendaestudantil.entidade.Evento; import com.agendaestudantil.entidade.Notificacao; import com.agendaestudantil.entidade.Tarefa; import com.agendaestudantil.repositorio.EventoRepositorio; import com.agendaestudantil.repositorio.NotificacaoRepositorio; import com.agendaestudantil.repositorio.TarefaRepositorio; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.scheduling.annotation.Scheduled; import org.springframework.stereotype.Service; import java.time.LocalDate; import java.time.LocalDateTime; import java.time.temporal.ChronoUnit; import java.util.List; @Service public class NotificacaoAgendadorServico { private static final Logger log = LoggerFactory.getLogger(NotificacaoAgendadorServico.class); private final TarefaRepositorio tarefaRepositorio; private final EventoRepositorio eventoRepositorio; private final NotificacaoRepositorio notificacaoRepositorio; public NotificacaoAgendadorServico(TarefaRepositorio tarefaRepositorio, EventoRepositorio eventoRepositorio, NotificacaoRepositorio notificacaoRepositorio) { this.tarefaRepositorio = tarefaRepositorio; this.eventoRepositorio = eventoRepositorio; this.notificacaoRepositorio = notificacaoRepositorio; } @Scheduled(fixedRate = 3600000) public void gerarNotificacoes() { log.debug("Iniciando geracao de notificacoes"); LocalDate hoje = LocalDate.now(); LocalDate ontem = hoje.minusDays(1); LocalDate tresDiasDepois = hoje.plusDays(3); List tarefas = tarefaRepositorio.findTarefasNaoConcluidasComDataEntre(ontem, tresDiasDepois); for (Tarefa tarefa : tarefas) { if (tarefa.getStatus() == Tarefa.StatusTarefa.CONCLUIDA) { continue; } LocalDate dataEntrega = tarefa.getDataEntrega(); if (dataEntrega == null) { continue; } long diasAteEntrega = ChronoUnit.DAYS.between(hoje, dataEntrega); if (dataEntrega.isBefore(hoje)) { if (!tarefa.getStatus().equals(Tarefa.StatusTarefa.ATRASADA)) { tarefa.setStatus(Tarefa.StatusTarefa.ATRASADA); tarefaRepositorio.save(tarefa); } if (!notificacaoRepositorio.existsByEstudanteIdAndReferenciaIdAndTipo( tarefa.getEstudanteId(), tarefa.getId(), Notificacao.TipoNotificacao.TAREFA_ATRASADA)) { criarNotificacao(tarefa.getEstudanteId(), tarefa.getId(), "Tarefa atrasada: " + tarefa.getTitulo(), "A tarefa '" + tarefa.getTitulo() + "' esta atrasada desde " + dataEntrega, Notificacao.TipoNotificacao.TAREFA_ATRASADA, Notificacao.TipoReferencia.TAREFA); } } else if (diasAteEntrega == 0 || diasAteEntrega == 1 || diasAteEntrega == 2 || diasAteEntrega == 3) { boolean enviarNotificacao = false; if (diasAteEntrega == 0 || diasAteEntrega == 1) { enviarNotificacao = true; } else if (diasAteEntrega == 2 || diasAteEntrega == 3) { if (tarefa.getPrioridade() == Tarefa.Prioridade.ALTA || tarefa.getPrioridade() == Tarefa.Prioridade.URGENTE) { enviarNotificacao = true; } } if (enviarNotificacao) { boolean jaNotificouHoje = notificacaoRepositorio.findByEstudanteIdAndReferenciaIdAndTipo( tarefa.getEstudanteId(), tarefa.getId(), Notificacao.TipoNotificacao.PRAZO_PROXIMO) .stream() .anyMatch(n -> n.getDataGeracao().toLocalDate().equals(hoje)); if (!jaNotificouHoje) { String prazo = diasAteEntrega == 0 ? "hoje" : (diasAteEntrega == 1 ? "amanha" : "em " + diasAteEntrega + " dias"); criarNotificacao(tarefa.getEstudanteId(), tarefa.getId(), "Tarefa com prazo proximo: " + tarefa.getTitulo(), "A tarefa '" + tarefa.getTitulo() + "' vence " + prazo, Notificacao.TipoNotificacao.PRAZO_PROXIMO, Notificacao.TipoReferencia.TAREFA); } } } } LocalDateTime agora = LocalDateTime.now(); LocalDateTime em24Horas = agora.plusHours(24); List eventos = eventoRepositorio.findEventosNasProximas24h(agora, em24Horas); for (Evento evento : eventos) { if (evento.getDataHora() == null) { continue; } if (!notificacaoRepositorio.existsByEstudanteIdAndReferenciaIdAndTipo( evento.getEstudanteId(), evento.getId(), Notificacao.TipoNotificacao.EVENTO_PROXIMO)) { criarNotificacao(evento.getEstudanteId(), evento.getId(), "Evento nas proximas 24h: " + evento.getTitulo(), "O evento '" + evento.getTitulo() + "' sera em " + evento.getDataHora(), Notificacao.TipoNotificacao.EVENTO_PROXIMO, Notificacao.TipoReferencia.EVENTO); } } log.debug("Geracao de notificacoes concluida"); } private void criarNotificacao(String estudanteId, String referenciaId, String titulo, String mensagem, Notificacao.TipoNotificacao tipo, Notificacao.TipoReferencia tipoReferencia) { Notificacao notif = new Notificacao(); notif.setEstudanteId(estudanteId); notif.setReferenciaId(referenciaId); notif.setTitulo(titulo); notif.setMensagem(mensagem); notif.setTipo(tipo); notif.setTipoReferencia(tipoReferencia); notif.setLida(false); notif.setDataGeracao(LocalDateTime.now()); notificacaoRepositorio.save(notif); log.debug("Notificacao criada para estudante {}", estudanteId); } }