package incheon.ags.mrb.style.mapper;

import incheon.ags.mrb.style.vo.RecipeLayerStyleVO;
import incheon.ags.mrb.style.web.dto.CategoryValueDTO;
import incheon.ags.mrb.style.web.dto.RecipeStyleSearchDTO;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.SelectProvider;

import java.util.List;

/**
 * 레시피 레이어 스타일 Mapper 인터페이스
 * - 레시피 레이어 스타일 정보 관리 (CRUD)
 * - lyr_style 테이블 매핑
 */
@org.egovframe.rte.psl.dataaccess.mapper.Mapper
@incheon.com.config.annotation.MainDB
public interface RecipeLayerStyleMapper {

        /**
         * 레시피 레이어 스타일 목록 조회
         * 
         * @param searchDTO 검색 조건
         * @param userId    사용자 ID
         * @return 레시피 레이어 스타일 목록
         */
        List<RecipeLayerStyleVO> selectServerStyleList(@Param("searchDTO") RecipeStyleSearchDTO searchDTO,
                        @Param("userId") String userId) throws Exception;

        /**
         * 레시피 레이어 스타일 전체 개수 조회
         * 
         * @param searchDTO 검색 조건
         * @param userId    사용자 ID
         * @return 총 개수
         */
        int selectServerStyleListCount(@Param("searchDTO") RecipeStyleSearchDTO searchDTO,
                        @Param("userId") String userId)
                        throws Exception;

        /**
         * 레시피 레이어 스타일 상세 조회
         * 
         * @param styleId 스타일 ID
         * @return 레시피 레이어 스타일 정보
         */
        RecipeLayerStyleVO selectServerStyle(@Param("styleId") Long styleId);

        /**
         * 레시피 레이어 스타일 상세 배치 조회
         *
         * @param styleIds 스타일 ID 목록
         * @return 레시피 레이어 스타일 정보 목록
         */
        List<RecipeLayerStyleVO> selectServerStyles(@Param("styleIds") List<Long> styleIds);

        /**
         * 레시피 레이어 스타일 등록
         * 
         * @param serverStyleVO 레시피 레이어 스타일 정보
         * @return 등록 결과
         */
        int insertServerStyle(RecipeLayerStyleVO serverStyleVO);

        /**
         * 레시피 레이어 스타일 등록
         * 
         * @param serverStyleVO 레시피 레이어 스타일 정보
         * @return 등록 결과
         */
        int insertServerStyleOnConflict(RecipeLayerStyleVO serverStyleVO);

        /**
         * 레시피 레이어 스타일 수정
         * 
         * @param serverStyleVO 레시피 레이어 스타일 정보
         * @param userId        사용자 ID
         * @return 수정 결과
         */
        int updateServerStyle(@Param("serverStyleVO") RecipeLayerStyleVO serverStyleVO, @Param("userId") String userId)
                        throws Exception;

        /**
         * 레시피 레이어 스타일 삭제
         * 
         * @param styleId 스타일 ID
         * @param userId  사용자 ID
         * @return 삭제 결과
         */
        int deleteServerStyle(@Param("styleId") Long styleId, @Param("userId") String userId) throws Exception;

        /**
         * 레시피 레이어 스타일 다중 삭제
         * 
         * @param styleIds 스타일 ID 목록
         * @param userId   사용자 ID
         * @return 삭제 결과
         */
        int deleteServerStyles(@Param("styleIds") List<Long> styleIds, @Param("userId") String userId) throws Exception;

        /**
         * 스타일 이름 중복 확인
         * 
         * @param styleName 스타일 이름
         * @param wrtrId    작성자 ID
         * @return 중복 개수
         */
        int checkStyleNameDuplicate(@Param("styleName") String styleName, @Param("wrtrId") String wrtrId)
                        throws Exception;

        /**
         * 사용자 ID와 스타일명으로 스타일 조회
         * 
         * @param userId  사용자 ID
         * @param styleNm 스타일명
         * @return 레시피 레이어 스타일 정보 (없으면 null)
         */
        RecipeLayerStyleVO selectStyleByUserIdAndName(@Param("userId") String userId, @Param("styleNm") String styleNm);

        /**
         * 특정 스타일 타입별 조회
         * 
         * @param styleTypeCd 스타일 타입 코드
         * @param wrtrId      작성자 ID (선택사항)
         * @return 레시피 레이어 스타일 목록
         */
        List<RecipeLayerStyleVO> selectStylesByType(@Param("styleTypeCd") String styleTypeCd,
                        @Param("wrtrId") String wrtrId) throws Exception;

        /**
         * 스타일 서비스명으로 조회
         * 
         * @param styleSrvcNm 스타일 서비스명
         * @return 레시피 레이어 스타일 정보
         */
        RecipeLayerStyleVO selectServerStyleByServiceName(@Param("styleSrvcNm") String styleSrvcNm) throws Exception;

        /**
         * 사용자 레이어의 물리명을 조회합니다.
         *
         * @param layerId 사용자 레이어 ID
         * @return 사용자 레이어의 물리명
         */
        String getLyrPhysNmByUserLyr(int layerId);

        /**
         * 업무 레이어의 물리명을 조회합니다.
         *
         * @param layerId 업무 레이어 ID
         * @return 업무 레이어의 물리명
         */
        String getLyrPhysNmByTaskLyr(int layerId);

        /**
         * 등간격 방식에 따른 구간 경계값 리스트를 반환합니다.
         *
         * @param lyrPhysNm  테이블 이름
         * @param columnName 커름 이름
         * @param numBreaks  구간 개수
         *
         * @return 계산된 구간 경계값(Double) 리스트
         */
        @SelectProvider(type = ClassificationSQLProvider.class, method = "getEqualClassification")
        List<Double> getEqualClassification(@Param("lyrPhysNm") String lyrPhysNm,
                        @Param("columnName") String columnName,
                        @Param("numBreaks") int numBreaks);

        /**
         * 분위수 방식에 따른 구간 경계값 리스트를 반환합니다.
         *
         * @param lyrPhysNm  테이블 이름
         * @param columnName 커름 이름
         * @param numBreaks  구간 개수
         *
         * @return 계산된 구간 경계값(Double) 리스트
         */
        @SelectProvider(type = ClassificationSQLProvider.class, method = "getQuantileClassification")
        List<Double> getQuantileClassification(@Param("lyrPhysNm") String lyrPhysNm,
                        @Param("columnName") String columnName,
                        @Param("numBreaks") int numBreaks);

        /**
         * 유형별 분류: 칼럼의 고유값 목록 조회 (GROUP BY)
         *
         * @param lyrPhysNm  테이블 물리명
         * @param columnName 칼럼명
         * @param limit      조회할 최대 개수
         * @param orderBy    정렬 기준 (ASC, DESC)
         * @return 고유값 및 개수 목록
         */
        List<CategoryValueDTO> getCategoryValues(
                        @Param("lyrPhysNm") String lyrPhysNm,
                        @Param("columnName") String columnName,
                        @Param("limit") Integer limit,
                        @Param("orderBy") String orderBy);

        /**
         * 조건에 맞는 스타일 중 하나를 랜덤하게 조회합니다 (서비스명 기반).
         * 
         * @param styleSrvcNm 스타일 서비스명
         * @return 조회된 스타일 정보
         */
        RecipeLayerStyleVO selectRandomStyle(@Param("styleSrvcNm") String styleSrvcNm);
}
