package com.kamco.cd.kamcoback.mapsheet.service;

import com.kamco.cd.kamcoback.common.utils.FIleChecker;
import com.kamco.cd.kamcoback.config.FileConfig;
import com.kamco.cd.kamcoback.mapsheet.dto.MapSheetMngDto;
import com.kamco.cd.kamcoback.mapsheet.dto.MapSheetMngDto.*;
import com.kamco.cd.kamcoback.postgres.core.MapSheetMngCoreService;
import jakarta.validation.Valid;
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardCopyOption;
import java.util.List;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.domain.Page;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

@Slf4j
@Service
@RequiredArgsConstructor
@Transactional(readOnly = true)
public class MapSheetMngService {

  private final MapSheetMngCoreService mapSheetMngCoreService;
  private final FileConfig fileConfig;

  public List<MngDto> findMapSheetMngList() {
    return mapSheetMngCoreService.findMapSheetMngList();
  }

  public List<Integer> findMapSheetMngYyyyList() {
    return mapSheetMngCoreService.findMapSheetMngYyyyList();
  }

  public MngDto findMapSheetMng(int mngYyyy) {
    return mapSheetMngCoreService.findMapSheetMng(mngYyyy);
  }

  @Transactional
  public DmlReturn mngComplete(int mngYyyy) {

    mapSheetMngCoreService.MapSheetMngComplete(mngYyyy);

    return new DmlReturn("success", "작업완료 처리되었습니다.");
  }

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

  public ErrorDataDto findMapSheetError(Long hstUid) {
    return mapSheetMngCoreService.findMapSheetError(hstUid);
  }

  @Transactional
  public DmlReturn mngDataSave(AddReq AddReq) {
    return mapSheetMngCoreService.mngDataSave(AddReq);
  }

  public DmlReturn uploadProcess(@Valid List<Long> hstUidList) {
    return mapSheetMngCoreService.uploadProcess(hstUidList);
  }

  public DmlReturn updateExceptUseInference(@Valid List<Long> hstUidList) {
    return mapSheetMngCoreService.updateExceptUseInference(hstUidList);
  }

