package incheon.product.geoview3d.theme.service.impl;

import incheon.com.cmm.exception.BusinessException;
import incheon.product.geoview3d.theme.mapper.ThemeMapper;
import incheon.product.geoview3d.theme.service.ThemeService;
import incheon.product.geoview3d.theme.vo.ThemeCategoryVO;
import incheon.product.geoview3d.theme.vo.ThemeLayerVO;
import lombok.extern.slf4j.Slf4j;
import org.egovframe.rte.fdl.cmmn.EgovAbstractServiceImpl;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.List;
import java.util.Map;
import java.util.regex.Pattern;

/**
 * 주제도 서비스 구현체.
 */
@Slf4j
@Service("productThemeService")
public class ThemeServiceImpl extends EgovAbstractServiceImpl implements ThemeService {

    /** SQL 식별자 허용 패턴: 영문, 숫자, 밑줄, 마침표(스키마.테이블)만 허용 */
    private static final Pattern SQL_IDENTIFIER = Pattern.compile("^[a-zA-Z_][a-zA-Z0-9_.]*$");

    @Resource(name = "productThemeMapper")
    private ThemeMapper themeMapper;

    @Override
    public String getThemeListJson() {
        return themeMapper.selectThemeListJson();
    }

    @Override
    public String getThemeJson(String themeId, String query, Integer limit) {
        if (themeId == null || themeId.isBlank()) {
            throw new BusinessException("주제도 ID가 필요합니다.", HttpStatus.BAD_REQUEST);
        }
        return themeMapper.selectThemeJson(themeId, query, limit);
    }

    @Override
    public List<ThemeCategoryVO> getCategories() {
        return themeMapper.selectThemeCategories();
    }

    @Override
    public List<ThemeLayerVO> getLayers() {
        return themeMapper.selectThemeLayers();
    }

    @Override
    public List<String> getFilterValues(String themeId, String filterName) {
        validateSqlIdentifier(filterName, "filterName");
        String sourceTable = themeMapper.selectThemeFilterSourceTable(themeId);
        if (sourceTable == null) {
            return List.of();
        }
        validateSqlIdentifier(sourceTable, "sourceTable");
        return themeMapper.selectThemeFilterList(sourceTable, filterName);
    }

    @Override
    public List<String> getFilterChildValues(String themeId, String filterName1, String filterValue, String filterName2) {
        validateSqlIdentifier(filterName1, "filterName1");
        validateSqlIdentifier(filterName2, "filterName2");
        String sourceTable = themeMapper.selectThemeFilterSourceTable(themeId);
        if (sourceTable == null) {
            return List.of();
        }
        validateSqlIdentifier(sourceTable, "sourceTable");
        return themeMapper.selectThemeFilterListByParent(sourceTable, filterName1, filterValue, filterName2);
    }

    private void validateSqlIdentifier(String value, String paramName) {
        if (value == null || !SQL_IDENTIFIER.matcher(value).matches()) {
            throw new BusinessException("유효하지 않은 식별자(" + paramName + "): " + value, HttpStatus.BAD_REQUEST);
        }
    }

    @Override
    public String getElectionGeom(String poiId) {
        return themeMapper.selectElectionGeomByPoiId(poiId);
    }

    @Override
    public List<Map<String, Object>> getWasteBagPrices(String sgg) {
        return themeMapper.selectWasteBagPriceList(sgg);
    }
}
