package incheon.ags.ias.dataHoprReg.service.impl;

import incheon.ags.ias.dataHoprReg.mapper.KbRtmsSyncMapper;
import incheon.ags.ias.dataHoprReg.service.KbRtmsInfoSyncService;
import incheon.ags.ias.dataHoprReg.util.KbRtmsFileRefiner;
import incheon.ags.ias.dataHoprReg.vo.KbRtmsInfoVO;
import incheon.com.cmm.exception.BusinessException;
import incheon.com.file.service.ComFileService;
import incheon.com.file.vo.ComFileDtlVO;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.egovframe.rte.fdl.cmmn.EgovAbstractServiceImpl;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.io.File;
import java.math.BigDecimal;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;

/**
 * KB RTMS 매물정보 동기화 서비스
 *
 * 파일: 222인천_정보.txt
 * 정제: ① 줄 끝 "|" 제거 ② "인천광역시" 줄 첫 번째 "||" → "|"
 * 정제 후 51컬럼: unq_key | ctpv_nm | ... | cmpx_x_sz | cmpx_y_sz
 * 동기화 방식: DELETE ALL + INSERT (Truncate 후 재적재)
 */
@Slf4j
@Service("kbRtmsInfoSyncService")
@RequiredArgsConstructor
public class KbRtmsInfoSyncServiceImpl extends EgovAbstractServiceImpl implements KbRtmsInfoSyncService {

    private static final int EXPECTED_COLS = 51;

    private final KbRtmsSyncMapper kbRtmsSyncMapper;
    private final ComFileService comFileService;

    @Value("${Globals.comfile.storage.path:../upload}")
    private String uploadPath;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int syncFromFile(String atchFileId, String operatorId) throws Exception {
        log.info("========== KB RTMS 매물정보 동기화 시작 ==========");

        File file = resolveFile(atchFileId);

        // filterIncheon=false, fixDoublePipe=true
        List<List<String>> rows = KbRtmsFileRefiner.readAndRefine(file, false, true, EXPECTED_COLS);

        if (rows.isEmpty()) {
            throw new BusinessException("파싱된 데이터가 없습니다. 매물정보 파일인지 확인해주세요.");
        }

        // 첫 행 검증: 매물정보 파일은 첫 컬럼=unq_key, 둘째 컬럼=ctpv_nm(시도명)
        List<String> firstRow = rows.get(0);
        String firstCol = firstRow.get(0);
        String secondCol = firstRow.get(1);
        if (firstCol == null || firstCol.isEmpty()) {
            throw new BusinessException("매물정보 파일 형식이 아닙니다. 첫 컬럼(unq_key)이 비어있습니다.");
        }
        if (secondCol == null || secondCol.isEmpty()) {
            throw new BusinessException("매물정보 파일 형식이 아닙니다. 둘째 컬럼(ctpv_nm)이 비어있습니다. 현재값: " + firstCol);
        }

        // 전체 삭제 후 재적재
        int deleted = kbRtmsSyncMapper.deleteInfoAll();
        log.info("기존 매물정보 삭제: {} 건", deleted);

        int processedCount = 0;
        for (List<String> c : rows) {
            KbRtmsInfoVO vo = new KbRtmsInfoVO();
            vo.setUnqKey(c.get(0));
            vo.setCtpvNm(c.get(1));
            vo.setGunguNm(c.get(2));
            vo.setEmdNm(c.get(3));
            vo.setLiNm(c.get(4));
            vo.setLnbr(c.get(5));
            vo.setLnbrElse(c.get(6));
            vo.setAptNm(c.get(7));
            vo.setHshdCnt(toBigDecimal(c.get(8)));
            vo.setDocn(toBigDecimal(c.get(9)));
            vo.setTofl(toBigDecimal(c.get(10)));
            vo.setTlf(toBigDecimal(c.get(11)));
            vo.setArchYm(c.get(12));
            vo.setAcoNm(c.get(13));
            vo.setHeatMth(c.get(14));
            vo.setHeatFuel(c.get(15));
            vo.setTpkctCnt(toBigDecimal(c.get(16)));
            vo.setMngOfceTelno(c.get(17));
            vo.setLtotSe(c.get(18));
            vo.setMvnYm(c.get(19));
            vo.setCmpxInfo(c.get(20));
            vo.setZip(c.get(21));
            vo.setMubldYn(c.get(22));
            vo.setRwhsSe(c.get(23));
            vo.setGuPbadmsFcltNm(c.get(24));
            vo.setDngPbadmsFcltNm(c.get(25));
            vo.setPolstnNm(c.get(26));
            vo.setFrstnNm(c.get(27));
            vo.setBankNm(c.get(28));
            vo.setHsptlNm(c.get(29));
            vo.setSportsCntrNm(c.get(30));
            vo.setShopngFcltNm(c.get(31));
            vo.setSchlNm(c.get(32));
            vo.setParkNm(c.get(33));
            vo.setGnrlBusNo(c.get(34));
            vo.setSeatBusNo(c.get(35));
            vo.setSubwayRteNm(c.get(36));
            vo.setSutaNm(c.get(37));
            vo.setTrnsitHr(c.get(38));
            vo.setStdgCd(c.get(39));
            vo.setRemdelngSe(c.get(40));
            vo.setRoadNmFndZip(c.get(41));
            vo.setRoadNmFndZipCd(c.get(42));
            vo.setBldgCrtrZip(c.get(43));
            vo.setRoadNmDtlNo(c.get(44));
            vo.setBaflSe(c.get(45));
            vo.setRootRoadNmAddr(c.get(46));
            vo.setSubRoadNmAddr(c.get(47));
            vo.setRoadNmAddrNo(c.get(48));
            vo.setCmpxXSz(toBigDecimal(c.get(49)));
            vo.setCmpxYSz(toBigDecimal(c.get(50)));
            vo.setOperatorId(operatorId);

            kbRtmsSyncMapper.insertInfo(vo);
            processedCount++;
        }

        log.info("========== KB RTMS 매물정보 동기화 완료: {} 건 ==========", processedCount);
        return processedCount;
    }

    private BigDecimal toBigDecimal(String value) {
        if (value == null || value.trim().isEmpty()) return null;
        try {
            return new BigDecimal(value.trim());
        } catch (NumberFormatException e) {
            return null;
        }
    }

    private File resolveFile(String atchFileId) throws Exception {
        if (atchFileId == null || atchFileId.trim().isEmpty()) {
            throw new BusinessException("첨부파일 ID가 없습니다.");
        }

        List<ComFileDtlVO> fileList = comFileService.selectComFileDtlList(atchFileId);
        if (fileList == null || fileList.isEmpty()) {
            throw new BusinessException("파일을 찾을 수 없습니다.");
        }

        ComFileDtlVO fileInfo = fileList.get(0);
        log.info("파일 정보: {} ({}bytes)", fileInfo.getOrgnlFileNm(), fileInfo.getFileSz());

        Path basePath = Paths.get(uploadPath).toAbsolutePath().normalize();
        Path filePath = basePath.resolve(fileInfo.getStrgPathNm()).resolve(fileInfo.getStrgFileNm());
        File file = filePath.toFile();

        if (!file.exists()) {
            throw new BusinessException("파일이 존재하지 않습니다: " + filePath);
        }

        return file;
    }
}
