package com.kamco.cd.training.postgres.core;

import com.kamco.cd.training.common.enums.HyperParamSelectType;
import com.kamco.cd.training.common.enums.ModelType;
import com.kamco.cd.training.common.enums.TrainStatusType;
import com.kamco.cd.training.common.exception.BadRequestException;
import com.kamco.cd.training.common.exception.CustomApiException;
import com.kamco.cd.training.common.utils.UserUtil;
import com.kamco.cd.training.dataset.dto.DatasetDto.DatasetReq;
import com.kamco.cd.training.dataset.dto.DatasetDto.SelectDataSet;
import com.kamco.cd.training.dataset.dto.DatasetDto.SelectTransferDataSet;
import com.kamco.cd.training.model.dto.ModelConfigDto;
import com.kamco.cd.training.model.dto.ModelTrainMngDto;
import com.kamco.cd.training.model.dto.ModelTrainMngDto.ListDto;
import com.kamco.cd.training.model.dto.ModelTrainMngDto.TrainingDataset;
import com.kamco.cd.training.postgres.entity.ModelConfigEntity;
import com.kamco.cd.training.postgres.entity.ModelDatasetEntity;
import com.kamco.cd.training.postgres.entity.ModelDatasetMappEntity;
import com.kamco.cd.training.postgres.entity.ModelHyperParamEntity;
import com.kamco.cd.training.postgres.entity.ModelMasterEntity;
import com.kamco.cd.training.postgres.repository.dataset.DatasetRepository;
import com.kamco.cd.training.postgres.repository.hyperparam.HyperParamRepository;
import com.kamco.cd.training.postgres.repository.model.ModelConfigRepository;
import com.kamco.cd.training.postgres.repository.model.ModelDatasetMappRepository;
import com.kamco.cd.training.postgres.repository.model.ModelDatasetRepository;
import com.kamco.cd.training.postgres.repository.model.ModelMngRepository;
import com.kamco.cd.training.train.dto.ModelTrainLinkDto;
import com.kamco.cd.training.train.dto.TrainRunRequest;
import java.time.ZonedDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
import lombok.RequiredArgsConstructor;
import org.springframework.data.domain.Page;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

@Service
@RequiredArgsConstructor
public class ModelTrainMngCoreService {

  private final ModelMngRepository modelMngRepository;
  private final ModelDatasetRepository modelDatasetRepository;
  private final ModelDatasetMappRepository modelDatasetMapRepository;
  private final ModelConfigRepository modelConfigRepository;
  private final HyperParamRepository hyperParamRepository;
  private final DatasetRepository datasetRepository;
  private final UserUtil userUtil;

  /**
   * 모델 목록 조회
   *
   * @param searchReq 검색 조건
   * @return 페이징 처리된 모델 목록
   */
  public Page<ListDto> findByModelList(ModelTrainMngDto.SearchReq searchReq) {
    //    Page<ModelMasterEntity> entityPage = modelMngRepository.findByModels(searchReq);
    //    return entityPage.map(ModelMasterEntity::toDto);
    return modelMngRepository.findByModels(searchReq);
  }

  /**
   * 학습모델 삭제
   *
   * @param uuid
   */
  public void deleteModel(UUID uuid) {
    ModelMasterEntity entity =
        modelMngRepository
            .findByUuid(uuid)
            .orElseThrow(() -> new CustomApiException("NOT_FOUND_DATA", HttpStatus.NOT_FOUND));
    entity.setDelYn(true);
    entity.setUpdatedDttm(ZonedDateTime.now());
    entity.setUpdatedUid(userUtil.getId());
  }

