package incheon.ags.ias.dataHoprReg.service.impl;

import incheon.ags.ias.dataHoprReg.mapper.KbRtmsSyncMapper;
import incheon.ags.ias.dataHoprReg.service.KbRtmsBjdcdSyncService;
import incheon.ags.ias.dataHoprReg.util.KbRtmsFileRefiner;
import incheon.ags.ias.dataHoprReg.vo.KbRtmsBjdcdVO;
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.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;

/**
 * KB RTMS 법정동코드 동기화 서비스
 *
 * 파일: 222인천시청_법정동코드.TXT
 * 정제: ① "28"로 시작하는 줄만 필터 ② 줄 끝 "|" 제거 ③ "인천광역시" 줄 첫 번째 "||" → "|"
 * 정제 후 6컬럼: stdg_cd | ctpv_nm | gungu_nm | emd_nm | li_nm | mtn_se_cd
 * 동기화 방식: DELETE ALL + INSERT (코드 테이블이므로 폐지된 코드 제거 필요)
 */
@Slf4j
@Service("kbRtmsBjdcdSyncService")
@RequiredArgsConstructor
public class KbRtmsBjdcdSyncServiceImpl extends EgovAbstractServiceImpl implements KbRtmsBjdcdSyncService {

    private static final int EXPECTED_COLS = 6;

    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=true (28 필터), fixDoublePipe=true (인천광역시 || 수정)
        List<List<String>> rows = KbRtmsFileRefiner.readAndRefine(file, true, true, EXPECTED_COLS);

        if (rows.isEmpty()) {
            throw new BusinessException("파싱된 데이터가 없습니다. 법정동코드 파일인지 확인해주세요.");
        }

        // 첫 행 검증: 법정동코드 파일은 첫 컬럼=stdg_cd("28"로 시작하는 10자리 코드)
        String firstCol = rows.get(0).get(0);
        if (firstCol == null || !firstCol.matches("28\\d{8}")) {
            throw new BusinessException("법정동코드 파일 형식이 아닙니다. 첫 컬럼이 인천 법정동코드(28XXXXXXXX)여야 합니다. 현재값: " + firstCol);
        }

        // 코드 테이블: 전체 삭제 후 재적재 (폐지된 법정동코드 제거)
        int deleted = kbRtmsSyncMapper.deleteBjdcdAll();
        log.info("기존 법정동코드 삭제: {} 건", deleted);

        int processedCount = 0;
        for (List<String> cols : rows) {
            KbRtmsBjdcdVO vo = new KbRtmsBjdcdVO();
            vo.setStdgCd(cols.get(0));
            vo.setCtpvNm(cols.get(1));
            vo.setGunguNm(cols.get(2));
            vo.setEmdNm(cols.get(3));
            vo.setLiNm(cols.get(4));
            vo.setMtnSeCd(cols.get(5));
            vo.setOperatorId(operatorId);

            kbRtmsSyncMapper.insertBjdcd(vo);
            processedCount++;
        }

        log.info("========== KB RTMS 법정동코드 동기화 완료: {} 건 ==========", processedCount);
        return processedCount;
    }

    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;
    }
}
