package go.kr.project.carInspectionPenalty.registration.service.impl.delay_checker;

import egovframework.constant.TaskPrcsSttsConstants;
import egovframework.exception.MessageException;
import egovframework.util.DateUtil;
import go.kr.project.api.model.request.NewBasicRequest;
import go.kr.project.api.model.response.NewBasicResponse;
import go.kr.project.api.service.ExternalVehicleApiService;
import go.kr.project.api.service.VmisCarBassMatterInqireLogService;
import go.kr.project.api.service.VmisCarLedgerFrmbkLogService;
import go.kr.project.carInspectionPenalty.registration.mapper.CarFfnlgTrgtMapper;
import go.kr.project.carInspectionPenalty.registration.model.CarFfnlgTrgtVO;
import go.kr.project.carInspectionPenalty.registration.service.impl.ComparisonRemarkBuilder;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import java.time.LocalDate;

/**
 * 6. 이첩 검증
 *
 * <p>DAYCNT 기반 부과기준일 계산 및 법정동코드 비교</p>
 */
@Slf4j
@Component
public class TransferCase115DayChecker extends AbstractComparisonChecker {

    public TransferCase115DayChecker(CarFfnlgTrgtMapper carFfnlgTrgtMapper,
                                     ExternalVehicleApiService apiService,
                                     VmisCarBassMatterInqireLogService bassMatterLogService,
                                     VmisCarLedgerFrmbkLogService ledgerLogService) {
        super(carFfnlgTrgtMapper, apiService, bassMatterLogService, ledgerLogService);
    }

