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

import java.time.OffsetDateTime;
import java.time.temporal.ChronoUnit;
import java.util.List;
import java.util.Set;

import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.iqser.red.service.persistence.management.v1.processor.entity.annotations.AnnotationEntityId;
import com.iqser.red.service.persistence.management.v1.processor.entity.annotations.ManualResizeRedactionEntity;
import com.iqser.red.service.persistence.management.v1.processor.entity.annotations.RectangleEntity;
import com.iqser.red.service.persistence.management.v1.processor.exception.NotFoundException;
import com.iqser.red.service.persistence.management.v1.processor.service.persistence.repository.annotationentity.ResizeRedactionRepository;
import com.iqser.red.service.persistence.service.v1.api.shared.model.annotations.AnnotationStatus;
import com.iqser.red.service.persistence.service.v1.api.shared.model.annotations.ResizeRedactionRequest;
import com.knecon.fforesight.databasetenantcommons.providers.utils.MagicConverter;

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

@Slf4j
@Service
@RequiredArgsConstructor
public class ResizeRedactionPersistenceService {

    private final ResizeRedactionRepository resizeRedactionRepository;


    @Transactional
    public ManualResizeRedactionEntity insert(String fileId, ResizeRedactionRequest resizeRedactionRequest) {

        ManualResizeRedactionEntity manualResizeRedaction = new ManualResizeRedactionEntity();
        manualResizeRedaction.setId(new AnnotationEntityId(resizeRedactionRequest.getAnnotationId(), fileId));
        BeanUtils.copyProperties(resizeRedactionRequest, manualResizeRedaction);
        manualResizeRedaction.setPositions(MagicConverter.convert(resizeRedactionRequest.getPositions(), RectangleEntity.class));
        manualResizeRedaction.setRequestDate(OffsetDateTime.now());

        if (manualResizeRedaction.getStatus()
                .equals(AnnotationStatus.APPROVED) && (manualResizeRedaction.getUpdateDictionary() == null || !manualResizeRedaction.getUpdateDictionary())) {
            manualResizeRedaction.setProcessedDate(OffsetDateTime.now().truncatedTo(ChronoUnit.MILLIS));
        }

        return resizeRedactionRepository.saveAndFlush(manualResizeRedaction);
    }


    @Transactional
    public void updateSurroundingText(AnnotationEntityId id, String textBefore, String textAfter) {

        resizeRedactionRepository.updateSurroundingText(id, textBefore, textAfter);
    }


    @Transactional
    public void updateStatus(String fileId, String annotationId, AnnotationStatus annotationStatus, Set<String> typeIdsOfModifiedDictionaries) {

        var resizeRedaction = resizeRedactionRepository.findById(new AnnotationEntityId(annotationId, fileId))
                .orElseThrow(() -> new NotFoundException("Unknown file/annotation combination: " + fileId + "/" + annotationId));

        resizeRedaction.setStatus(annotationStatus);
        resizeRedaction.setTypeIdsOfModifiedDictionaries(typeIdsOfModifiedDictionaries);
    }


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

        resizeRedactionRepository.deleteByIdIs(new AnnotationEntityId(annotationId, fileId));
    }


    @Transactional
    public void softDelete(String fileId, String annotationId, OffsetDateTime softDeleteTime) {

        resizeRedactionRepository.updateSoftDelete(new AnnotationEntityId(annotationId, fileId), softDeleteTime);
    }


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

        resizeRedactionRepository.updateSoftDelete(new AnnotationEntityId(annotationId, fileId), null);
    }


    public ManualResizeRedactionEntity findResizeRedaction(String fileId, String annotationId) {

        return resizeRedactionRepository.findByIdAndNotSoftDeleted(new AnnotationEntityId(annotationId, fileId))
                .orElseThrow(() -> new NotFoundException("Unknown file/annotation combination: " + fileId + "/" + annotationId));
    }


    public List<ManualResizeRedactionEntity> findResizeRedactions(String fileId, boolean includeDeletions) {

        return resizeRedactionRepository.findByFileIdIncludeDeletions(fileId, includeDeletions);
    }


    public List<ManualResizeRedactionEntity> findByAnnotationStatusAndValue(AnnotationStatus status, String value) {

        return resizeRedactionRepository.findByStatusAndValue(status, value);
    }


    public void markAsProcessed(String annotationId, String fileId) {

        resizeRedactionRepository.markAsProcessed(new AnnotationEntityId(annotationId, fileId), OffsetDateTime.now().truncatedTo(ChronoUnit.MILLIS));
    }

}