  /**
   * 모델학습 저장
   *
   * @param addReq
   * @return
   */
  public ModelTrainMngDto.Basic saveModel(ModelTrainMngDto.AddReq addReq) {
    ModelMasterEntity entity = new ModelMasterEntity();
    ModelHyperParamEntity hyperParamEntity = new ModelHyperParamEntity();

    //     최적화 파라미터는 모델 type의 디폴트사용
    if (HyperParamSelectType.OPTIMIZED.getId().equals(addReq.getHyperParamType())) {
      ModelType modelType = ModelType.getValueData(addReq.getModelNo());
      hyperParamEntity =
          hyperParamRepository.getHyperParamByType(modelType).stream()
              .filter(e -> e.getIsDefault() == Boolean.TRUE)
              .findFirst()
              .orElse(null);
      //      hyperParamEntity = hyperParamRepository.findByHyperVer("HPs_0001").orElse(null);

    } else {
      hyperParamEntity =
          hyperParamRepository.findHyperParamByUuid(addReq.getHyperUuid()).orElse(null);
    }

    if (hyperParamEntity == null || hyperParamEntity.getHyperVer() == null) {
      throw new CustomApiException("NOT_FOUND_DATA", HttpStatus.NOT_FOUND);
    }
    // 하이퍼 파라미터 사용 횟수 업데이트
    hyperParamEntity.setTotalUseCnt(
        hyperParamEntity.getTotalUseCnt() == null ? 1 : hyperParamEntity.getTotalUseCnt() + 1);

    // 최근 사용일시 업데이트
    hyperParamEntity.setLastUsedDttm(ZonedDateTime.now());

    String modelVer =
        String.join(
            ".", addReq.getModelNo(), hyperParamEntity.getHyperVer(), entity.getUuid().toString());
    entity.setModelVer(modelVer);
    entity.setHyperParamId(hyperParamEntity.getId());
    entity.setModelNo(addReq.getModelNo());
    entity.setTrainType(addReq.getTrainType()); // 일반, 전이
    entity.setBeforeModelId(addReq.getBeforeModelId());

    // 전이학습일 때 beforeModelUuid 추가하기
    if (addReq.getBeforeModelId() != null) {
      ModelMasterEntity beforeModel =
          modelMngRepository
              .findById(addReq.getBeforeModelId())
              .orElseThrow(() -> new CustomApiException("NOT_FOUND_DATA", HttpStatus.NOT_FOUND));
      entity.setBeforeModelUuid(beforeModel.getUuid());
    }

    entity.setStatusCd(TrainStatusType.READY.getId());
    entity.setStep1State(TrainStatusType.READY.getId());

    entity.setCreatedUid(userUtil.getId());
    ModelMasterEntity resultEntity = modelMngRepository.save(entity);

    ModelTrainMngDto.Basic result = new ModelTrainMngDto.Basic();
    result.setId(resultEntity.getId());
    result.setUuid(resultEntity.getUuid());

    return result;
  }

  /**
   * data set 저장
   *
   * @param modelId 저장한 모델 학습 id
   * @param addReq 요청 파라미터
   */
  public void saveModelDataset(Long modelId, ModelTrainMngDto.AddReq addReq) {

    TrainingDataset dataset = addReq.getTrainingDataset();
    ModelMasterEntity modelMasterEntity = new ModelMasterEntity();
    ModelDatasetEntity datasetEntity = new ModelDatasetEntity();

    modelMasterEntity.setId(modelId);
    datasetEntity.setModel(modelMasterEntity);

    if (addReq.getModelNo().equals(ModelType.G1.getId())) {
      datasetEntity.setBuildingCnt(dataset.getSummary().getBuildingCnt());
      datasetEntity.setContainerCnt(dataset.getSummary().getContainerCnt());
    } else if (addReq.getModelNo().equals(ModelType.G2.getId())) {
      datasetEntity.setWasteCnt(dataset.getSummary().getWasteCnt());
    } else if (addReq.getModelNo().equals(ModelType.G3.getId())) {
      datasetEntity.setLandCoverCnt(dataset.getSummary().getLandCoverCnt());
    } else if (addReq.getModelNo().equals(ModelType.G4.getId())) {
      datasetEntity.setSolarCnt(dataset.getSummary().getSolarPanelCnt());
    }

    datasetEntity.setCreatedUid(userUtil.getId());

    // data set 저장
    modelDatasetRepository.save(datasetEntity);
  }

