package ru.soune.nocopy.service.search;

import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import ru.soune.nocopy.dto.search.GlobalSearchStartRequest;
import ru.soune.nocopy.entity.file.FileEntity;
import ru.soune.nocopy.entity.file.FileType;
import ru.soune.nocopy.entity.monitoring.FileMonitoringEntity;
import ru.soune.nocopy.entity.search.GlobalSearchTask;
import ru.soune.nocopy.entity.search.SearchStatus;
import ru.soune.nocopy.repository.FileEntityRepository;
import ru.soune.nocopy.repository.FileMonitoringRepository;
import ru.soune.nocopy.repository.GlobalSearchTaskRepository;
import ru.soune.nocopy.service.file.FileEntityService;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;

@Slf4j
@Service
@RequiredArgsConstructor
public class GlobalSearchService {

    private final FileEntityRepository fileEntityRepository;

    private final FileMonitoringRepository fileMonitoringRepository;

    private final GlobalSearchTaskRepository globalSearchTaskRepository;

    private final GlobalSearchAsyncProcessor asyncProcessor;

    private final FileEntityService fileEntityService;

    @Transactional
    public String startSearch(GlobalSearchStartRequest request, Long userId, List<FileEntity> filesToProcess) {
        GlobalSearchTask task = new GlobalSearchTask();
        task.setUserId(userId);
        task.setSearchType(request.getSearchType());
        task.setStatus(SearchStatus.PROCESSING.name());
        task.setTotalFiles(filesToProcess.size());
        task.setProcessedFiles(0);
        task.setCreatedAt(LocalDateTime.now());

        GlobalSearchTask save = globalSearchTaskRepository.save(task);

        List<String> fileIds = filesToProcess.stream().map(FileEntity::getId).toList();

        asyncProcessor.processFilesAsync(save.getTaskId(), fileIds, userId);

        return save.getTaskId();
    }

    public List<FileEntity> getFilesToProcess(GlobalSearchStartRequest request, Long userId) {
        if ("monitoring".equals(request.getSearchType())) {
            List<FileMonitoringEntity> monitoringFiles =
                    fileMonitoringRepository.findByUserIdAndIsActiveTrue(userId);

            return monitoringFiles.isEmpty() ? new ArrayList<>(): monitoringFiles.stream()
                    .map(FileMonitoringEntity::getFile)
                    .toList();
        } else {
            List<String> fileIds = request.getFileIds().isEmpty() ? fileEntityService.getAllUserFiles(userId)
                    .stream()
                    .filter(f -> f.getMimeType().equals(FileType.IMAGE.getDisplayName()))
                    .map(FileEntity::getId)
                    .toList(): request.getFileIds();

            return fileEntityRepository.findAllById(fileIds);
        }
    }
}
