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

import com.kamco.cd.kamcoback.inference.dto.InferenceResultShpDto;
import com.kamco.cd.kamcoback.postgres.entity.MapSheetAnalDataInferenceGeomEntity;
import com.kamco.cd.kamcoback.postgres.repository.Inference.InferenceResultRepository;
import java.util.List;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

@Service
@RequiredArgsConstructor
public class InferenceResultShpCoreService {

  private final InferenceResultRepository repo;

  /**
   * inference_results 기준으로 - tb_map_sheet_anal_data_inference -
   * tb_map_sheet_anal_data_inference_geom 테이블을 최신 상태로 구성한다.
   */
  @Transactional
  public InferenceResultShpDto.InferenceCntDto buildInferenceData() {
    int sheetAnalDataCnt = repo.upsertGroupsFromMapSheetAnal();
    int inferenceCnt = repo.upsertGroupsFromInferenceResults();
    int inferenceGeomCnt = repo.upsertGeomsFromInferenceResults();

    InferenceResultShpDto.InferenceCntDto cntDto = new InferenceResultShpDto.InferenceCntDto();
    cntDto.setSheetAnalDataCnt(sheetAnalDataCnt);
    cntDto.setInferenceCnt(inferenceCnt);
    cntDto.setInferenceGeomCnt(inferenceGeomCnt);

    return cntDto;
  }

  /** 파일 생성이 완료되지 않은 분석 데이터(data_uid) 목록을 조회한다. */
  @Transactional(readOnly = true)
  public List<Long> findPendingDataUids(int limit) {
    return repo.findPendingDataUids(limit);
  }

  /**
   * 분석 데이터 재생성을 위해 기존 파일 생성 상태를 초기화한다.
   *
   * <p>- 분석 데이터(file_created_yn)를 미생성 상태로 변경 - 해당 분석 데이터에 속한 모든 도형의 생성 상태를 미생성으로 변경
   */
  @Transactional
  public void resetForRegenerate(Long dataUid) {
    repo.resetInferenceCreated(dataUid);
    repo.resetGeomCreatedByDataUid(dataUid);
  }

  /**
   * 지정된 분석 데이터에 속한 도형 정보를 조회한다.
   *
   * <p>- 파일 미생성 상태의 도형만 대상 - geometry가 존재하는 도형만 조회
   */
  @Transactional(readOnly = true)
  public List<InferenceResultShpDto.Basic> loadGeomDtos(Long dataUid, int limit) {
    List<MapSheetAnalDataInferenceGeomEntity> entities =
        repo.findGeomEntitiesByDataUid(dataUid, limit);

    return entities.stream().map(InferenceResultShpDto.Basic::from).toList();
  }

  /**
   * 파일 생성이 성공한 도형 및 분석 데이터에 대해 생성 완료 상태로 갱신한다.
   *
   * @param dataUid 분석 데이터 UID
   * @param geoUids 파일 생성이 완료된 도형 UID 목록
   */
  @Transactional
  public void markSuccess(Long dataUid, List<Long> geoUids) {
    repo.markGeomCreatedByGeoUids(geoUids);
    repo.markInferenceCreated(dataUid);
  }
}
