package ru.soune.nocopy.scheduler;

import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import ru.soune.nocopy.entity.monitoring.FileMonitoringEntity;
import ru.soune.nocopy.entity.notification.NotificationType;
import ru.soune.nocopy.repository.FileMonitoringRepository;
import ru.soune.nocopy.service.monitoring.MonitoringSearchService;
import ru.soune.nocopy.service.notification.NotificationService;

import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;

@Slf4j
@Component
@RequiredArgsConstructor
public class MonitoringScheduler {

    private final FileMonitoringRepository monitoringRepository;

    private final MonitoringSearchService monitoringSearchService;

    private final NotificationService notificationService;

    @Scheduled(cron = "0 1 2 * * *", zone = "Europe/Moscow")
    @Transactional
    public void processScheduledMonitoring() {
        log.info("Starting scheduled monitoring check at 02:01 MSK");

        LocalDateTime now = LocalDateTime.now();
        List<FileMonitoringEntity> readyForRun = monitoringRepository.findReadyForRun(now);
        Map<Long, List<FileMonitoringEntity>> groupingFilesMonitoring = readyForRun.stream()
                .collect(Collectors.groupingBy(FileMonitoringEntity::getUserId));

        log.info("Found {} files ready for monitoring", readyForRun.size());

        //TODO check tokens for apply
        for (FileMonitoringEntity monitoring : readyForRun) {
            try {
                monitoringSearchService.processFileSearch(monitoring);
                log.info("Successfully queued search for file: {}", monitoring.getFile().getId());
            } catch (Exception e) {
                log.error("Failed to process monitoring for file: {}", monitoring.getFile().getId(), e);
                monitoring.setLastRunStatus("ERROR: " + e.getMessage());
                monitoringRepository.save(monitoring);
            }
        }

        Set<Long> usersForNotifications = groupingFilesMonitoring.keySet();
        for (Long userId : usersForNotifications) {
            notificationService.addNotification(NotificationType.MONITORING_RESULT, userId);
        }
    }
}