  /**
   * 학습모델 수정
   *
   * @param modelId
   * @param req
   */
  public void updateModelMaster(Long modelId, ModelTrainMngDto.UpdateReq req) {
    ModelMasterEntity entity =
        modelMngRepository
            .findById(modelId)
            .orElseThrow(() -> new CustomApiException("NOT_FOUND_DATA", HttpStatus.NOT_FOUND));
    // 임시폴더 UID업데이트
    if (req.getRequestPath() != null && !req.getRequestPath().isEmpty()) {
      entity.setRequestPath(req.getRequestPath());
    }

    entity.setTmpFileStatus(req.getTmpFileStatus());
    entity.setTmpFileEndDttm(req.getTmpFileEndDttm());
  }

  /**
   * 모델 데이터셋 mapping 테이블 저장
   *
   * @param modelId 모델학습 id
   * @param datasetList 선택한 data set
   */
  public void saveModelDatasetMap(Long modelId, List<Long> datasetList) {

    for (Long datasetId : datasetList) {
      ModelDatasetMappEntity mapEntity = new ModelDatasetMappEntity();
      mapEntity.setModelUid(modelId);
      mapEntity.setDatasetUid(datasetId);
      modelDatasetMapRepository.save(mapEntity);
    }
  }

  /**
   * 모델학습 config 저장
   *
   * @param modelId 모델학습 id
   * @param req 요청 파라미터
   * @return
   */
  public void saveModelConfig(Long modelId, ModelTrainMngDto.ModelConfig req) {
    ModelMasterEntity modelMasterEntity = new ModelMasterEntity();
    ModelConfigEntity entity = new ModelConfigEntity();
    modelMasterEntity.setId(modelId);
    entity.setModel(modelMasterEntity);
    entity.setEpochCount(
        req.getEpochCnt() < 10
            ? 10
            : req.getEpochCnt()); // 에폭이 10 이하이면 10으로 고정하기. 10 이상 에폭으로 해야 best 에폭 파일이 생성되어 내려옴
    entity.setTrainPercent(req.getTrainingCnt());
    entity.setValidationPercent(req.getValidationCnt());
    entity.setTestPercent(req.getTestCnt());
    entity.setMemo(req.getMemo());

    modelConfigRepository.save(entity);
  }

  // TODO 미사용시작
  /**
   * 데이터셋 매핑 생성
   *
   * @param modelUid 모델 UID
   * @param datasetIds 데이터셋 ID 목록
   */
  public void createDatasetMappings(Long modelUid, List<Long> datasetIds) {
    for (Long datasetId : datasetIds) {
      ModelDatasetMappEntity mapping = new ModelDatasetMappEntity();
      mapping.setModelUid(modelUid);
      mapping.setDatasetUid(datasetId);
      mapping.setDatasetType("TRAIN");
      modelDatasetMapRepository.save(mapping);
    }
  }

  // TODO 미사용 끝

  /**
   * UUID로 모델 조회
   *
   * @param uuid UUID
   * @return 모델 Entity
   */
  public ModelMasterEntity findByUuid(UUID uuid) {
    try {
      return modelMngRepository
          .findByUuid(uuid)
          .orElseThrow(() -> new CustomApiException("NOT_FOUND_DATA", HttpStatus.NOT_FOUND));
    } catch (IllegalArgumentException e) {
      throw new BadRequestException("잘못된 UUID 형식입니다: " + uuid);
    }
  }

  /**
   * uuid로 model id 조회
   *
   * @param uuid
   * @return
   */
  public Long findModelIdByUuid(UUID uuid) {
    ModelMasterEntity entity =
        modelMngRepository
            .findByUuid(uuid)
            .orElseThrow(() -> new CustomApiException("NOT_FOUND_DATA", HttpStatus.NOT_FOUND));
    return entity.getId();
  }