    @Override
    public String check(CarFfnlgTrgtVO existingData, String userOrgCd, NewBasicResponse step0Response) {
        String vhclno = existingData.getVhclno();

        try {
            // DAYCNT 가져오기
            String daycntStr = existingData.getDaycnt();
            if (daycntStr == null || daycntStr.isEmpty()) {
                log.debug("[이첩] DAYCNT 없음 - 차량번호: {}", vhclno);
                return null;
            }

            int daycnt = Integer.parseInt(daycntStr);
            log.info("[이첩] DAYCNT: {} - 차량번호: {}", daycnt, vhclno);

            // 부과기준일 계산
            String levyCrtrYmd;
            String transferType;

            if (daycnt > 115) {
                // 이첩-2: 부과기준일 = 검사종료일자 + 115일
                String inspEndYmd = existingData.getInspEndYmd().replace("-", "");
                LocalDate inspEndDate = DateUtil.parseDate(inspEndYmd);
                LocalDate levyCrtrDate = inspEndDate.plusDays(115);
                levyCrtrYmd = levyCrtrDate.format(DATE_FORMATTER);
                transferType = "이첩-2";
                log.info("[이첩-2] 부과기준일 = 검사종료일자({}) + 115일 = {}", inspEndYmd, levyCrtrYmd);
            } else {
                // 이첩-1: 부과기준일 = 검사일자
                levyCrtrYmd = existingData.getInspYmd().replace("-", "");
                transferType = "이첩-1";
                log.info("[이첩-1] 부과기준일 = 검사일자 = {}", levyCrtrYmd);
            }

            // Step 0: 공통으로 이미 호출됨 - step0Response 사용
            if (step0Response == null || step0Response.getRecord() == null || step0Response.getRecord().isEmpty()) {
                log.warn("[이첩] Step 0 응답 없음 - 차량번호: {}", vhclno);
                return null;
            }

            NewBasicResponse.Record step0Record = step0Response.getRecord().get(0);
            String step0vin = step0Record.getVin();  // 차대번호

            // 자동차기본정보 API 호출 (부과기준일 기준)
            log.info("[{}] 자동차기본정보 조회 - 차대번호: {}, 부과기준일: {}", transferType, step0vin, levyCrtrYmd);

            NewBasicRequest request = createBasicRequest(null, step0vin, levyCrtrYmd);
            NewBasicResponse response = apiService.getBasicInfo(request);

            // API 응답에 CAR_FFNLG_TRGT_ID 업데이트
            bassMatterLogService.updateCarFfnlgTrgtIdByTxIdNewTx(response, existingData.getCarFfnlgTrgtId());

            if (response == null || response.getRecord() == null || response.getRecord().isEmpty()) {
                log.warn("[{}] 응답 없음 - 차량번호: {}", transferType, vhclno);
                return null;
            }

            NewBasicResponse.Record record = response.getRecord().get(0);
            String usgsrhldStdgCd = record.getUsgsrhldStdgCd();  // 사용본거지법정동코드

            log.info("[{}] API 응답 - 사용본거지법정동코드: {}", transferType, usgsrhldStdgCd);

            // 법정동코드 유효성 검사
            if (usgsrhldStdgCd == null || usgsrhldStdgCd.length() < 4) {
                log.debug("[{}] 법정동코드 없음 - 차량번호: {}", transferType, vhclno);
                return null;
            }

            // 사용자 조직코드 유효성 검사
            if (userOrgCd == null) {
                log.debug("[{}] 사용자 정보 없음", transferType);
                return null;
            }

            // 법정동코드 앞 4자리 vs 사용자 조직코드 앞 4자리 비교
            String legalDong4 = usgsrhldStdgCd.substring(0, 4);
            String userOrg4 = userOrgCd.length() >= 4 ? userOrgCd.substring(0, 4) : userOrgCd;

            if (legalDong4.equals(userOrg4)) {
                log.debug("[{}] 법정동코드 일치 - 차량번호: {}, 법정동: {}, 조직: {}",
                        transferType, vhclno, legalDong4, userOrg4);
                return null;
            }

            log.info("[{}] 법정동코드 불일치! 차량번호: {}, 법정동: {}, 조직: {}",
                    transferType, vhclno, legalDong4, userOrg4);

            // 시군구 코드 및 시군구명 조회
            String sggCd = usgsrhldStdgCd.length() >= 5 ? usgsrhldStdgCd.substring(0, 5) : usgsrhldStdgCd;
            String sggNm = carFfnlgTrgtMapper.selectSggNmBySggCd(sggCd);
            if (sggNm == null || sggNm.isEmpty()) {
                log.warn("[{}] 시군구명 조회 실패 - 시군구코드: {}", transferType, sggCd);
                sggNm = "";
            }

            // 소유자명
            String ownerNm = record.getRprsOwnrNm();

            // 비고 생성
            String rmrk;
            String rmrkDtl;
            if ("이첩-1".equals(transferType)) { // 5번
                rmrk = ComparisonRemarkBuilder.buildTransferCase1Remark(sggNm, ownerNm);
                rmrkDtl = ComparisonRemarkBuilder.buildTransferCase1RemarkDetail(
                        vhclno, existingData.getInspYmd(), ownerNm, usgsrhldStdgCd, sggNm, userOrgCd);
            } else { // 7번
                rmrk = ComparisonRemarkBuilder.buildTransferCase2Remark(sggNm, ownerNm);
                rmrkDtl = ComparisonRemarkBuilder.buildTransferCase2RemarkDetail(
                        vhclno, existingData.getInspEndYmd(), ownerNm, usgsrhldStdgCd, sggNm, userOrgCd, daycntStr);
            }

            // DB 업데이트
            existingData.setCarBassMatterInqireId(response.getGeneratedId());
            existingData.setTaskPrcsSttsCd(TaskPrcsSttsConstants.TASK_PRCS_STTS_CD_03_TRANSFER);
            existingData.setTaskPrcsYmd(LocalDate.now().format(DATE_FORMATTER_DASH));
            existingData.setCarBscMttrInqFlnm(existingData.getOwnrNm());
            existingData.setCarBscMttrInqSggCd(sggCd);
            existingData.setCarBscMttrInqSggNm(sggNm);
            existingData.setRmrk(rmrk);
            existingData.setRmrkDtl(rmrkDtl);

            int updateCount = carFfnlgTrgtMapper.update(existingData);
            if (updateCount == 0) {
                throw new MessageException(String.format("[%s] 업데이트 실패: %s", transferType, vhclno));
            }

            log.info("[{}] 처리 완료! 차량번호: {}, 시군구: {}({})", transferType, vhclno, sggNm, sggCd);
            return TaskPrcsSttsConstants.TASK_PRCS_STTS_CD_03_TRANSFER;

        } catch (Exception e) {
            log.error("[이첩] 검증 중 오류 발생 - 차량번호: {}", vhclno, e);
            throw new MessageException(String.format("[이첩] 검증 중 오류 발생 - 차량번호: %s", vhclno), e);
        }
    }
}
