package com.geosegbar.infra.instrument_graph_customization_properties.persistence.jpa;

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

import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.jpa.repository.QueryHints;
import org.springframework.data.repository.query.Param;
import org.springframework.stereotype.Repository;

import com.geosegbar.common.enums.CustomizationTypeEnum;
import com.geosegbar.common.enums.LimitValueTypeEnum;
import com.geosegbar.common.enums.LineTypeEnum;
import com.geosegbar.entities.InstrumentGraphCustomizationPropertiesEntity;

import jakarta.persistence.QueryHint;

@Repository
public interface InstrumentGraphCustomizationPropertiesRepository extends JpaRepository<InstrumentGraphCustomizationPropertiesEntity, Long> {

    @QueryHints(
            @QueryHint(name = "org.hibernate.cacheable", value = "true"))
    @Query("SELECT DISTINCT p FROM InstrumentGraphCustomizationPropertiesEntity p "
            + "LEFT JOIN FETCH p.output o "
            + "LEFT JOIN FETCH o.measurementUnit "
            + "LEFT JOIN FETCH p.statisticalLimit sl "
            + "LEFT JOIN FETCH sl.output slo "
            + "LEFT JOIN FETCH slo.measurementUnit "
            + "LEFT JOIN FETCH p.deterministicLimit dl "
            + "LEFT JOIN FETCH dl.output dlo "
            + "LEFT JOIN FETCH dlo.measurementUnit "
            + "LEFT JOIN FETCH p.instrument i "
            + "LEFT JOIN FETCH p.constant c "
            + "LEFT JOIN FETCH c.measurementUnit "
            + "WHERE p.pattern.id = :patternId")
    List<InstrumentGraphCustomizationPropertiesEntity> findByPatternId(@Param("patternId") Long patternId);

    List<InstrumentGraphCustomizationPropertiesEntity> findByConstantId(Long constantId);

    List<InstrumentGraphCustomizationPropertiesEntity> findByCustomizationType(CustomizationTypeEnum customizationType);

    List<InstrumentGraphCustomizationPropertiesEntity> findByPatternIdAndCustomizationType(
            Long patternId, CustomizationTypeEnum customizationType);

    Optional<InstrumentGraphCustomizationPropertiesEntity> findByNameAndPatternId(String name, Long patternId);

    List<InstrumentGraphCustomizationPropertiesEntity> findByOutputId(Long outputId);

    List<InstrumentGraphCustomizationPropertiesEntity> findByStatisticalLimitId(Long statisticalLimitId);

    List<InstrumentGraphCustomizationPropertiesEntity> findByDeterministicLimitId(Long deterministicLimitId);

    List<InstrumentGraphCustomizationPropertiesEntity> findByInstrumentId(Long instrumentId);

    List<InstrumentGraphCustomizationPropertiesEntity> findByLabelEnableTrue();

    List<InstrumentGraphCustomizationPropertiesEntity> findByIsPrimaryOrdinateTrue();

    List<InstrumentGraphCustomizationPropertiesEntity> findByIsPrimaryOrdinateFalse();

    List<InstrumentGraphCustomizationPropertiesEntity> findByFillColor(String fillColor);

    List<InstrumentGraphCustomizationPropertiesEntity> findByLineType(LineTypeEnum lineType);

    boolean existsByNameAndPatternId(String name, Long patternId);

    @Query("SELECT p FROM InstrumentGraphCustomizationPropertiesEntity p "
            + "WHERE p.pattern.instrument.id = :instrumentId")
    List<InstrumentGraphCustomizationPropertiesEntity> findByPatternInstrumentId(@Param("instrumentId") Long instrumentId);

    void deleteByPatternId(Long patternId);

    List<InstrumentGraphCustomizationPropertiesEntity> findByPatternIdAndStatisticalLimitIdAndLimitValueType(
            Long patternId, Long statisticalLimitId, LimitValueTypeEnum limitValueType);

    List<InstrumentGraphCustomizationPropertiesEntity> findByPatternIdAndDeterministicLimitIdAndLimitValueType(
            Long patternId, Long deterministicLimitId, LimitValueTypeEnum limitValueType);

    @Query("SELECT p FROM InstrumentGraphCustomizationPropertiesEntity p "
            + "WHERE p.pattern.id = :patternId AND p.customizationType = 'STATISTICAL_LIMIT' "
            + "AND p.statisticalLimit.id = :limitId")
    List<InstrumentGraphCustomizationPropertiesEntity> findStatisticalLimitPropertiesByPatternAndLimit(
            @Param("patternId") Long patternId, @Param("limitId") Long limitId);

    @Query("SELECT p FROM InstrumentGraphCustomizationPropertiesEntity p "
            + "WHERE p.pattern.id = :patternId AND p.customizationType = 'DETERMINISTIC_LIMIT' "
            + "AND p.deterministicLimit.id = :limitId")
    List<InstrumentGraphCustomizationPropertiesEntity> findDeterministicLimitPropertiesByPatternAndLimit(
            @Param("patternId") Long patternId, @Param("limitId") Long limitId);
}
