package org.brapi.test.BrAPITestServer.repository.geno;

import java.util.List;
import java.util.Optional;

import org.brapi.test.BrAPITestServer.model.entity.geno.CallEntity;
import org.brapi.test.BrAPITestServer.repository.BrAPIRepository;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;

public interface CallRepository extends BrAPIRepository<CallEntity, String> {

	@Query("SELECT COUNT(c) FROM CallEntity c WHERE c.callSet.id = :callSetDbId")
	long countByCallSetDbId(@Param("callSetDbId") String callSetDbId);

	@Query(value = "SELECT c FROM CallEntity c "
			+ "LEFT JOIN FETCH c.callSet cs "
			+ "LEFT JOIN FETCH c.variant v "
			+ "LEFT JOIN FETCH v.variantSet vs",
			countQuery = "SELECT COUNT(c) FROM CallEntity c")
	Page<CallEntity> findAllWithReferences(Pageable pageable);

	@Query(value = "SELECT c FROM CallEntity c "
			+ "LEFT JOIN FETCH c.callSet cs "
			+ "LEFT JOIN FETCH c.variant v "
			+ "LEFT JOIN FETCH v.variantSet vs "
			+ "WHERE (:callSetFilter = false OR cs.id IN :callSetDbIds) "
			+ "AND (:variantFilter = false OR v.id IN :variantDbIds) "
			+ "AND (:variantSetFilter = false OR vs.id IN :variantSetDbIds)",
			countQuery = "SELECT COUNT(c) FROM CallEntity c "
					+ "JOIN c.callSet cs "
					+ "JOIN c.variant v "
					+ "JOIN v.variantSet vs "
					+ "WHERE (:callSetFilter = false OR cs.id IN :callSetDbIds) "
					+ "AND (:variantFilter = false OR v.id IN :variantDbIds) "
					+ "AND (:variantSetFilter = false OR vs.id IN :variantSetDbIds)")
	Page<CallEntity> findByFiltersWithReferences(@Param("callSetDbIds") List<String> callSetDbIds,
			@Param("callSetFilter") boolean callSetFilter,
			@Param("variantDbIds") List<String> variantDbIds,
			@Param("variantFilter") boolean variantFilter,
			@Param("variantSetDbIds") List<String> variantSetDbIds,
			@Param("variantSetFilter") boolean variantSetFilter,
			Pageable pageable);

	@Query("SELECT c FROM CallEntity c "
			+ "JOIN FETCH c.callSet cs "
			+ "JOIN FETCH c.variant v "
			+ "JOIN FETCH v.variantSet vs "
			+ "WHERE cs.id = :callSetDbId "
			+ "AND v.id = :variantDbId "
			+ "AND vs.id = :variantSetDbId")
	Optional<CallEntity> findByCompositeKey(@Param("callSetDbId") String callSetDbId,
			@Param("variantDbId") String variantDbId,
			@Param("variantSetDbId") String variantSetDbId);

}
