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.ManualRecategorizationEntity;
import com.iqser.red.service.persistence.management.v1.processor.exception.NotFoundException;
import com.iqser.red.service.persistence.management.v1.processor.service.persistence.repository.annotationentity.RecategorizationRepository;
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.RecategorizationRequest;

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

@Slf4j
@Service
@RequiredArgsConstructor
public class RecategorizationPersistenceService {

    private final RecategorizationRepository recategorizationRepository;


    public void insert(String fileId, RecategorizationRequest recategorizationRequest) {

        ManualRecategorizationEntity manualImageRecategorization = new ManualRecategorizationEntity();
        manualImageRecategorization.setId(new AnnotationEntityId(recategorizationRequest.getAnnotationId(), fileId));
        BeanUtils.copyProperties(recategorizationRequest, manualImageRecategorization);
        manualImageRecategorization.setRequestDate(OffsetDateTime.now());
        manualImageRecategorization.setTypeId(recategorizationRequest.getDossierTemplateTypeId());
        recategorizationRepository.saveAndFlush(manualImageRecategorization);

    }


    @Transactional
    public void updateStatus(String fileId, String annotationId, AnnotationStatus annotationStatus) {

        recategorizationRepository.updateStatus(new AnnotationEntityId(annotationId, fileId), annotationStatus);
    }


    @Transactional
    public void updateStatus(String fileId,
                             String annotationId,
                             AnnotationStatus annotationStatus,
                             boolean modifiedDictionary,
                             Set<String> typeIdsOfDictionaryWithAdd,
                             Set<String> typeIdsOfDictionaryWithDelete) {

        ManualRecategorizationEntity addRedaction = recategorizationRepository.findById(new AnnotationEntityId(annotationId, fileId))
                .orElseThrow(() -> new NotFoundException("Unknown file/annotation combination: " + fileId + "/" + annotationId));

        addRedaction.setStatus(annotationStatus);
        addRedaction.setAddToDictionary(modifiedDictionary);
        addRedaction.setTypeIdsOfDictionariesWithAdd(typeIdsOfDictionaryWithAdd);
        addRedaction.setTypeIdsOfDictionariesWithDelete(typeIdsOfDictionaryWithDelete);

        recategorizationRepository.saveAndFlush(addRedaction);
    }


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

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


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

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


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

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


    public ManualRecategorizationEntity findRecategorization(String fileId, String annotationId) {

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


    public List<ManualRecategorizationEntity> findRecategorizations(String fileId, boolean includeDeletions) {

        return recategorizationRepository.findByFileIdIncludeDeletions(fileId, includeDeletions);

    }


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

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

}
