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

import com.kamco.cd.kamcoback.mapsheet.dto.ImageryDto;
import com.kamco.cd.kamcoback.mapsheet.dto.MapSheetMngDto;
import com.kamco.cd.kamcoback.postgres.entity.MapSheetMngHstEntity;
import com.kamco.cd.kamcoback.postgres.repository.mapsheet.MapSheetMngRepository;
import jakarta.persistence.EntityNotFoundException;
import jakarta.validation.Valid;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.domain.Page;
import org.springframework.stereotype.Service;

@Service
@RequiredArgsConstructor
public class MapSheetMngCoreService {

  private final MapSheetMngRepository mapSheetMngRepository;

  private static final String ORIGINAL_IMAGES_PATH = "/app/original-images";

  @Value("{spring.profiles.active}")
  private String activeEnv;

  public Page<MapSheetMngDto.ErrorDataDto> findMapSheetErrorList(
      MapSheetMngDto.@Valid searchReq searchReq) {
    return mapSheetMngRepository.findMapSheetErrorList(searchReq);
  }

  public Page<MapSheetMngDto.MngDto> findMapSheetMngList(
      MapSheetMngDto.@Valid searchReq searchReq) {
    return mapSheetMngRepository.findMapSheetMngList(searchReq);
  }

  public MapSheetMngDto.DmlReturn uploadProcess(@Valid List<Long> hstUidList) {
    int count = 0;
    if (!Objects.isNull(hstUidList) && !hstUidList.isEmpty()) {
      for (Long hstUid : hstUidList) {
        Optional<MapSheetMngHstEntity> entity =
            Optional.ofNullable(
                mapSheetMngRepository
                    .findMapSheetMngHstInfo(hstUid)
                    .orElseThrow(EntityNotFoundException::new));

        // TODO: local TEST 시 각자 경로 수정하기
        // TODO: application.yml 에 active profile : local 로 임시 변경하여 테스트
        String localPath = "";
        // String localPath = "C:\\Users\\gypark\\Desktop\\file";
        String rootDir = ORIGINAL_IMAGES_PATH + "/" + entity.get().getMngYyyy();
        if (activeEnv.equals("local")) {
          rootDir = localPath + rootDir;
        }

        String filename = entity.get().getMapSheetNum();
        String[] extensions = {"tif", "tfw"};
        boolean flag = allExtensionsExist(rootDir, filename, extensions);
        if (flag) {
          count += 1;
        }

        MapSheetMngDto.DataState dataState =
            flag ? MapSheetMngDto.DataState.SUCCESS : MapSheetMngDto.DataState.FAIL;
        entity.get().updateDataState(dataState);
      }
    }
    return new MapSheetMngDto.DmlReturn("success", count + "개 업로드 성공하였습니다.");
  }

  public MapSheetMngDto.DmlReturn updateExceptUseInference(@Valid List<Long> hstUidList) {
    if (!Objects.isNull(hstUidList) && !hstUidList.isEmpty()) {
      for (Long hstUid : hstUidList) {
        Optional<MapSheetMngHstEntity> entity =
            Optional.ofNullable(
                mapSheetMngRepository
                    .findMapSheetMngHstInfo(hstUid)
                    .orElseThrow(EntityNotFoundException::new));

        entity.get().updateUseInference(true);
      }
    }
    return new MapSheetMngDto.DmlReturn("success", hstUidList.size() + "개 추론제외 업데이트 하였습니다.");
  }

  /**
   * 특정 파일명 + 여러 확장자가 모두 존재하는지 확인
   *
   * @param rootDir 검색할 최상위 디렉토리
   * @param filename 파일명 (확장자 제외)
   * @param extensions 확인할 확장자 배열 (예: {"tif", "tfw"})
   * @return 모든 확장자가 존재하면 true, 하나라도 없으면 false
   */
  public static boolean allExtensionsExist(String rootDir, String filename, String... extensions) {
    try (Stream<Path> paths = Files.walk(Paths.get(rootDir))) {

      // 모든 파일명을 Set으로 저장
      Set<String> fileNames =
          paths
              .filter(Files::isRegularFile)
              .map(p -> p.getFileName().toString())
              .collect(Collectors.toSet());

      // 모든 확장자 파일 존재 여부 확인
      for (String ext : extensions) {
        String target = filename + "." + ext;
        if (!fileNames.contains(target)) {
          return false; // 하나라도 없으면 false
        }
      }

      return true; // 모두 존재하면 true

    } catch (IOException e) {
      throw new RuntimeException("File search error", e);
    }
  }


  public MapSheetMngDto.DmlReturn syncProcess(ImageryDto.searchReq searchReq) {
    int count = 0;

    //대상파일목록 가저오기
    Page<ImageryDto.SyncDto>  pageImagerySyncDto = mapSheetMngRepository.findImageryList(searchReq);
    //List<ImagerySyncDto> imagerySyncDtoList = pageImagerySyncDto.getContent();

    for (ImageryDto.SyncDto dto : pageImagerySyncDto.getContent()) {
      // 여기에 처리 로직 작성
      System.out.println("ID: " + dto.getId());

      // 예: 특정 작업 수행
      // someService.process(dto);
    }


    return new MapSheetMngDto.DmlReturn("success", count + "개 업로드 성공하였습니다.");
  }

}
