package incheon.ags.dss.status.service.impl;

import java.util.List;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import incheon.ags.dss.status.mapper.AnaIdctDtlMapper;
import incheon.ags.dss.status.mapper.AnaIdctMstMapper;
import incheon.ags.dss.status.service.AnaIdctService;
import incheon.ags.dss.status.vo.AnaIdctDtlVO;
import incheon.ags.dss.status.vo.AnaIdctMstVO;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;

@Service("anaIdctService")
@RequiredArgsConstructor
@Slf4j
public class AnaIdctServiceImpl implements AnaIdctService {

    private final AnaIdctMstMapper anaIdctMstMapper;
    private final AnaIdctDtlMapper anaIdctDtlMapper;

    @Override
    public List<AnaIdctMstVO> selectAnaIdctList(AnaIdctMstVO searchVO) throws Exception {
        return anaIdctMstMapper.selectAnaIdctMstList(searchVO);
    }

    @Override
    public int selectAnaIdctListCnt(AnaIdctMstVO searchVO) throws Exception {
        return anaIdctMstMapper.selectAnaIdctMstListCnt(searchVO);
    }

    /**
     * 지표 상세 정보 조회 (Mst + Dtl)
     */
    @Override
    public AnaIdctMstVO selectAnaIdctDetail(AnaIdctMstVO vo) throws Exception {
        log.info("Reading Mst Detail...");
        // 1. Mst(부모) 정보 조회
        AnaIdctMstVO mstData = anaIdctMstMapper.selectAnaIdctMstDetail(vo);
        
        if (mstData != null) {
            log.info("Reading Dtl List (ana_idct_dtl)...");
            // 2. Dtl(자식) 정보 조회
            AnaIdctDtlVO dtlSearchVO = new AnaIdctDtlVO();
            dtlSearchVO.setIdctId(mstData.getIdctId());
            List<AnaIdctDtlVO> dtlList = anaIdctDtlMapper.selectAnaIdctDtlList(dtlSearchVO);
            
            // 3. 부모 VO에 자식 List를 담아서 반환
            mstData.setItemList(dtlList);
        }
        
        return mstData;
    }

    /**
     * 지표 정보 저장 (Mst + Dtl) (트랜잭션)
     */
    @Override
    @Transactional
    public int saveAnaIdct(AnaIdctMstVO vo) throws Exception {
        
        // 1. Mst(부모) 저장 (등록/수정)
        // (idctId는 String PK이므로, VO에 값이 있는지 여부로 등록/수정 판별)
        // (Controller에서 detail.do로 조회한 데이터가 없으면 idctId가 비어있음)
        
        AnaIdctMstVO checkVO = anaIdctMstMapper.selectAnaIdctMstDetail(vo);
        
        if (checkVO != null) {
            log.info("Updating AnaIdct Mst (idctId: {})", vo.getIdctId());
            anaIdctMstMapper.updateAnaIdctMst(vo);
        } else {
            log.info("Inserting AnaIdct Mst (idctId: {})", vo.getIdctId());
            anaIdctMstMapper.insertAnaIdctMst(vo);
        }
        
        String idctId = vo.getIdctId();
        
        // --- Dtl(지표 수식) 처리 ---
        // 2. 기존 Dtl(자식) 항목들 일괄 삭제
        log.info("Deleting old AnaIdct Dtl (idctId: {})...", idctId);
        AnaIdctDtlVO deleteVO = new AnaIdctDtlVO();
        deleteVO.setIdctId(idctId);
        anaIdctDtlMapper.deleteAnaIdctDtlByMst(deleteVO);

        // 3. 새 Dtl(자식) 목록 등록
        if (vo.getItemList() != null) {
            log.info("Inserting new AnaIdct Dtl ({} items)...", vo.getItemList().size());
            for (AnaIdctDtlVO item : vo.getItemList()) {
                item.setIdctId(idctId); // 부모 PK(Foreign Key) 세팅
                anaIdctDtlMapper.insertAnaIdctDtl(item);
            }
        }
        
        // PK가 int(serial)가 아니므로 1(성공) 반환
        return 1;
    }

    /**
     * 지표 정보 삭제 (Mst + Dtl) (트랜잭션)
     */
    @Override
    @Transactional
    public int deleteAnaIdct(AnaIdctMstVO vo) throws Exception {
        log.warn("Deleting AnaIdct Set (idctId: {})...", vo.getIdctId());
        
        // 1. Mst(부모) 삭제 (Soft Delete) 시도
        // 권한 체크(user_id, sys_idct_yn='N')가 XML 쿼리에 포함됨
        int result = anaIdctMstMapper.deleteAnaIdctMst(vo);
        
        // 2. 삭제된 행이 0개라면 권한이 없거나 시스템 지표임 -> 예외 발생
        if (result == 0) {
            log.error("삭제 실패: 권한이 없거나 시스템 지표입니다. ID: {}", vo.getIdctId());
            throw new RuntimeException("삭제 권한이 없거나 시스템 지표는 삭제할 수 없습니다.");
        }
        
        // 3. Mst 삭제 성공 시에만 Dtl(자식) 물리 삭제 진행
        // (Soft Delete된 지표의 상세 항목을 굳이 남길 필요가 없다면 삭제, 남겨야 한다면 생략 가능. 현재는 삭제 로직 유지)
        AnaIdctDtlVO deleteDtlVO = new AnaIdctDtlVO();
        deleteDtlVO.setIdctId(vo.getIdctId());
        anaIdctDtlMapper.deleteAnaIdctDtlByMst(deleteDtlVO);
        
        return 1;
    }

	@Override
	public int selectAnaIdctExstCnt(String idctId) throws Exception {
		return anaIdctMstMapper.selectAnaIdctExstCnt(idctId);
	}
}