package go.kr.project.api.internal.service.impl;

import go.kr.project.api.config.ApiConstant;
import go.kr.project.api.internal.client.GovernmentApi;
import go.kr.project.api.internal.service.VmisCarLedgerFrmbkService;
import go.kr.project.api.internal.service.VmisRequestEnricher;
import go.kr.project.api.internal.util.ExceptionDetailUtil;
import go.kr.project.api.model.Envelope;
import go.kr.project.api.model.request.LedgerRequest;
import go.kr.project.api.model.response.LedgerResponse;
import go.kr.project.api.model.response.VmisCarLedgerFrmbkDtlVO;
import go.kr.project.api.model.response.VmisCarLedgerFrmbkVO;
import go.kr.project.api.service.VmisCarLedgerFrmbkLogService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.egovframe.rte.fdl.cmmn.EgovAbstractServiceImpl;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

/**
 * 자동차 등록 원부(갑) 서비스 구현체 (오케스트레이션)
 * - 요청 보강, 외부 API 호출, 로그 서비스 위임
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class VmisCarLedgerFrmbkServiceImpl extends EgovAbstractServiceImpl implements VmisCarLedgerFrmbkService {

    private final GovernmentApi governmentApi;
    private final VmisRequestEnricher enricher;
    private final VmisCarLedgerFrmbkLogService logService;

    /**
     * 자동차 등록원부(갑) 조회: 보강 -> 최초요청로그(별도TX) -> 외부호출 -> 응답로그(마스터/상세, 별도TX) -> 오류 시 에러로그(별도TX).
     */
    @Override
    @Transactional
    public ResponseEntity<Envelope<LedgerResponse>> ledger(Envelope<LedgerRequest> envelope) {
        // 1) 요청 보강
        enricher.enrichLedger(envelope);

        String generatedId = null;
        try {
            // 2) 최초 요청 로그 저장 (첫 번째 데이터 기준)
            if (envelope.getData() != null && !envelope.getData().isEmpty()) {
                LedgerRequest req = envelope.getData().get(0);
                VmisCarLedgerFrmbkVO init = VmisCarLedgerFrmbkVO.fromRequest(req);
                generatedId = logService.createInitialRequestNewTx(init);
            }

            // 3) 외부 API 호출
            ResponseEntity<Envelope<LedgerResponse>> response = governmentApi.callLedger(envelope);

            // 4) 응답 로그 업데이트 (마스터 + 상세)
            if (generatedId != null && response.getBody() != null &&
                    response.getBody().getData() != null && !response.getBody().getData().isEmpty()) {
                LedgerResponse body = response.getBody().getData().get(0);
                VmisCarLedgerFrmbkVO masterUpdate = VmisCarLedgerFrmbkVO.fromResponseMaster(generatedId, body);
                logService.updateResponseNewTx(masterUpdate);

                List<VmisCarLedgerFrmbkDtlVO> details = VmisCarLedgerFrmbkDtlVO.listFromResponse(body, generatedId);
                if (details != null && !details.isEmpty()) {
                    logService.saveDetailsNewTx(generatedId, details);
                }
            }

            return response;
        } catch (Exception e) {
            // 5) 오류 로그 업데이트
            if (generatedId != null) {
                try {
                    String detail = ExceptionDetailUtil.buildForLog(e);
                    VmisCarLedgerFrmbkVO errorLog = VmisCarLedgerFrmbkVO.builder()
                            .carLedgerFrmbkId(generatedId)
                            .cntcResultCode(ApiConstant.CNTC_RESULT_CODE_ERROR)
                            .cntcResultDtls(detail)
                            .build();
                    logService.updateResponseNewTx(errorLog);
                    log.error("[LEDGER-ERR-LOG] API 호출 에러 정보 저장 완료(별도TX) - ID: {}, detail: {}", generatedId, detail, e);
                } catch (Exception ignore) {
                    log.error("[LEDGER-ERR-LOG] 에러 로그 저장 실패 - ID: {}", generatedId, ignore);
                }
            }
            throw e;
        }
    }
}
