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

import com.kamco.cd.kamcoback.common.enums.DetectionClassification;
import com.kamco.cd.kamcoback.inference.dto.InferenceResultDto;
import com.kamco.cd.kamcoback.inference.dto.InferenceResultDto.Clazzes;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.FetchType;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.persistence.JoinColumn;
import jakarta.persistence.ManyToOne;
import jakarta.persistence.SequenceGenerator;
import jakarta.persistence.Table;
import jakarta.validation.constraints.Size;
import java.time.ZonedDateTime;
import java.util.UUID;
import lombok.Getter;
import lombok.Setter;
import org.hibernate.annotations.ColumnDefault;
import org.locationtech.jts.geom.Geometry;

@Getter
@Setter
@Entity
@Table(name = "tb_map_sheet_anal_data_geom")
public class MapSheetAnalDataGeomEntity {

  @Id
  @GeneratedValue(
      strategy = GenerationType.SEQUENCE,
      generator = "tb_map_sheet_anal_data_geom_id_gen")
  @SequenceGenerator(
      name = "tb_map_sheet_anal_data_geom_id_gen",
      sequenceName = "tb_map_sheet_learn_data_geom_geom_uid",
      allocationSize = 1)
  @Column(name = "geo_uid", nullable = false)
  private Long id;

  @Column(name = "uuid")
  private UUID uuid;

  @Column(name = "cd_prob")
  private Double cdProb;

  @Size(max = 40)
  @Column(name = "class_before_cd", length = 40)
  private String classBeforeCd;

  @Column(name = "class_before_prob")
  private Double classBeforeProb;

  @Size(max = 40)
  @Column(name = "class_after_cd", length = 40)
  private String classAfterCd;

  @Column(name = "class_after_prob")
  private Double classAfterProb;

  @Column(name = "map_sheet_num")
  private Long mapSheetNum;

  @ManyToOne(fetch = FetchType.EAGER)
  @JoinColumn(name = "map_5k_id", referencedColumnName = "fid")
  private MapInkx5kEntity map5k;

  @Column(name = "compare_yyyy")
  private Integer compareYyyy;

  @Column(name = "target_yyyy")
  private Integer targetYyyy;

  @Column(name = "area")
  private Double area;

  @Size(max = 100)
  @Column(name = "geo_type", length = 100)
  private String geoType;

  @Column(name = "data_uid")
  private Long dataUid;

  @ColumnDefault("now()")
  @Column(name = "created_dttm")
  private ZonedDateTime createdDttm;

  @Column(name = "created_uid")
  private Long createdUid;

  @ColumnDefault("now()")
  @Column(name = "updated_dttm")
  private ZonedDateTime updatedDttm;

  @Column(name = "updated_uid")
  private Long updatedUid;

  @ColumnDefault("0")
  @Column(name = "geom_cnt")
  private Long geomCnt;

  @ColumnDefault("0")
  @Column(name = "pnu")
  private Long pnu;

  @Size(max = 20)
  @ColumnDefault("0")
  @Column(name = "fit_state", length = 20)
  private String fitState;

  @ColumnDefault("now()")
  @Column(name = "fit_state_dttm")
  private ZonedDateTime fitStateDttm;

  @Column(name = "labeler_uid")
  private Long labelerUid;

  @Size(max = 20)
  @ColumnDefault("0")
  @Column(name = "label_state", length = 20)
  private String labelState;

  @ColumnDefault("now()")
  @Column(name = "label_state_dttm")
  private ZonedDateTime labelStateDttm;

  @Column(name = "tester_uid")
  private Long testerUid;

  @Size(max = 20)
  @ColumnDefault("0")
  @Column(name = "test_state", length = 20)
  private String testState;

  @ColumnDefault("now()")
  @Column(name = "test_state_dttm")
  private ZonedDateTime testStateDttm;

  @Column(name = "fit_state_cmmnt", length = Integer.MAX_VALUE)
  private String fitStateCmmnt;

  @Column(name = "ref_map_sheet_num")
  private Long refMapSheetNum;

  @Column(name = "geom", columnDefinition = "geometry")
  private Geometry geom;

  @Column(name = "geom_center", columnDefinition = "geometry")
  private Geometry geomCenter;

  public InferenceResultDto.DetailListEntity toEntity() {
    DetectionClassification classification = DetectionClassification.fromString(classBeforeCd);
    Clazzes comparedClazz = new Clazzes(classification, classBeforeProb);
    DetectionClassification classification1 = DetectionClassification.fromString(classAfterCd);
    Clazzes targetClazz = new Clazzes(classification1, classAfterProb);
    InferenceResultDto.MapSheet mapSheet = map5k != null ? map5k.toEntity() : null;

    InferenceResultDto.Coordinate coordinate = null;
    if (geomCenter != null) {
      org.locationtech.jts.geom.Point point = (org.locationtech.jts.geom.Point) geomCenter;
      coordinate = new InferenceResultDto.Coordinate(point.getX(), point.getY());
    }

    return new InferenceResultDto.DetailListEntity(
        uuid, cdProb, comparedClazz, targetClazz, mapSheet, coordinate, createdDttm);
  }
}
