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

import java.util.List;

import incheon.ags.dss.regen.vo.UrbMdlMstVO;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import incheon.ags.dss.config.mapper.SimZoneDtlMapper;
import incheon.ags.dss.config.mapper.SimZoneMstMapper;
import incheon.ags.dss.config.service.SimZoneService;
import incheon.ags.dss.config.vo.SimZoneDtlVO;
import incheon.ags.dss.config.vo.SimZoneMstVO;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;

@Service("simZoneService")
@RequiredArgsConstructor
@Slf4j
public class SimZoneServiceImpl implements SimZoneService {

	// --- 1. SimZone (Mst/Dtl) 매퍼 ---
    private final SimZoneMstMapper simZoneMstMapper;
    private final SimZoneDtlMapper simZoneDtlMapper;
    
    @Override
    public List<SimZoneMstVO> selectSimZoneList(SimZoneMstVO searchVO) throws Exception {
        return simZoneMstMapper.selectSimZoneMstList(searchVO);
    }

    @Override
    public int selectSimZoneListCnt(SimZoneMstVO searchVO) throws Exception {
        return simZoneMstMapper.selectSimZoneMstListCnt(searchVO);
    }
    
    @Override
    public List<UrbMdlMstVO> selectSimZoneRecentList(SimZoneMstVO searchVO) throws Exception {
        return simZoneMstMapper.selectSimZoneMstRecentList(searchVO);
    }

    /**
     * 구역 상세 정보 조회 (Mst + Dtl)
     */
    @Override
    public SimZoneMstVO selectSimZoneDetail(SimZoneMstVO vo) throws Exception {
        log.info("Reading Mst Detail...");
        // 1. Mst(부모) 정보 조회
        SimZoneMstVO mstData = simZoneMstMapper.selectSimZoneMstDetail(vo);
        
        if (mstData != null) {
            log.info("Reading Dtl List (sim_zone_dtl)...");
            // 2. Dtl(자식) 정보 조회
            SimZoneDtlVO dtlSearchVO = new SimZoneDtlVO();
            dtlSearchVO.setZoneNo(mstData.getZoneNo());
            List<SimZoneDtlVO> dtlList = simZoneDtlMapper.selectSimZoneDtlList(dtlSearchVO);
            
            // 3. 부모 VO에 자식 List를 담아서 반환
            mstData.setItemList(dtlList);
        }
        
        return mstData;
    }

    /**
     * 구역 정보 저장 (Mst + Dtl) (트랜잭션)
     */
    @Override
    @Transactional
    public Long saveSimZone(SimZoneMstVO vo) throws Exception {
        
        // 1. Mst(부모) 저장 (등록/수정)
        if (vo.getZoneNo() > 0) {
            log.info("Updating SimZone Mst (zoneNo: {})", vo.getZoneNo());
            simZoneMstMapper.updateSimZoneMst(vo);
        } else {
            log.info("Inserting SimZone Mst (zoneNm: {})", vo.getZoneNm());
            simZoneMstMapper.insertSimZoneMst(vo); // insert 후 vo.zoneNo에 PK 세팅
        }
        
        Long zoneNo = vo.getZoneNo();
        String loginId = vo.getLastMdfcnId(); // Controller에서 세팅 (ComDefaultVO 상속)
        
        // --- Dtl(구역 도형) 처리 ---
        // 2. 기존 Dtl(자식) 항목들 일괄 삭제
        log.info("Deleting old SimZone Dtl (zoneNo: {})...", zoneNo);
        SimZoneDtlVO deleteVO = new SimZoneDtlVO();
        deleteVO.setZoneNo(zoneNo);
        simZoneDtlMapper.deleteSimZoneDtlByMst(deleteVO);

        // 3. 새 Dtl(자식) 목록 등록
        if (vo.getItemList() != null) {
            log.info("Inserting new SimZone Dtl ({} items)...", vo.getItemList().size());
            for (SimZoneDtlVO item : vo.getItemList()) {
                item.setZoneNo(zoneNo);
                item.setFrstRegId(loginId); 
                item.setLastMdfcnId(loginId);
                simZoneDtlMapper.insertSimZoneDtl(item);
            }
        }
        
        //4. 마스터 집계(Aggregation) 실행
        simZoneDtlMapper.recalculateSimZoneMst(vo.getZoneNo());
        
        return zoneNo;
    }

    /**
     * 구역 정보 삭제 (Mst + Dtl 및 연관 자식 포함 총 19개 테이블) (트랜잭션)
     * 연관된 모든 테이블(19종, 대상분류 포함)을 순서대로 일괄 삭제합니다.
     */
    @Override
    @Transactional
    public int deleteSimZone(SimZoneMstVO vo) throws Exception {
        log.warn("Deleting SimZone Cascade (zoneNo: {}) via Single CTE Query.", vo.getZoneNo());
        
        // Dtl 삭제 및 연관 테이블 삭제는 Mapper XML 내부에서 모두 처리됨.
        return simZoneMstMapper.deleteSimZoneMst(vo);
    }
}