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

import com.kamco.cd.kamcoback.common.enums.MngStateType;
import com.kamco.cd.kamcoback.common.enums.SyncStateType;
import com.kamco.cd.kamcoback.common.utils.Enums;
import com.kamco.cd.kamcoback.common.utils.interfaces.JsonFormatDttm;
import io.swagger.v3.oas.annotations.media.Schema;
import java.time.ZonedDateTime;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;

public class MapSheetMngDto {

  @Schema(name = "MngSearchReq", description = "영상관리 검색 요청")
  @Getter
  @Setter
  @NoArgsConstructor
  @AllArgsConstructor
  public static class MngSearchReq {

    // 페이징 파라미터
    @Schema(description = "페이지 번호 (0부터 시작) ", example = "0")
    private int page = 0;

    @Schema(description = "페이지 크기", example = "20")
    private int size = 20;

    @Schema(description = "년도", example = "2025")
    private Integer mngYyyy;

    public Pageable toPageable() {
      return PageRequest.of(page, size);
    }
  }

  @Schema(name = "MngAddReq", description = "영상관리 생성 요청")
  @Getter
  @Setter
  @NoArgsConstructor
  @AllArgsConstructor
  public static class AddReq {
    @Schema(description = "관리년도", example = "2022")
    private int mngYyyy;

    @Schema(description = "선택폴더경로", example = "D:\\app\\original-images\\2022")
    private String mngPath;
  }

  @Schema(name = "DeleteFileReq", description = "파일 삭제 요청")
  @Getter
  @Setter
  @NoArgsConstructor
  @AllArgsConstructor
  public static class DeleteFileReq {
    @Schema(description = "파일 경로", example = "/app/original-images/2024/00000001.tif")
    private String filePath;
  }

  @Schema(name = "MngDto", description = "영상관리 검색 리턴")
  @Getter
  @Setter
  @NoArgsConstructor
  @AllArgsConstructor
  public static class MngDto {
    private int rowNum;
    private int mngYyyy;
    private String mngState;
    private String syncState;
    private String syncDataCheckState;
    private Long syncTotCnt;
    private Long syncStateDoneCnt;
    private Long syncDataCheckDoneCnt;
    private Long syncNotPaireCnt;
    private Long syncNotPaireExecCnt;
    private Long syncDuplicateCnt;
    private Long syncDuplicateExecCnt;
    private Long syncFaultCnt;
    private Long syncFaultExecCnt;
    @JsonFormatDttm private ZonedDateTime rgstStrtDttm;
    @JsonFormatDttm private ZonedDateTime rgstEndDttm;

    public double getSyncStateDoneRate() {
      if (this.syncTotCnt == null || this.syncTotCnt == 0) {
        return 0.0;
      }
      return (double) this.syncStateDoneCnt / this.syncTotCnt * 100.0;
    }

    public double getSyncDataCheckDoneRate() {
      if (this.syncTotCnt == null || this.syncTotCnt == 0) {
        return 0.0;
      }
      return (double) this.syncDataCheckDoneCnt / this.syncTotCnt * 100.0;
    }

    public long getSyncErrorTotCnt() {
      return this.syncNotPaireCnt + this.syncDuplicateCnt + this.syncFaultCnt;
    }

    public long getSyncErrorExecTotCnt() {
      return this.syncNotPaireExecCnt + this.syncDuplicateExecCnt + this.syncFaultExecCnt;
    }

    public String getMngStateName() {
      String enumId = this.mngState;
      if (enumId == null || enumId.isEmpty()) enumId = "NOTYET";

      MngStateType type = Enums.fromId(MngStateType.class, enumId);
      return type.getText();
    }
  }

  @Schema(name = "ErrorSearchReq", description = "영상관리 오류데이터 검색 요청")
  @Getter
  @Setter
  @NoArgsConstructor
  @AllArgsConstructor
  public static class ErrorSearchReq {

    // 페이징 파라미터
    @Schema(description = "페이지 번호 (0부터 시작) ", example = "0")
    private int page = 0;

