package incheon.ags.ias.dataHoprReg.service.impl;

import incheon.ags.ias.dataHoprReg.mapper.KbRtmsSyncMapper;
import incheon.ags.ias.dataHoprReg.service.KbRtmsPriceSyncService;
import incheon.ags.ias.dataHoprReg.util.KbRtmsFileRefiner;
import incheon.ags.ias.dataHoprReg.vo.KbRtmsPriceVO;
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
 * 정제: ① 줄 끝 "|" 제거 ② "인천광역시" 줄 첫 번째 "||" → "|"
 * 정제 후 20컬럼: curprc_updt_day | unq_key | blnc_accto_se_no | ... | stdg_cd
 * UPSERT 키: (curprc_updt_day, unq_key, blnc_accto_se_no)
 *
 * 주의: 시세는 누적 데이터 (기존 주차 데이터 유지, 신규 주차 추가)
 */
@Slf4j
@Service("kbRtmsPriceSyncService")
@RequiredArgsConstructor
public class KbRtmsPriceSyncServiceImpl extends EgovAbstractServiceImpl implements KbRtmsPriceSyncService {

    private static final int EXPECTED_COLS = 20;

    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("파싱된 데이터가 없습니다. 시세 파일인지 확인해주세요.");
        }

        // 첫 행 검증: 시세 파일은 첫 컬럼이 8자리 날짜(YYYYMMDD)
        String firstCol = rows.get(0).get(0);
        if (firstCol == null || !firstCol.matches("\\d{8}")) {
            throw new BusinessException("시세 파일 형식이 아닙니다. 첫 컬럼이 날짜(YYYYMMDD)여야 합니다. 현재값: " + firstCol);
        }

        int processedCount = 0;
        for (List<String> c : rows) {
            KbRtmsPriceVO vo = new KbRtmsPriceVO();
            vo.setCurprcUpdtDay(c.get(0));
            vo.setUnqKey(c.get(1));
            BigDecimal blncAcctoSeNo = toBigDecimal(c.get(2));
            if (blncAcctoSeNo == null) {
                log.warn("시세 {}행: blnc_accto_se_no 누락, 스킵", processedCount + 1);
                continue;
            }
            vo.setBlncAcctoSeNo(blncAcctoSeNo);
            vo.setCtpvNm(c.get(3));
            vo.setGunguNm(c.get(4));
            vo.setEmdNm(c.get(5));
            vo.setLiNm(c.get(6));
            vo.setLnbr(c.get(7));
            vo.setLnbrElse(c.get(8));
            vo.setAptNm(c.get(9));
            vo.setTrdLwrAvgpc(toBigDecimal(c.get(10)));
            vo.setTrdGnrlAvgpc(toBigDecimal(c.get(11)));
            vo.setTrdUpAvgpc(toBigDecimal(c.get(12)));
            vo.setLodbLwrAvgpc(toBigDecimal(c.get(13)));
            vo.setLodbGnrlAvgpc(toBigDecimal(c.get(14)));
            vo.setLodbUpAvgpc(toBigDecimal(c.get(15)));
            vo.setMrntGtn(toBigDecimal(c.get(16)));
            vo.setMrntLwrAvgpc(toBigDecimal(c.get(17)));
            vo.setMrntUpAvgpc(toBigDecimal(c.get(18)));
            vo.setStdgCd(c.get(19));
            vo.setOperatorId(operatorId);

            kbRtmsSyncMapper.upsertPrice(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;
    }
}