  /**
   * 모델학습 아이디로 config정보 조회
   *
   * @param uuid
   * @return
   */
  public ModelConfigDto.Basic findModelConfigByModelId(UUID uuid) {
    ModelMasterEntity modelEntity = findByUuid(uuid);
    return modelConfigRepository
        .findModelConfigByModelId(modelEntity.getId())
        .orElseThrow(() -> new CustomApiException("NOT_FOUND_DATA", HttpStatus.NOT_FOUND));
  }

  // TODO 미사용시작
  public ModelConfigDto.TransferBasic findModelTransferConfigByModelId(UUID uuid) {
    ModelMasterEntity modelEntity = findByUuid(uuid);
    return modelConfigRepository
        .findModelTransferConfigByModelId(modelEntity.getId())
        .orElseThrow(() -> new CustomApiException("NOT_FOUND_DATA", HttpStatus.NOT_FOUND));
  }

  // TODO 미사용 끝

  /**
   * 데이터셋 G1 목록
   *
   * @param req
   * @return
   */
  public List<SelectDataSet> getDatasetSelectG1List(DatasetReq req) {
    return datasetRepository.getDatasetSelectG1List(req);
  }

  // TODO 미사용시작
  /**
   * 전이학습 데이터셋 G1 목록
   *
   * @param modelId 모델 Id
   * @return
   */
  public List<SelectTransferDataSet> getDatasetTransferSelectG1List(Long modelId) {
    return datasetRepository.getDatasetTransferSelectG1List(modelId);
  }

  // TODO 미사용 끝

  /**
   * 데이터셋 G2, G3 목록
   *
   * @param req
   * @return
   */
  public List<SelectDataSet> getDatasetSelectG2G3List(DatasetReq req) {
    return datasetRepository.getDatasetSelectG2G3List(req);
  }

  // TODO 미사용시작
  /**
   * 전이학습 데이터셋 G2, G3 목록
   *
   * @param modelId 모델 Id
   * @param modelNo G2, G3
   * @return
   */
  public List<SelectTransferDataSet> getDatasetTransferSelectG2G3List(
      Long modelId, String modelNo) {
    return datasetRepository.getDatasetTransferSelectG2G3List(modelId, modelNo);
  }

  /**
   * 데이터셋 G4 목록
   *
   * @param req
   * @return
   */
  public List<SelectDataSet> getDatasetSelectG4List(DatasetReq req) {
    return datasetRepository.getDatasetSelectG4List(req);
  }

  // TODO 미사용 끝

  /**
   * 모델관리 조회
   *
   * @param id
   * @return
   */
  public ModelTrainMngDto.Basic findModelById(Long id) {
    ModelMasterEntity entity =
        modelMngRepository
            .findById(id)
            .orElseThrow(() -> new IllegalArgumentException("Model not found: " + id));
    return entity.toDto();
  }

  /**
   * 모델관리 조회
   *
   * @param uuid
   * @return
   */
  public ModelTrainMngDto.Basic findModelByUuid(UUID uuid) {
    ModelMasterEntity entity =
        modelMngRepository
            .findByUuid(uuid)
            .orElseThrow(() -> new IllegalArgumentException("Model not found: " + uuid));
    return entity.toDto();
  }

  /** 마스터를 IN_PROGRESS로 전환하고, 현재 실행 jobId를 연결 - UI/중단/상태조회 모두 currentAttemptId를 기준으로 동작 */
  @Transactional
  public void markInProgress(Long modelId, Long jobId) {
    ModelMasterEntity master =
        modelMngRepository
            .findById(modelId)
            .orElseThrow(() -> new IllegalArgumentException("Model not found: " + modelId));

    master.setStatusCd(TrainStatusType.IN_PROGRESS.getId());
    master.setCurrentAttemptId(jobId);

    // 필요하면 시작시간도 여기서 찍어줌
    modelMngRepository.flush();
  }

