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

import java.time.OffsetDateTime;
import java.util.List;

import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Modifying;
import org.springframework.data.jpa.repository.Query;

import com.iqser.red.service.persistence.management.v1.processor.entity.dossier.DossierEntity;
import com.iqser.red.service.persistence.management.v1.processor.service.persistence.projection.DossierCountByStatusProjection;

public interface DossierRepository extends JpaRepository<DossierEntity, String> {

    @Query("select d.id from DossierEntity  d where d.lastUpdated > :since")
    List<String> findDossierChangeByLastUpdatedIsAfter(OffsetDateTime since);


    @Modifying
    @Query("update DossierEntity d set d.softDeletedTime = null, d.lastUpdated = :lastUpdated where d.id = :dossierId" + " and d.hardDeletedTime is null")
    int undelete(String dossierId, OffsetDateTime lastUpdated);


    @Modifying
    @Query("update DossierEntity d set d.softDeletedTime = :softDeletedTime, d.lastUpdated = :lastUpdated where d.id = :dossierId")
    void markDossierAsDeleted(String dossierId, OffsetDateTime softDeletedTime, OffsetDateTime lastUpdated);


    @Modifying
    @Query("update DossierEntity d set d.hardDeletedTime = :hardDeletedTime, d.lastUpdated = :lastUpdated, " + "d.softDeletedTime = " + "case " + "when d.softDeletedTime is null then :hardDeletedTime " + "else d.softDeletedTime " + "end " + "where d.id = :dossierId")
    void hardDelete(String dossierId, OffsetDateTime hardDeletedTime, OffsetDateTime lastUpdated);


    @Modifying
    @Query("update DossierEntity d set d.archivedTime = :archiveTime, d.lastUpdated = :archiveTime where d.id = :dossierId ")
    void archiveDossier(String dossierId, OffsetDateTime archiveTime);


    @Modifying
    @Query("update DossierEntity d set d.lastUpdated = :lastUpdated, d.archivedTime = null where d.id = :dossierId")
    int unarchiveDossier(String dossierId, OffsetDateTime lastUpdated);


    @Query("select count(d) from DossierEntity d where d.archivedTime is not null and d.softDeletedTime is null and d.hardDeletedTime is null and d.dossierTemplateId = :dossierTemplateId")
    int countArchived(String dossierTemplateId);


    @Query("select count(d) from DossierEntity d where d.hardDeletedTime is null and d.softDeletedTime is not null and d.dossierTemplateId = :dossierTemplateId")
    int countSofDeleted(String dossierTemplateId);


    @Query("select count(d) from DossierEntity d where d.archivedTime is null and d.softDeletedTime is null and d.hardDeletedTime is null and d.dossierTemplateId = :dossierTemplateId")
    int countActive(String dossierTemplateId);


    @Query("select d.dossierStatusId as dossierStatusId, count(d) as count from DossierEntity d where d.archivedTime is null and d.softDeletedTime is null and d.hardDeletedTime is null and d.dossierTemplateId = :dossierTemplateId group by d.dossierStatusId")
    List<DossierCountByStatusProjection> countByDossierStatus(String dossierTemplateId);


    @Query("select d.id from DossierEntity d where d.dossierTemplateId = :dossierTemplateId and d.archivedTime is null and d.softDeletedTime is null and d.hardDeletedTime is null")
    List<String> findActiveDossierIdsForTemplate(String dossierTemplateId);


    @Query("select d from DossierEntity d where d.dossierTemplateId = :dossierTemplateId")
    List<DossierEntity> findByDossierTemplateId(String dossierTemplateId);


    @Modifying
    @Query("update DossierEntity d set d.watermarkId = null where d.watermarkId = :watermarkId")
    int countDeleteWatermark(long watermarkId);


    @Modifying
    @Query("update DossierEntity d set d.previewWatermarkId = null where d.previewWatermarkId = :previewWatermarkId")
    int countDeletePreviewWatermark(long previewWatermarkId);


    @Query("select count(d) from DossierEntity d where d.watermarkId = :watermarkId or d.previewWatermarkId = :watermarkId")
    int countDossiersWithWatermarkInUse(long watermarkId);

}
