package incheon.ags.ias.comCd.service.impl;

import incheon.ags.ias.comCd.mapper.ComCdMapper;
import incheon.ags.ias.comCd.service.ComCdService;
import incheon.ags.ias.comCd.vo.ComCdVO;
import incheon.ags.ias.comCd.vo.ComGroupCdVO;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.egovframe.rte.fdl.cmmn.EgovAbstractServiceImpl;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 공통코드 Service 구현체
 */
@Slf4j
@Service("comCdService")
@RequiredArgsConstructor
public class ComCdServiceImpl extends EgovAbstractServiceImpl implements ComCdService {

    private final ComCdMapper comCdMapper;


    /* ========================================
     * 그룹코드 관련 메서드
     * ======================================== */

    @Override
    public List<ComGroupCdVO> selectComGroupCdList(ComGroupCdVO vo) throws Exception {
        return comCdMapper.selectComGroupCdList(vo);
    }

    @Override
    public ComGroupCdVO selectComGroupCdTotalCnt(ComGroupCdVO vo) throws Exception {
        return comCdMapper.selectComGroupCdTotalCnt(vo);
    }

    @Override
    public ComGroupCdVO selectComGroupCdListUseCnt() throws Exception {
        return comCdMapper.selectComGroupCdListUseCnt();
    }

    @Override
    public ComGroupCdVO selectComGroupCdDetail(String groupCd) throws Exception {
        return comCdMapper.selectComGroupCdDetail(groupCd);
    }

    @Override
    public int insertComGroupCd(ComGroupCdVO vo) throws Exception {
        return comCdMapper.insertComGroupCd(vo);
    }

    @Override
    public int updateComGroupCd(ComGroupCdVO vo) throws Exception {
        return comCdMapper.updateComGroupCd(vo);
    }

    @Override
    public int deleteComGroupCd(String groupCd) throws Exception {
        ComGroupCdVO vo = new ComGroupCdVO();
        vo.setGroupCd(groupCd);
        return comCdMapper.deleteComGroupCd(vo);
    }


    /* ========================================
     * 상세코드 관련 메서드
     * ======================================== */

    @Override
    public List<ComCdVO> getComCdByGroupCd(String groupCd) throws Exception {
        return comCdMapper.getComCdByGroupCd(groupCd);
    }

    @Override
    public ComCdVO getComCdDetail(String groupCd, String cd) throws Exception {
        if (!StringUtils.hasText(groupCd) || !StringUtils.hasText(cd)) {
            log.error("필수 파라미터 누락 - groupCd: {}, cd: {}", groupCd, cd);
            return null;
        }
        return comCdMapper.selectComCdDetail(groupCd, cd);
    }

    @Override
    public int insertComCd(ComCdVO vo) throws Exception {
        return comCdMapper.insertComCd(vo);
    }

    @Override
    public int updateComCd(ComCdVO vo) throws Exception {
        if (!StringUtils.hasText(vo.getGroupCd()) || !StringUtils.hasText(vo.getCd())) {
            throw new IllegalArgumentException("그룹코드와 상세코드는 필수입니다.");
        }

        // 수정 전 데이터 존재 여부 확인
        ComCdVO existingData = getComCdDetail(vo.getGroupCd(), vo.getCd());
        if (existingData == null) {
            throw new IllegalArgumentException("수정할 데이터가 존재하지 않습니다.");
        }

        return comCdMapper.updateComCd(vo);
    }

    @Override
    public int deleteComCd(String cd, String groupCd) throws Exception {
        Map<String, Object> paramMap = new HashMap<>();
        paramMap.put("cd", cd);
        paramMap.put("groupCd", groupCd);
        return comCdMapper.deleteComCd(paramMap);
    }

    @Override
    public ComCdVO getComCdTotalCnt() throws Exception {
        return comCdMapper.getComCdTotalCnt();
    }

    @Override
    public ComCdVO getComCdListUseCnt() throws Exception {
        return comCdMapper.getComCdListUseCnt();
    }

    @Override
    public String getCodeName(String groupCd, String cd) {
        try {
            // 파라미터 검증
            if (!StringUtils.hasText(groupCd) || !StringUtils.hasText(cd)) {
                log.warn("공통코드명 조회 실패 - 파라미터 누락 (groupCd: {}, cd: {})", groupCd, cd);
                return "-";
            }

            ComCdVO codeInfo = null;

            // 시스템 코드인 경우 SYS 테이블에서 조회 (뷰용 API와 동일한 로직)
            if ("SYS_CD".equals(groupCd)) {
                List<ComCdVO> systemCodeList = comCdMapper.selectSysCdList();
                codeInfo = systemCodeList.stream()
                        .filter(code -> cd.equals(code.getCd()))
                        .findFirst()
                        .orElse(null);
            } else {
                // 일반 공통코드 조회
                codeInfo = comCdMapper.selectComCdDetail(groupCd, cd);
            }

            if (codeInfo == null || !StringUtils.hasText(codeInfo.getCdNm())) {
                log.warn("공통코드명 조회 실패 - 코드 없음 (groupCd: {}, cd: {})", groupCd, cd);
                return "-";
            }

            return codeInfo.getCdNm();

        } catch (Exception e) {
            log.error("공통코드명 조회 중 오류 발생 (groupCd: {}, cd: {})", groupCd, cd, e);
            return "-";
        }
    }

    @Override
//    @Cacheable(value = "systemCodes", key = "'all'")
    public List<ComCdVO> getSystemCodeList() throws Exception {
        log.info("=== DB에서 시스템 코드 목록 조회");
        return comCdMapper.selectSysCdList();
    }

}