  /** 마지막 에러 메시지 초기화 - 재시작/새 실행 때 이전 에러 흔적 제거 */
  @Transactional
  public void clearLastError(Long modelId) {
    ModelMasterEntity master =
        modelMngRepository
            .findById(modelId)
            .orElseThrow(() -> new IllegalArgumentException("Model not found: " + modelId));

    master.setLastError(null);
    modelMngRepository.flush();
  }

  /** 중단 처리(옵션) - cancel에서 쓰려고 하면 같이 구현 */
  @Transactional
  public void markStopped(Long modelId) {
    ModelMasterEntity master =
        modelMngRepository
            .findById(modelId)
            .orElseThrow(() -> new IllegalArgumentException("Model not found: " + modelId));

    master.setStatusCd(TrainStatusType.STOPPED.getId());
    if (master.getStep2StrtDttm() != null) {
      master.setStep2State(TrainStatusType.STOPPED.getId());
    } else {
      master.setStep1State(TrainStatusType.STOPPED.getId());
    }
  }

  /** 완료 처리(옵션) - Worker가 성공 시 호출 */
  @Transactional
  public void markCompleted(Long modelId) {
    ModelMasterEntity master =
        modelMngRepository
            .findById(modelId)
            .orElseThrow(() -> new IllegalArgumentException("Model not found: " + modelId));

    master.setStatusCd(TrainStatusType.COMPLETED.getId());
  }

  /**
   * step 1오류 처리(옵션) - Worker가 실패 시 호출
   *
   * @param modelId
   * @param errorMessage
   */
  @Transactional
  public void markError(Long modelId, String errorMessage) {
    ModelMasterEntity master =
        modelMngRepository
            .findById(modelId)
            .orElseThrow(() -> new IllegalArgumentException("Model not found: " + modelId));

    master.setStatusCd(TrainStatusType.ERROR.getId());
    master.setStep1State(TrainStatusType.ERROR.getId());
    master.setLastError(errorMessage);
    master.setUpdatedUid(userUtil.getId());
    master.setUpdatedDttm(ZonedDateTime.now());
  }

  /**
   * step 2오류 처리(옵션) - Worker가 실패 시 호출
   *
   * @param modelId
   * @param errorMessage
   */
  @Transactional
  public void markStep2Error(Long modelId, String errorMessage) {
    ModelMasterEntity master =
        modelMngRepository
            .findById(modelId)
            .orElseThrow(() -> new IllegalArgumentException("Model not found: " + modelId));

    master.setStatusCd(TrainStatusType.ERROR.getId());
    master.setStep2State(TrainStatusType.ERROR.getId());
    master.setLastError(errorMessage);
    master.setUpdatedUid(userUtil.getId());
    master.setUpdatedDttm(ZonedDateTime.now());
  }

  /**
   * step1 정지 처리
   *
   * @param modelId
   * @param errorMessage
   */
  public void markStep1Stop(Long modelId, String errorMessage) {
    ModelMasterEntity master =
        modelMngRepository
            .findById(modelId)
            .orElseThrow(() -> new IllegalArgumentException("Model not found: " + modelId));

    master.setStatusCd(TrainStatusType.STOPPED.getId());
    master.setStep1State(TrainStatusType.STOPPED.getId());
    master.setLastError(errorMessage);
    master.setUpdatedUid(userUtil.getId());
    master.setUpdatedDttm(ZonedDateTime.now());
  }

