package gc.mda.signal_batch.domain.gis.dto;

import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import gc.mda.signal_batch.global.config.FlexibleLocalDateTimeDeserializer;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.Valid;
import jakarta.validation.constraints.NotNull;
import jakarta.validation.constraints.Size;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.time.LocalDateTime;
import java.util.List;

@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
@Schema(description = "다중 폴리곤 영역 탐색 요청")
public class AreaSearchRequest {

    @NotNull(message = "시작 시간은 필수입니다")
    @JsonDeserialize(using = FlexibleLocalDateTimeDeserializer.class)
    @Schema(description = "조회 시작 시간", example = "2026-02-01T00:00:00", requiredMode = Schema.RequiredMode.REQUIRED)
    private LocalDateTime startTime;

    @NotNull(message = "종료 시간은 필수입니다")
    @JsonDeserialize(using = FlexibleLocalDateTimeDeserializer.class)
    @Schema(description = "조회 종료 시간", example = "2026-02-07T23:59:59", requiredMode = Schema.RequiredMode.REQUIRED)
    private LocalDateTime endTime;

    @Schema(description = "검색 모드: ANY(합집합), ALL(교집합), SEQUENTIAL(순차 통과). 폴리곤 1개일 때는 무시됨",
            example = "ANY", defaultValue = "ANY")
    @Builder.Default
    private SearchMode mode = SearchMode.ANY;

    @NotNull(message = "폴리곤 목록은 필수입니다")
    @Size(min = 1, max = 10, message = "폴리곤은 1~10개까지 지정 가능합니다")
    @Valid
    @Schema(description = "탐색 대상 폴리곤 영역 목록 (1~10개)", requiredMode = Schema.RequiredMode.REQUIRED)
    private List<SearchPolygon> polygons;

    @Schema(description = "검색 모드 (폴리곤이 2개 이상일 때 적용)")
    public enum SearchMode {
        @Schema(description = "합집합: 어느 한 영역이라도 통과한 선박")
        ANY,
        @Schema(description = "교집합: 모든 영역을 통과한 선박")
        ALL,
        @Schema(description = "순차 통과: 모든 영역을 지정된 순서대로 통과한 선박")
        SEQUENTIAL
    }

    @Data
    @Builder
    @NoArgsConstructor
    @AllArgsConstructor
    @Schema(description = "탐색 대상 폴리곤 영역")
    public static class SearchPolygon {

        @Schema(description = "클라이언트 지정 영역 식별자", example = "zone_A")
        private String id;

        @Schema(description = "영역 표시명", example = "대한해협 서수도")
        private String name;

        @NotNull(message = "폴리곤 좌표는 필수입니다")
        @Size(min = 4, message = "폴리곤은 최소 4개 좌표 필요 (첫점==끝점)")
        @Schema(description = "폴리곤 좌표 배열 [[lon,lat],...] 첫점과 끝점이 동일해야 함",
                example = "[[128.5,34.0],[129.5,34.0],[129.5,35.0],[128.5,35.0],[128.5,34.0]]",
                requiredMode = Schema.RequiredMode.REQUIRED)
        private List<double[]> coordinates;
    }
}
