package incheon.sgp.thm.mapper;

import java.sql.Timestamp;
import java.util.List;
import java.util.Map;

import incheon.sgp.thm.dto.*;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.session.ResultHandler;

import incheon.sgp.thm.trf.CctvRow;
import incheon.sgp.thm.trf.TrafficRow;

@org.egovframe.rte.psl.dataaccess.mapper.Mapper
@incheon.com.config.annotation.ExternalDB
public interface SgpThmMapper {
	String selectThemeListJson();

	String selectThemeJson(@Param("thmId") String thmId, @Param("q") String q, @Param("limit") Integer limit);

	List<SgpThmCategoryDto> selectThemeCategories();

	List<SgpThmLayerDto> selectThemeLayers();

	String selectThemeFilterSourceTable(@Param("themeId") String themeId);

	List<String> selectThemeFilterList(@Param("sourceTable") String sourceTable, @Param("filterName") String filterName);

	List<String> selectThemeFilterListByParent(
		@Param("sourceTable") String sourceTable,
		@Param("filterName1") String filterName1,
		@Param("filterValue") String filterValue,
		@Param("filterName2") String filterName2
	);

	Timestamp findLatestCreatedTs();

	Timestamp findLatestCreatedCctvTs();

	// 교통소통정보
	void upsertSnapshotBatch(@Param("rows") List<TrafficRow> rows);

	void upsertLatestBatch(@Param("rows") List<TrafficRow> rows);

	int deleteOldSnapshots();

	List<Map<String, Object>> selectLinkGradesInBbox(@Param("roadType") int roadType, @Param("minX") double minX,
			@Param("minY") double minY, @Param("maxX") double maxX, @Param("maxY") double maxY);

	// roadType 기준으로 도로 이름/도로 종류 리스트 조회
	List<Map<String, Object>> selectRoadNames(
			@Param("roadType") Integer roadType,
			@Param("searchName") String searchName,
			@Param("offset") Integer offset,
			@Param("pageSize") Integer pageSize);

	int countRoadNames(
			@Param("roadType") Integer roadType,
			@Param("searchName") String searchName);

	// 단일 도로이름으로 해당 도로 내 링크 목록 조회
	// 순서 없음, 순서는 service단에서 f_node, t_node 연결하여 return
	List<Map<String, Object>> selectLinksByRoadName(@Param("roadName") String roadName);

	// CCTV
	void upsertCctvSnapshotBatch(@Param("rows") List<CctvRow> rows);

	void upsertCctvLatestBatch(@Param("rows") List<CctvRow> rows);

	int deleteOldCctvSnapshots();

	List<Map<String, Object>> selectCctvList(@Param("gid") Integer gid, @Param("minX") double minX,
			@Param("minY") double minY, @Param("maxX") double maxX, @Param("maxY") double maxY);

	List<Map<String, Object>> selectCctvNewList(double minX, double minY, double maxX, double maxY);

	SgpThmSubwayDto selectSubwayByName(@Param("subwayName") String subwayName);

	List<SgpThmStationDto> selectStationsBySubwayName(@Param("subwayName") String subwayName);

	List<SgpThmStationShpDto> selectStationShpsBySubwayName(@Param("subwayName") String subwayName);

	/**
	 * 시뮬레이션 JSON 조회
	 * 
	 * @param simId 시뮬레이션 ID
	 * @return JSON 문자열
	 */
	String selectSimulationJsonBySimId(@Param("simId") String simId);

	/**
	 * 클리핑 정보 조회
	 * 
	 * @param clipId 클리핑 ID
	 * @return 클리핑 정보
	 */
	SgpThmTilesetClippingDto selectTilesetClippingById(@Param("clipId") String clipId);

	/**
	 * poi_id로 선거구 Geometry 조회
	 * 
	 * @param poiId 주제도 POI ID (예: "incheon_elec_districts_28010_001")
	 * @return GeoJSON 형태의 geometry 데이터 (WGS84 좌표계)
	 */
	String selectElectionGeomByPoiId(@Param("poiId") String poiId);

	/**
	 * 비오톱 전체 Geometry 및 bio_val 조회 (한 번에 전체)
	 * 
	 * @return List<SgpThmBiotopeGeomDto>
	 */
	List<SgpThmBiotopeGeomDto> selectAllBiotopeGeoms();

	/**
	 * 비오톱 전체 Geometry 스트리밍 조회 - Legacy (ST_AsGeoJSON 방식)
	 * A/B 테스트용: 기존 방식 유지
	 * 
	 * @param handler MyBatis ResultHandler
	 */
	void streamAllBiotopeGeomsLegacy(ResultHandler<SgpThmBiotopeGeomDto> handler);

	/**
	 * 비오톱 전체 Geometry 스트리밍 조회 - Optimized (bio_code DB 변환)
	 * bio_code를 DB에서 직접 변환하여 Java 로직 단순화
	 * 
	 * @param handler MyBatis ResultHandler
	 */
	void streamAllBiotopeGeomsOptimized(ResultHandler<SgpThmBiotopeGeomDto> handler);

	List<Map<String, Object>> getWasteBagPriceList(@Param("sggNm") String sggName);

	Long upsertWindMeta(
			@Param("year") int year,
			@Param("month") int month,
			@Param("day") int day,
			@Param("time") String time,
			@Param("filename") String filename);

	Map<String, Object> selectWindById(@Param("id") Long id);

	List<Map<String, Object>> selectWindByDay(
			@Param("year") int year,
			@Param("month") int month,
			@Param("day") int day,
			@Param("filename") String filename);

	List<Map<String, Object>> selectWindByRange(
			@Param("startKey") String startKey,
			@Param("endKey") String endKey,
			@Param("filename") String filename);

	Map<String, Object> selectWindPrev(
			@Param("boundaryKey") String boundaryKey,
			@Param("filename") String filename);

	Map<String, Object> selectWindNext(
			@Param("boundaryKey") String boundaryKey,
			@Param("filename") String filename);

	List<Map<String, Object>> selectWindByFilename(@Param("filename") String filename);
}