  /**
   * step2 정지 처리
   *
   * @param modelId
   * @param errorMessage
   */
  public void markStep2Stop(Long modelId, String errorMessage) {
    ModelMasterEntity master =
        modelMngRepository
            .findById(modelId)
            .orElseThrow(() -> new IllegalArgumentException("Model not found: " + modelId));

    master.setStatusCd(TrainStatusType.STOPPED.getId());
    master.setStep2State(TrainStatusType.STOPPED.getId());
    master.setLastError(errorMessage);
    master.setUpdatedUid(userUtil.getId());
    master.setUpdatedDttm(ZonedDateTime.now());
  }

  @Transactional
  public void markSuccess(Long modelId) {
    ModelMasterEntity master =
        modelMngRepository
            .findById(modelId)
            .orElseThrow(() -> new IllegalArgumentException("Model not found: " + modelId));

    // 모델 상태 완료 처리
    master.setStatusCd(TrainStatusType.COMPLETED.getId());

    // (선택) 마지막 에러 메시지 비우기
    master.setLastError(null);
  }

  /**
   * 학습 실행에 필요한 파라미터 조회
   *
   * @param modelId
   * @return
   */
  public TrainRunRequest findTrainRunRequest(Long modelId) {
    return modelMngRepository.findTrainRunRequest(modelId);
  }

  /**
   * step1 진행중 처리
   *
   * @param modelId
   * @param jobId
   */
  @Transactional(propagation = Propagation.REQUIRES_NEW)
  public void markStep1InProgress(Long modelId, Long jobId) {
    ModelMasterEntity entity =
        modelMngRepository
            .findById(modelId)
            .orElseThrow(() -> new IllegalArgumentException("Model not found: " + modelId));

    entity.setStatusCd(TrainStatusType.IN_PROGRESS.getId());
    entity.setStrtDttm(ZonedDateTime.now());
    entity.setStep1StrtDttm(ZonedDateTime.now());
    entity.setStep1State(TrainStatusType.IN_PROGRESS.getId());
    entity.setCurrentAttemptId(jobId);
    entity.setUpdatedDttm(ZonedDateTime.now());
    entity.setUpdatedUid(userUtil.getId());
  }

  /**
   * step2 진행중 처리
   *
   * @param modelId
   */
  @Transactional(propagation = Propagation.REQUIRES_NEW)
  public void markStep2InProgress(Long modelId, Long jobId) {
    ModelMasterEntity entity =
        modelMngRepository
            .findById(modelId)
            .orElseThrow(() -> new IllegalArgumentException("Model not found: " + modelId));

    entity.setStatusCd(TrainStatusType.IN_PROGRESS.getId());
    entity.setStep2StrtDttm(ZonedDateTime.now());
    entity.setStep2State(TrainStatusType.IN_PROGRESS.getId());
    entity.setCurrentAttemptId(jobId);
    entity.setUpdatedDttm(ZonedDateTime.now());
    entity.setUpdatedUid(userUtil.getId());
  }

  /**
   * step1 완료처리
   *
   * @param modelId
   */
  @Transactional(propagation = Propagation.REQUIRES_NEW)
  public void markStep1Success(Long modelId) {
    ModelMasterEntity entity =
        modelMngRepository
            .findById(modelId)
            .orElseThrow(() -> new IllegalArgumentException("Model not found: " + modelId));

    entity.setStatusCd(TrainStatusType.COMPLETED.getId());
    entity.setStep1State(TrainStatusType.COMPLETED.getId());
    entity.setStep1EndDttm(ZonedDateTime.now());
    entity.setUpdatedDttm(ZonedDateTime.now());
    entity.setUpdatedUid(userUtil.getId());
  }

  /**
   * step2 완료처리
   *
   * @param modelId
   */
  @Transactional(propagation = Propagation.REQUIRES_NEW)
  public void markStep2Success(Long modelId) {
    ModelMasterEntity entity =
        modelMngRepository
            .findById(modelId)
            .orElseThrow(() -> new IllegalArgumentException("Model not found: " + modelId));

    entity.setStatusCd(TrainStatusType.COMPLETED.getId());
    entity.setStep2State(TrainStatusType.COMPLETED.getId());
    entity.setStep2EndDttm(ZonedDateTime.now());
    entity.setUpdatedDttm(ZonedDateTime.now());
    entity.setUpdatedUid(userUtil.getId());
  }