  @Transactional
  public DmlReturn uploadPair(MultipartFile tfwFile, MultipartFile tifFile, Long hstUid) {

    String rootPath = fileConfig.getRootSyncDir();
    String tmpPath = fileConfig.getTmpSyncDir();

    ErrorDataDto errDto = mapSheetMngCoreService.findMapSheetError(hstUid);
    if (errDto == null) {
      return new DmlReturn("fail", "NO hstUid Data");
    }

    // 파일검증용 임시저장 폴더 확인
    log.info("TmpPath > {}", tmpPath);
    if (!FIleChecker.mkDir(tmpPath)) {
      return new DmlReturn("fail", "CREATE TEMP FOLDER ERROR");
    }

    // 파일 유효성 검증
    if (tfwFile == null || tfwFile.isEmpty() || tfwFile.getSize() == 0) {
      return new DmlReturn("fail", "TFW SIZE 오류");
    } else if (tifFile == null || tifFile.isEmpty() || tifFile.getSize() == 0) {
      return new DmlReturn("fail", "TIF SIZE 오류");
    }

    // 확장자명 체크
    if (!FIleChecker.checkExtensions(tfwFile.getOriginalFilename(), "tfw")) {
      return new DmlReturn("fail", "TFW FILENAME ERROR");
    } else if (!FIleChecker.checkExtensions(tifFile.getOriginalFilename(), "tif")) {
      return new DmlReturn("fail", "TIF FILENAME ERROR");
    }

    MngDto mngDto = mapSheetMngCoreService.findMapSheetMng(errDto.getMngYyyy());
    String targetYearDir = mngDto.getMngPath();

    // 중복체크
    List<FIleChecker.Basic> basicTfwList =
        FIleChecker.getFilesFromAllDepth(targetYearDir, tfwFile.getOriginalFilename(), "tfw");

    List<FIleChecker.Basic> basicTifList =
        FIleChecker.getFilesFromAllDepth(targetYearDir, tifFile.getOriginalFilename(), "tif");

    int tfwCnt =
        (int)
            basicTfwList.stream()
                .filter(dto -> dto.getExtension().toString().equals("tfw"))
                .count();

    int tifCnt =
        (int)
            basicTifList.stream()
                .filter(dto -> dto.getExtension().toString().equals("tif"))
                .count();

    if (tfwCnt > 0 || tifCnt > 0) {
      String tfwtifMsg = "";
      if (tfwCnt > 0) {
        tfwtifMsg = tfwFile.getOriginalFilename();
      }
      if (tifCnt > 0) {
        if (tfwCnt > 0) {
          tfwtifMsg = "," + tifFile.getOriginalFilename();
        } else {
          tfwtifMsg = tifFile.getOriginalFilename();
        }
      }
      return new DmlReturn("duplicate", tfwtifMsg);
    }

    File directory = new File(tmpPath);
    String tfwTmpPath = tmpPath + tfwFile.getOriginalFilename();
    Path tfwTmpSavePath = Paths.get(tfwTmpPath);
    String tifTmpPath = tmpPath + tifFile.getOriginalFilename();
    Path tifTmpSavePath = Paths.get(tifTmpPath);
    boolean fileUpload = true;
    try {
      tfwFile.transferTo(tfwTmpSavePath);
      tifFile.transferTo(tifTmpSavePath);
    } catch (IOException e) {
      // throw new RuntimeException(e);
      return new DmlReturn("fail", "UPLOAD ERROR");
    }

    if (!FIleChecker.cmmndGdalInfo(tifTmpPath)) {
      return new DmlReturn("fail", "TIF TYPE ERROR");
    }
    if (!FIleChecker.checkTfw(tfwTmpPath)) {
      return new DmlReturn("fail", "TFW TYPE ERROR");
    }

    // 싱크파일목록으로 업로드 경로 확인
    List<MngFilesDto> mngFiles = mapSheetMngCoreService.findIdToMapSheetFileList(hstUid);
    String uploadPath = "";
    for (MngFilesDto dto : mngFiles) {
      uploadPath = dto.getFilePath();
      break;
    }

    Path tfwTargetPath = null;
    Path tifTargetPath = null;

    // 파일이 존재하지 않을 경우(0개) 해당년도 다른 파일경로로 참조
    if (uploadPath.isEmpty()) {
      MngFilesDto filesDto =
          mapSheetMngCoreService.findYyyyToMapSheetFilePathRefer(errDto.getMngYyyy());
      if (filesDto != null) {
        String referPath = filesDto.getFilePath();
        uploadPath = Paths.get(referPath).getParent().toString() + "/" + errDto.getRefMapSheetNum();
        tfwTargetPath = Paths.get(uploadPath).resolve(tfwFile.getOriginalFilename());
        tifTargetPath = Paths.get(uploadPath).resolve(tifFile.getOriginalFilename());
      }
    }

    // 업로드 경로 확인(없으면 생성)
    if (!FIleChecker.mkDir(uploadPath)) {
      return new DmlReturn("fail", "CREATE FOLDER ERROR");
    }

    try {
      Files.move(tfwTmpSavePath, tfwTargetPath, StandardCopyOption.REPLACE_EXISTING);
      Files.move(tifTmpSavePath, tifTargetPath, StandardCopyOption.REPLACE_EXISTING);
    } catch (IOException e) {
      throw new RuntimeException(e);
    }

    // hst업데이트
    MapSheetMngDto.SyncCheckStateReqUpdateDto updReqSyncCheckState =
        new MapSheetMngDto.SyncCheckStateReqUpdateDto();
    updReqSyncCheckState.setHstUid(hstUid);
    updReqSyncCheckState.setFilePath(uploadPath);
    updReqSyncCheckState.setSyncCheckTfwFileName(tfwFile.getOriginalFilename());
    updReqSyncCheckState.setSyncCheckTifFileName(tifFile.getOriginalFilename());
    updReqSyncCheckState.setSyncCheckState("DONE");
    mapSheetMngCoreService.updateMapSheetMngHstSyncCheckState(updReqSyncCheckState);
    // 파일정보 업데이트
    mapSheetMngCoreService.deleteByHstUidMngFile(hstUid);

    MapSheetMngDto.MngFileAddReq addReq = new MapSheetMngDto.MngFileAddReq();
    addReq.setMngYyyy(errDto.getMngYyyy());
    addReq.setMapSheetNum(errDto.getMapSheetNum());
    addReq.setRefMapSheetNum(errDto.getRefMapSheetNum());
    addReq.setFilePath(uploadPath);
    addReq.setFileName(tfwFile.getOriginalFilename());
    addReq.setFileExt("tfw");
    addReq.setFileSize(tfwFile.getSize());
    addReq.setHstUid(errDto.getHstUid());
    addReq.setFileState("DONE");

    mapSheetMngCoreService.mngFileSave(addReq);

    addReq.setFileExt("tif");
    addReq.setFileSize(tifFile.getSize());
    mapSheetMngCoreService.mngFileSave(addReq);

    return new DmlReturn("success", "파일 업로드 완료되었습니다.");
  }

  public List<MngFilesDto> findHstUidToMapSheetFileList(Long hstUid) {
    return mapSheetMngCoreService.findHstUidToMapSheetFileList(hstUid);
  }

  @Transactional
  public DmlReturn deleteByFileUidMngFile(List<Long> fileUids) {

    long hstUid = 0;
    // hstUid = 149049;

    for (Long uid : fileUids) {
      MapSheetMngDto.MngFilesDto dto = mapSheetMngCoreService.findIdToMapSheetFile(uid);
      hstUid = dto.getHstUid();

      String filePath = dto.getFilePath() + "/" + dto.getFileName();
      Path path = Paths.get(filePath);
      try {
        boolean isDeleted = Files.deleteIfExists(path);
        if (isDeleted) {
          System.out.println("파일 삭제 성공: " + filePath);
        } else {
          System.out.println("삭제 실패: 파일이 존재하지 않습니다.");
        }
      } catch (IOException e) {
        System.err.println("파일 삭제 중 오류 발생: " + e.getMessage());
      }
      DmlReturn dmlReturn = mapSheetMngCoreService.deleteByFileUidMngFile(uid);
    }

    // 중복제거 확인후 처리상태(DONE)변경
    if (hstUid > 0) {
      mapSheetMngCoreService.updateByHstUidSyncCheckState(hstUid);
    }

    return new DmlReturn("success", fileUids.size() + "개 파일이 삭제되었습니다.");
  }
}
