package go.kr.project.carInspectionPenalty.registrationOm.service.impl.om_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.registrationOm.mapper.CarFfnlgTrgtIncmpMapper;
import go.kr.project.carInspectionPenalty.registrationOm.model.CarFfnlgTrgtIncmpVO;
import go.kr.project.carInspectionPenalty.registrationOm.service.impl.ComparisonOmRemarkBuilder;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import java.time.LocalDate;

/**
 * 2. 이첩 검증 api-1번호출.!소유자명.contains("상품용")
 *
 * API 호출 3단계:
 * 1) 자동차기본정보(차량번호, 부과일자=검사유효기간 + 146일) → 소유자명
 * 2) 자동차기본정보(차량번호, 부과일자=검사유효기간 - 90일) → 소유자명
 * 3) 자동차기본정보(차량번호, 부과일자=오늘) → 소유자명
 *
 * 비교조건:
 * - 1단계: 소유자, 사용본거지법정동코드
 * - 2단계: 1단계 소유자 = 2단계 소유자 동일
 * - 3단계: 1단계 소유자 = 3단계 소유자 동일
 *
 * 법정동코드 비교:
 * - 사용본거지법정동코드 앞 4자리 != 사용자 조직코드 앞 4자리
 */
@Slf4j
@Component
public class TransferOmChecker extends AbstractComparisonOmChecker {

    public TransferOmChecker(CarFfnlgTrgtIncmpMapper carFfnlgTrgtIncmpMapper,
                             ExternalVehicleApiService apiService,
                             VmisCarBassMatterInqireLogService bassMatterLogService,
                             VmisCarLedgerFrmbkLogService ledgerLogService) {
        super(carFfnlgTrgtIncmpMapper, apiService, bassMatterLogService, ledgerLogService);
    }

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

