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

import egovframework.util.SessionUtil;
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.carInspectionPenalty.registration.model.CarFfnlgTrgtVO;
import go.kr.project.carInspectionPenalty.registration.service.ComparisonService;
import go.kr.project.carInspectionPenalty.registration.service.impl.delay_checker.*;
import go.kr.project.login.model.LoginUserVO;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.egovframe.rte.fdl.cmmn.EgovAbstractServiceImpl;
import org.springframework.stereotype.Service;

import java.time.LocalDate;
import java.time.format.DateTimeFormatter;

/**
 * 과태료 대상 비교 서비스 구현체
 *
 * <p>각 비교 로직을 독립적인 체커 클래스로 분리하여 관리합니다.</p>
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class ComparisonServiceImpl extends EgovAbstractServiceImpl implements ComparisonService {

    private final ProductUseChecker productUseChecker;
    private final ProductUseChnageChecker productUseChnageChecker;
    private final ProductCloseWithin31Checker productCloseWithin31Checker;
    private final OwnerCloseWithin31Checker ownerCloseWithin31Checker;
    private final ProductLevyOver31Checker productLevyOver31Checker;
    private final OwnerLevyOver31Checker ownerLevyOver31Checker;
    private final TransferCase115DayChecker transferCase115DayChecker;

    private final ExternalVehicleApiService apiService;
    private final VmisCarBassMatterInqireLogService bassMatterLogService;

    private static final DateTimeFormatter DATE_FORMATTER = DateTimeFormatter.ofPattern("yyyyMMdd");

    /**
     * 비교 로직 메인 메서드
     *
     * <p>순차적으로 각 비교 체커를 실행하고, 하나라도 적용되면 즉시 종료합니다.</p>
     */
    @Override
    public String executeComparison(CarFfnlgTrgtVO existingData, LoginUserVO userInfo) {
        // ========== 특수문자 '*' 제거 (전출차량, 재검여부 표시용) ==========
        // 차량번호에서 '*' 제거
        if (existingData.getVhclno() != null) {
            String cleanVhclno = existingData.getVhclno().replace("*", "");
            existingData.setVhclno(cleanVhclno);
        }

        // 일수에서 '*' 제거
        if (existingData.getDaycnt() != null) {
            String cleanDaycnt = existingData.getDaycnt().replace("*", "");
            existingData.setDaycnt(cleanDaycnt);
        }

        String vhclno = existingData.getVhclno();
        log.info("========== 비교 로직 시작: {} ==========", vhclno);

        // 사용자 조직코드 추출
        String userOrgCd = userInfo != null ? userInfo.getOrgCd() : null;

        // ========== Step 0: 자동차기본정보 조회 (차량번호 + 오늘일자) - 한번만 호출 ==========
        log.info("[공통] Step 0: 자동차기본정보 조회 - 차량번호: {}, 현재일", vhclno);
        NewBasicResponse step0Response = null;
        try {
            NewBasicRequest step0Request = createBasicRequest(vhclno, null, LocalDate.now().format(DATE_FORMATTER));
            step0Response = apiService.getBasicInfo(step0Request);
            bassMatterLogService.updateCarFfnlgTrgtIdByTxIdNewTx(step0Response, existingData.getCarFfnlgTrgtId());

            if (step0Response == null || step0Response.getRecord() == null || step0Response.getRecord().isEmpty()) {
                log.warn("[공통] Step 0 응답 없음 - 차량번호: {}", vhclno);
                log.info("========== 비교 로직 종료 (Step 0 응답 없음): {} ==========", vhclno);
                return null;
            }
        } catch (Exception e) {
            log.error("[공통] Step 0 호출 중 오류 발생 - 차량번호: {}", vhclno, e);
            log.info("========== 비교 로직 종료 (Step 0 오류): {} ==========", vhclno);
            return null;
        }

        // ========== 1. 상품용 체크 - api-1번호출.소유자명.contains("상품용") ==========
        String productUseResult = productUseChecker.check(existingData, userOrgCd, step0Response);
        if (productUseResult != null) {
            log.info("========== 비교 로직 종료 (상품용): {} ==========", vhclno);
            return productUseResult;
        }

        // ========== 2. 상품용 체크 - api-1번호출.소유자명.contains("상품용-변경등록") ==========
        String productUseChangeResult = productUseChnageChecker.check(existingData, userOrgCd, step0Response);
        if (productUseChangeResult != null) {
            log.info("========== 비교 로직 종료 (상품용-변경등록): {} ==========", vhclno);
            return productUseChangeResult;
        }

        // ========== 3. 내사종결 체크 - 명의이전 이전소유자 상품용, 31일 이내 ==========
        String investigationClosedByProductResult = productCloseWithin31Checker.check(existingData, userOrgCd, step0Response);
        if (investigationClosedByProductResult != null) {
            log.info("========== 비교 로직 종료 (내사종결 - 명의이전 이전소유자 상품용, 31일 이내): {} ==========", vhclno);
            return investigationClosedByProductResult;
        }

        // ========== 4. 내사종결 체크 - 명의이전, 31일 이내 ==========
        String investigationClosedByOwnerChangeResult = ownerCloseWithin31Checker.check(existingData, userOrgCd, step0Response);
        if (investigationClosedByOwnerChangeResult != null) {
            log.info("========== 비교 로직 종료 (내사종결 - 명의이전, 31일 이내): {} ==========", vhclno);
            return investigationClosedByOwnerChangeResult;
        }

        // ========== 5. 이첩 체크 ==========
        String transferResult = transferCase115DayChecker.check(existingData, userOrgCd, step0Response);
        if (transferResult != null) {
            log.info("========== 비교 로직 종료 (이첩): {} ==========", vhclno);
            return transferResult;
        }

        // ========== 6. 날짜 수정 후 부과 체크 - 명의이전 이전소유자 상품용, 31일 초과 ==========
        String dateModifiedLevyByProductResult = productLevyOver31Checker.check(existingData, userOrgCd, step0Response);
        if (dateModifiedLevyByProductResult != null) {
            log.info("========== 비교 로직 종료 (날짜 수정 후 부과 - 명의이전 이전소유자, 31일 초과): {} ==========", vhclno);
            return dateModifiedLevyByProductResult;
        }

        // ========== 7. 날짜 수정 후 부과 체크 - 명의이전, 31일 초과 ==========
        String dateModifiedLevyByOwnerChangeOverResult = ownerLevyOver31Checker.check(existingData, userOrgCd, step0Response);
        if (dateModifiedLevyByOwnerChangeOverResult != null) {
            log.info("========== 비교 로직 종료 (날짜 수정 후 부과 - 명의이전, 31일 초과): {} ==========", vhclno);
            return dateModifiedLevyByOwnerChangeOverResult;
        }



        log.info("========== 비교 로직 종료 (미적용): {} ==========", vhclno);
        return null;
    }

    /**
     * 자동차기본정보 요청 객체 생성
     */
    private NewBasicRequest createBasicRequest(String vhrno, String vin, String levyCrtrYmd) {
        NewBasicRequest request = new NewBasicRequest();

        NewBasicRequest.Record record = new NewBasicRequest.Record();
        record.setLevyCrtrYmd(levyCrtrYmd);

        if (vhrno != null) {
            // API 호출 시 '*' 특수문자 제거 (전출차량 표시용)
            String cleanVhrno = vhrno.replace("*", "");
            record.setVhrno(cleanVhrno);
            record.setInqSeCd("3");  // 3: 자동차번호
        } else if (vin != null) {
            record.setVin(vin);
            record.setInqSeCd("2");  // 2: 차대번호
        }

        request.setRecord(java.util.Arrays.asList(record));
        return request;
    }
}