    @Schema(description = "페이지 크기", example = "20")
    private int size = 20;

    @Schema(description = "정렬", example = "id desc")
    private String sort;

    @Schema(description = "오류종류(페어누락:NOTPAIR,중복파일:DUPLICATE,손상파일:FAULT)", example = "NOTPAIR")
    private String syncState;

    @Schema(description = "처리유형(처리:DONE,미처리:NOTYET)", example = "DONE")
    private String syncCheckState;

    @Schema(description = "검색어", example = "부산3959")
    private String searchValue;

    @Schema(description = "년도", example = "2025")
    private Integer mngYyyy;

    public Pageable toPageable() {
      if (sort != null && !sort.isEmpty()) {
        String[] sortParams = sort.split(",");
        String property = sortParams[0];
        Sort.Direction direction =
            sortParams.length > 1 ? Sort.Direction.fromString(sortParams[1]) : Sort.Direction.ASC;
        return PageRequest.of(page, size, Sort.by(direction, property));
      }
      return PageRequest.of(page, size);
    }
  }

  @Schema(name = "ErrorDataDto", description = "영상관리 오류데이터 검색 리턴")
  @Getter
  @Setter
  public static class ErrorDataDto {
    // private Integer rowNum;
    private Long hstUid;
    private String mapSheetNum;
    private String map50kName;
    private String map5kName;
    private String mapSrcName;
    private Integer mapCodeSrc;
    @JsonFormatDttm private ZonedDateTime createdDttm;

    private String syncState;
    private String syncStateName;
    private String syncTfwFileName;
    private String syncTifFileName;

    private String errorCheckState;
    private String errorCheckStateName;
    private String errorCheckTfwFileName;
    private String errorCheckTifFileName;

    // private List<MngFIleDto> fileArray;

    public ErrorDataDto(
        Long hstUid,
        String map50kName,
        String map5kName,
        String mapSrcName,
        Integer mapCodeSrc,
        ZonedDateTime createdDttm,
        String syncState,
        String syncTfwFileName,
        String syncTifFileName,
        String errorCheckState,
        String errorCheckTfwFileName,
        String errorCheckTifFileName) {
      this.hstUid = hstUid;
      this.map50kName = map50kName;
      this.map5kName = map5kName;
      this.mapSrcName = mapSrcName;
      this.mapCodeSrc = mapCodeSrc;
      this.createdDttm = createdDttm;
      this.syncState = syncState;
      this.syncStateName = getSyncStateName(syncState);
      this.syncTfwFileName = syncTfwFileName;
      this.syncTifFileName = syncTifFileName;
      this.errorCheckState = errorCheckState;
      this.errorCheckStateName = getSyncStateName(errorCheckState);
      this.errorCheckTfwFileName = errorCheckTfwFileName;
      this.errorCheckTifFileName = errorCheckTifFileName;
    }

    private String getSyncStateName(String enumId) {
      if (enumId == null || enumId.isEmpty()) enumId = "NOTYET";

      SyncStateType type = Enums.fromId(SyncStateType.class, enumId);
      return type.getText();
    }
  }

  @Schema(name = "MngFIleDto", description = "관리파일정보")
  @Getter
  @Setter
  public static class MngFIleDto {
    private Long fileUid;
    private String filePath;
    private String fileName;
    private Long fileSize;
    private String fileState;
    private Long hstUid;
  }

  @Schema(name = "DmlReturn", description = "영상관리 DML 수행 후 리턴")
  @Getter
  @Setter
  @NoArgsConstructor
  @AllArgsConstructor
  public static class DmlReturn {
    private String flag;
    private String message;
  }

  @Schema(name = "MngFilesDto", description = "영상파일내역 검색 리턴")
  @Getter
  @Setter
  @NoArgsConstructor
  @AllArgsConstructor
  public static class MngFilesDto {
    private long fileUid;
    private int mngYyyy;
    private String mapSheetNum;
    private String refMapSheetNum;
    private String filePath;
    private String fileName;
    private String fileExt;
    private Long hstUid;
    private Long fileSize;
  }
}