  public void updateModelMasterBestEpoch(Long modelId, int epoch) {
    ModelMasterEntity entity =
        modelMngRepository
            .findById(modelId)
            .orElseThrow(() -> new IllegalArgumentException("Model not found: " + modelId));

    entity.setBestEpoch(epoch);
  }

  /**
   * 데이터셋 uid 조회
   *
   * @param datasetIds
   * @return
   */
  public List<String> findDatasetUid(List<Long> datasetIds) {
    return datasetRepository.findDatasetUid(datasetIds);
  }

  public List<Long> findModelDatasetMapp(Long modelId) {
    List<Long> datasetUids = new ArrayList<>();
    List<ModelDatasetMappEntity> entities = modelDatasetMapRepository.findByModelUid(modelId);
    for (ModelDatasetMappEntity entity : entities) {
      datasetUids.add(entity.getDatasetUid());
    }

    return datasetUids;
  }

  public Long findModelStep1InProgressCnt() {
    return modelMngRepository.findModelStep1InProgressCnt();
  }

  /**
   * train 링크할 파일 경로
   *
   * @param modelId
   * @return
   */
  public List<ModelTrainLinkDto> findDatasetTrainPath(Long modelId) {
    return modelDatasetMapRepository.findDatasetTrainPath(modelId);
  }

  /**
   * validation 링크할 파일 경로
   *
   * @param modelId
   * @return
   */
  public List<ModelTrainLinkDto> findDatasetValPath(Long modelId) {
    return modelDatasetMapRepository.findDatasetValPath(modelId);
  }

  /**
   * test 링크할 파일 경로
   *
   * @param modelId
   * @return
   */
  public List<ModelTrainLinkDto> findDatasetTestPath(Long modelId) {
    return modelDatasetMapRepository.findDatasetTestPath(modelId);
  }

  public void updateTrainRequestPath(Long modelId, String datasetUid) {
    ModelMasterEntity entity =
        modelMngRepository
            .findById(modelId)
            .orElseThrow(() -> new CustomApiException("NOT_FOUND_DATA", HttpStatus.NOT_FOUND));

    // 임시폴더 UID업데이트
    entity.setRequestPath(datasetUid);
    entity.setReqTmpYn(false); // false 인 것은 train, test 실행 시 docker 명령어에 request 폴더를 바라보게 할 예정
  }

  public void updateTmpFileStatusStart(Long modelId) {
    ModelMasterEntity entity =
        modelMngRepository
            .findById(modelId)
            .orElseThrow(() -> new CustomApiException("NOT_FOUND_DATA", HttpStatus.NOT_FOUND));

    entity.setReqTmpYn(true);
    entity.setTmpFileStatus("IN_PROGRESS");
    entity.setTmpFileStartDttm(ZonedDateTime.now());
  }

  public void updateTmpFileStatusFail(Long modelId, String message) {
    ModelMasterEntity entity =
        modelMngRepository
            .findById(modelId)
            .orElseThrow(() -> new CustomApiException("NOT_FOUND_DATA", HttpStatus.NOT_FOUND));

    entity.setTmpFileStatus("FAIL");
    entity.setTmpFileErrMessage(message);
  }

  public ModelTrainMngDto.InProgressModel findInprogressModel() {
    return modelMngRepository.findInprogressModel();
  }

  public ModelTrainMngDto.ProgressPercent findTrainProgressPercent(UUID uuid) {
    ModelMasterEntity entity =
        modelMngRepository
            .findByUuid(uuid)
            .orElseThrow(() -> new CustomApiException("NOT_FOUND_DATA", HttpStatus.NOT_FOUND));

    return modelMngRepository.findTrainProgressPercent(entity.getId());
  }
}
