package com.iqser.red.service.persistence.management.v1.processor.service.persistence.annotations;

import java.time.OffsetDateTime;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import jakarta.transaction.Transactional;

import org.springframework.dao.EmptyResultDataAccessException;
import org.springframework.stereotype.Service;

import com.iqser.red.service.persistence.management.v1.processor.entity.annotations.CommentEntity;
import com.iqser.red.service.persistence.management.v1.processor.exception.NotFoundException;
import com.iqser.red.service.persistence.management.v1.processor.service.persistence.repository.CommentRepository;

import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;

@Slf4j
@Service
@RequiredArgsConstructor
public class CommentPersistenceService {

    private final CommentRepository commentRepository;


    public CommentEntity insert(CommentEntity comment) {

        return commentRepository.saveAndFlush(comment);

    }


    public CommentEntity findComment(long commentId) {

        return commentRepository.findById(commentId).orElseThrow(() -> new NotFoundException("Comment with id: " + commentId + " not found"));
    }


    public Map<String, List<CommentEntity>> findCommentsByFileID(String fileId, boolean includeDeletions) {

        List<CommentEntity> comments = commentRepository.findByFileId(fileId, includeDeletions);

        return comments.stream().sorted(Comparator.comparing(CommentEntity::getDate)).collect(Collectors.groupingBy(CommentEntity::getAnnotationId));
    }


    public boolean fileHasComments(String fileId) {

        return commentRepository.existsByFileIdAndSoftDeletedTimeIsNull(fileId);
    }


    @Transactional
    public void hardDelete(long commentId) {

        try {
            commentRepository.deleteById(commentId);
        } catch (EmptyResultDataAccessException e) {
            log.info("Ignored silently during deletion: {}", e.getMessage());
        }
    }


    @Transactional
    public void hardDelete(String fileId, String annotationId) {

        List<CommentEntity> comments = findCommentsByAnnotationId(fileId, annotationId, true);
        commentRepository.deleteAllInBatch(comments);
    }


    public List<CommentEntity> findCommentsByAnnotationId(String fileId, String annotationId, boolean includeDeletions) {

        return commentRepository.findByFileIdAndAnnotationId(fileId, annotationId, includeDeletions);
    }


    @Transactional
    public void softDelete(long commentId, OffsetDateTime softDeletedTime) {

        commentRepository.updateSoftDelete(commentId, softDeletedTime);
    }


    @Transactional
    public void undelete(long commentId) {

        commentRepository.updateSoftDelete(commentId, null);
    }

}
