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

import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.kamco.cd.kamcoback.common.utils.html.HtmlEscapeDeserializer;
import com.kamco.cd.kamcoback.common.utils.html.HtmlUnescapeSerializer;
import com.kamco.cd.kamcoback.common.utils.interfaces.JsonFormatDttm;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.NotEmpty;
import jakarta.validation.constraints.NotNull;
import java.time.ZonedDateTime;
import java.util.List;
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 CommonCodeDto {

  @Schema(name = "CodeAddReq", description = "공통코드 저장 정보")
  @Getter
  @Setter
  @NoArgsConstructor
  @AllArgsConstructor
  public static class AddReq {

    @NotEmpty private String code;
    @NotEmpty private String name;
    private String description;
    private int order;
    private boolean used;
    private Long parentId;

    @JsonDeserialize(using = HtmlEscapeDeserializer.class)
    private String props1;

    @JsonDeserialize(using = HtmlEscapeDeserializer.class)
    private String props2;

    @JsonDeserialize(using = HtmlEscapeDeserializer.class)
    private String props3;
  }

  @Schema(name = "CodeModifyReq", description = "공통코드 수정 정보")
  @Getter
  @Setter
  @NoArgsConstructor
  @AllArgsConstructor
  public static class ModifyReq {

    @NotEmpty private String name;
    private String description;
    private boolean used;

    @JsonDeserialize(using = HtmlEscapeDeserializer.class)
    private String props1;

    @JsonDeserialize(using = HtmlEscapeDeserializer.class)
    private String props2;

    @JsonDeserialize(using = HtmlEscapeDeserializer.class)
    private String props3;
  }

  @Schema(name = "CodeOrderReq", description = "공통코드 순서 변경 정보")
  @Getter
  @Setter
  @NoArgsConstructor
  @AllArgsConstructor
  public static class OrderReq {

    @NotNull private Long id;
    @NotNull private Integer order;
  }

  @Schema(name = "CommonCode Basic", description = "공통코드 기본 정보")
  @Getter
  public static class Basic {

    private Long id;
    private String code;
    private String description;
    private String name;
    private Integer order;
    private Boolean used;
    private Boolean deleted;
    private List<CommonCodeDto.Basic> children;

    @JsonFormatDttm private ZonedDateTime createdDttm;

    @JsonFormatDttm private ZonedDateTime updatedDttm;

    @JsonSerialize(using = HtmlUnescapeSerializer.class)
    private String props1;

    @JsonSerialize(using = HtmlUnescapeSerializer.class)
    private String props2;

    @JsonSerialize(using = HtmlUnescapeSerializer.class)
    private String props3;

    @JsonFormatDttm private ZonedDateTime deletedDttm;

    public Basic(
        Long id,
        String code,
        String description,
        String name,
        Integer order,
        Boolean used,
        Boolean deleted,
        List<CommonCodeDto.Basic> children,
        ZonedDateTime createdDttm,
        ZonedDateTime updatedDttm,
        String props1,
        String props2,
        String props3,
        ZonedDateTime deletedDttm) {
      this.id = id;
      this.code = code;
      this.description = description;
      this.name = name;
      this.order = order;
      this.used = used;
      this.deleted = deleted;
      this.children = children;
      this.createdDttm = createdDttm;
      this.updatedDttm = updatedDttm;
      this.props1 = props1;
      this.props2 = props2;
      this.props3 = props3;
      this.deletedDttm = deletedDttm;
    }
  }

  @Schema(name = "SearchReq", description = "검색 요청")
  @Getter
  @Setter
  @NoArgsConstructor
  @AllArgsConstructor
  public static class SearchReq {

    // 검색 조건
    private String name;

    // 페이징 파라미터
    private int page = 0;
    private int size = 20;
    private String sort;

    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);
    }
  }

  @Getter
  public static class Clazzes {

    private String code;
    private String name;
    private Integer order;
    private String color;

    public Clazzes(String code, String name, Integer order, String color) {
      this.code = code;
      this.name = name;
      this.order = order;
      this.color = color;
    }
  }

  @Getter
  @AllArgsConstructor
  public static class CodeDto {

    private String code;
    private String name;
  }
}