        try {
            String inspVldPrd = existingData.getInspVldPrd();

            // 검사유효기간에서 종료일 추출
            String inspVldPrdEnd = null;
            if (inspVldPrd != null && inspVldPrd.contains("~")) {
                String[] dates = inspVldPrd.split("~");
                inspVldPrdEnd = dates.length > 1 ? dates[1].trim().replace("-", "") : null;
            }

            if (inspVldPrdEnd == null) {
                log.info("[이첩-미필] 검사유효기간 종료일 없음 - 차량번호: {}", vhclno);
                return null;
            }

            log.info("[상품용-미필] Step 0: 자동차기본정보 조회 - 차량번호: {}, 현재일", vhclno);
            NewBasicRequest step0Request = createBasicRequest(vhclno, null, LocalDate.now().format(DATE_FORMATTER));
            NewBasicResponse step0Response = apiService.getBasicInfo(step0Request);
            bassMatterLogService.updateCarFfnlgTrgtIdByTxIdNewTx(step0Response, existingData.getCarFfnlgTrgtIncmpId());

            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();  // 차대번호

            // 1단계: 자동차기본정보(차량번호, 부과일자=검사유효기간 + 146일)
            // 부과일자는 이미 146일로 계산되어 있음
            String step1Ymd = existingData.getLevyCrtrYmd();

            log.info("[이첩-미필] 1단계 API 호출 - 차대번호: {}, 부과일자: {}", step0vin, step1Ymd);
            NewBasicRequest step1Request = createBasicRequest(null, step0vin, step1Ymd);
            NewBasicResponse step1Response = apiService.getBasicInfo(step1Request);
            bassMatterLogService.updateCarFfnlgTrgtIdByTxIdNewTx(step1Response, existingData.getCarFfnlgTrgtIncmpId());

            if (step1Response == null || step1Response.getRecord() == null || step1Response.getRecord().isEmpty()) {
                log.warn("[이첩-미필] 1단계 응답 없음 - 차량번호: {}", vhclno);
                return null;
            }

            NewBasicResponse.Record step1Record = step1Response.getRecord().get(0);
            String step1RprsOwnrNm = step1Record.getRprsOwnrNm();  // 검사일 기준 소유자명
            String step1RprsvOwnrIdecno = step1Record.getRprsvOwnrIdecno(); // 검사일 기준 소유자 회원번호
            String step1UsgsrhldStdgCd = step1Record.getUsgsrhldStdgCd();  // 1단계 사용본거지법정동코드
            String step1Vin = step1Record.getVin(); // 1단계 차대번호

            // 소유자명에 "상품용" 포함 여부 체크
            if (step1RprsOwnrNm != null && step1RprsOwnrNm.contains("상품용")) {
                log.info("[이첩-미필] 소유자명에 '상품용' 포함 - 차량번호: {}, 소유자명: {}", vhclno, step1RprsOwnrNm);
                return null;
            }

            log.info("[이첩-미필] 1단계 - 소유자명: {}, 법정동코드: {}", step1RprsOwnrNm, step1UsgsrhldStdgCd);

            // 2단계: 자동차기본정보(차량번호, 부과일자=검사유효기간 - 90일)
            LocalDate inspVldPrdEndDate = DateUtil.parseDate(inspVldPrdEnd);
            LocalDate step2Date = inspVldPrdEndDate.minusDays(90);
            String step2Ymd = step2Date.format(DATE_FORMATTER);

            log.info("[이첩-미필] 2단계 API 호출 - 차대번호: {}, 부과일자: {}", step1Vin, step2Ymd);
            NewBasicRequest step2Request = createBasicRequest(null, step1Vin, step2Ymd);
            NewBasicResponse step2Response = apiService.getBasicInfo(step2Request);
            bassMatterLogService.updateCarFfnlgTrgtIdByTxIdNewTx(step2Response, existingData.getCarFfnlgTrgtIncmpId());

            if (step2Response == null || step2Response.getRecord() == null || step2Response.getRecord().isEmpty()) {
                log.warn("[이첩-미필] 2단계 응답 없음 - 차대번호: {}", step1Vin);
                return null;
            }

            NewBasicResponse.Record step2Record = step2Response.getRecord().get(0);
            String step2RprsOwnrNm = step2Record.getRprsOwnrNm();  // 2단계 소유자명
            String step2RprsvOwnrIdecno = step2Record.getRprsvOwnrIdecno();  // 2단계 소유자 회원번호

            log.info("[이첩-미필] 2단계 - 소유자명: {}", step2RprsOwnrNm);

            // 2단계 비교: 1단계 소유자 = 2단계 소유자 동일 체크
            if (step1RprsvOwnrIdecno != null && !step1RprsvOwnrIdecno.equals(step2RprsvOwnrIdecno)) {
                log.info("[이첩-미필] 1단계와 2단계 소유자 동일 - 차량번호: {}, 소유자: {}", vhclno, step1RprsOwnrNm);
                return null;
            }

            // 3단계: 자동차기본정보(차대번호, 부과일자=오늘)
            String step3Ymd = LocalDate.now().format(DATE_FORMATTER);

            log.info("[이첩-미필] 3단계 API 호출 - 차대번호: {}, 부과일자: {}", step1Vin, step3Ymd);
            NewBasicRequest step3Request = createBasicRequest(null, step1Vin, step3Ymd);
            NewBasicResponse step3Response = apiService.getBasicInfo(step3Request);
            bassMatterLogService.updateCarFfnlgTrgtIdByTxIdNewTx(step3Response, existingData.getCarFfnlgTrgtIncmpId());

            if (step3Response == null || step3Response.getRecord() == null || step3Response.getRecord().isEmpty()) {
                log.warn("[이첩-미필] 3단계 응답 없음 - 차대번호: {}", step1Vin);
                return null;
            }

            NewBasicResponse.Record step3Record = step3Response.getRecord().get(0);
            String step3RprsOwnrNm = step3Record.getRprsOwnrNm();  // 3단계 소유자명
            String step3RprsvOwnrIdecno = step3Record.getRprsvOwnrIdecno();  // 3단계 소유자 회원번호

            log.info("[이첩-미필] 3단계 - 소유자명: {}", step3RprsOwnrNm);

            // 3단계 비교: 1단계 소유자 = 3단계 소유자 동일 체크
            if (step1RprsvOwnrIdecno != null && !step1RprsvOwnrIdecno.equals(step3RprsvOwnrIdecno)) {
                log.info("[이첩-미필] 1단계와 3단계 소유자 동일 - 차량번호: {}, 소유자: {}", vhclno, step1RprsOwnrNm);
                return null;
            }

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

            // 사용자 조직코드 유효성 검사
            if (userOrgCd == null) {
                log.info("[이첩-미필] 사용자 정보 없음");
                return null;
            }

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

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

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

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

            // 소유자명
            String ownerNm = step1RprsOwnrNm;

            // 비고 생성 (이첩 케이스)
            String rmrk = ComparisonOmRemarkBuilder.buildTransferRemark(sggNm, ownerNm);
            String rmrkDtl = ComparisonOmRemarkBuilder.buildTransferRemarkDetail(
                    vhclno, inspVldPrdEnd, step1Ymd, ownerNm, step1UsgsrhldStdgCd, sggNm, userOrgCd);

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

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

            log.info("[이첩-미필] 처리 완료! 차량번호: {}, 시군구: {}({})", 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);
        }
    }
}
