package com.kamco.cd.training.dataset.dto;

import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.kamco.cd.training.common.enums.DetectionClassification;
import com.kamco.cd.training.common.utils.HeaderUtil;
import com.kamco.cd.training.common.utils.interfaces.JsonFormatDttm;
import io.swagger.v3.oas.annotations.media.Schema;
import java.time.ZonedDateTime;
import java.util.UUID;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;

@Slf4j
public class DatasetObjDto {

  @Schema(name = "DatasetObj Basic", description = "데이터셋 객체 Obj 기본 정보")
  @Getter
  @Setter
  @NoArgsConstructor
  public static class Basic {

    private Long objId;
    private Long datasetUid;
    private Integer targetYyyy;
    private String targetClassCd;
    private Integer compareYyyy;
    private String compareClassCd;
    private String targetPath;
    private String comparePath;
    private String labelPath;
    private String geojsonPath;
    private String mapSheetNum;
    @JsonFormatDttm private ZonedDateTime createdDttm;
    private Long createdUid;
    private Boolean deleted;
    private UUID uuid;
    @JsonIgnore private String geoJsonb;
    private JsonNode geoJson;

    public Basic(
        Long objId,
        Long datasetUid,
        Integer targetYyyy,
        String targetClassCd,
        Integer compareYyyy,
        String compareClassCd,
        String targetPath,
        String comparePath,
        String labelPath,
        String geojsonPath,
        String mapSheetNum,
        ZonedDateTime createdDttm,
        Long createdUid,
        Boolean deleted,
        UUID uuid,
        String geoJsonb) {
      this.objId = objId;
      this.datasetUid = datasetUid;
      this.targetYyyy = targetYyyy;
      this.targetClassCd = targetClassCd;
      this.compareYyyy = compareYyyy;
      this.compareClassCd = compareClassCd;
      this.targetPath = targetPath;
      this.comparePath = comparePath;
      this.labelPath = labelPath;
      this.geojsonPath = geojsonPath;
      this.mapSheetNum = mapSheetNum;
      this.createdDttm = createdDttm;
      this.createdUid = createdUid;
      this.deleted = deleted;
      this.uuid = uuid;
      this.geoJsonb = geoJsonb;

      JsonNode geoJsonNode = null;
      ObjectMapper mapper = new ObjectMapper();
      if (geoJsonb != null) {
        try {
          geoJsonNode = mapper.readTree(geoJsonb);
        } catch (JsonProcessingException e) {
          throw new RuntimeException(e);
        }
      }

      this.geoJson = geoJsonNode;
    }
  }

  @Schema(name = "DatasetSearchReq", description = "데이터셋 상세 도엽목록 조회 요청")
  @Getter
  @Setter
  @NoArgsConstructor
  @AllArgsConstructor
  public static class SearchReq {
    @Schema(description = "회차 uuid", example = "e9a6774b-4f81-4402-b080-51d27fac1f01")
    private UUID uuid;

    @Schema(description = "비교년도분류", example = "waste")
    private String compareClassCd;

    @Schema(description = "기준년도분류", example = "land")
    private String targetClassCd;

    @Schema(description = "도엽번호", example = "36713060")
    private String mapSheetNum;

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

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

    public Pageable toPageable() {
      return PageRequest.of(page, size, Sort.by(Sort.Direction.DESC, "createdDttm"));
    }
  }

  @Getter
  @Setter
  @AllArgsConstructor
  @NoArgsConstructor
  public static class DatasetClass {
    private String classCd;

    public String getClassName() {

      return HeaderUtil.isEnglishRequest()
          ? DetectionClassification.fromString(classCd).getId()
          : DetectionClassification.fromString(classCd).getDesc();
      // fromString 메서드를 사용하여 안전하게 변환 (미정의 값은 ETC로 처리)
      // return DetectionClassification.valueOf(classCd.toUpperCase()).getDesc();
    }
  }

  @Getter
  @Setter
  public static class DatasetStorage {
    private String usableBytes;
  }

  @Getter
  @Setter
  @NoArgsConstructor
  @AllArgsConstructor
  @Builder
  public static class DatasetObjRegDto {
    private Long datasetUid;
    private Integer compareYyyy;
    private String compareClassCd;
    private Integer targetYyyy;
    private String targetClassCd;
    private String comparePath;
    private String targetPath;
    private String labelPath;
    private String geojsonPath;
    private String mapSheetNum;
    private JsonNode geojson;
    private String fileName;
  }

  @Getter
  @Setter
  @NoArgsConstructor
  @AllArgsConstructor
  @Builder
  public static class DatasetClsObjRegDto {
    private Long datasetUid;
    private String type;
    private Integer yyyy;
    private String classCd;
    private String mapSheetNum;
    private String tifImgPath;
    private String fileName;
  }
}
