package incheon.ags.mrb.analysis.web;

import incheon.ags.mrb.analysis.service.SpatialAnalysisService;
import incheon.ags.mrb.analysis.vo.AnlsHstryVO;
import incheon.ags.mrb.analysis.vo.request.*;
import incheon.com.cmm.api.DefaultApiResponse;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.media.Content;
import io.swagger.v3.oas.annotations.media.Schema;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import io.swagger.v3.oas.annotations.responses.ApiResponses;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.server.ResponseStatusException;

import javax.validation.Valid;

@Tag(name = "공간 분석 API")
@RestController
@RequestMapping("/ags/mrb/analysis")
@RequiredArgsConstructor
public class SpatialAnalysisController {

    private static final Logger logger = LoggerFactory.getLogger(SpatialAnalysisController.class);

    private final SpatialAnalysisService spatialAnalysisService;

    /**
     * 포인트 집계 시작 요청 API
     */
    @Operation(summary = "포인트 집계 시작 요청", description = "포인트 집계 시작을 요청합니다.")
    @ApiResponses(value = {
            @ApiResponse(responseCode = "200", description = "포인트 집계 시작 성공",
                    content = @Content(schema = @Schema(implementation = DefaultApiResponse.class))),
            @ApiResponse(responseCode = "400", description = "요청 파라미터 오류"),
            @ApiResponse(responseCode = "404", description = "레이어를 찾을 수 없음"),
            @ApiResponse(responseCode = "500", description = "서버 내부 오류")
    })
    @PostMapping("/ap/start")
    public ResponseEntity<DefaultApiResponse<AnlsHstryVO>> startAggregatePoints(
            @Valid @RequestBody AggregatePointsRequestDTO request) {

        logger.info("포인트 집계 시작 요청");
        try {
            AnlsHstryVO result = spatialAnalysisService.startAggregatePoints(request);
            return ResponseEntity.ok(DefaultApiResponse.success(result, "포인트 집계 시작 성공"));
        } catch (IllegalArgumentException e) {
            logger.warn("포인트 집계 시작 실패 - 잘못된 요청", e);
            return ResponseEntity.badRequest()
                    .body(DefaultApiResponse.error(400, "포인트 집계 시작 실패 - 잘못된 요청", "INVALID_REQUEST"));
        } catch (SecurityException e) {
            logger.warn("포인트 집계 시작 실패 - 권한 없음", e);
            return ResponseEntity.status(403)
                    .body(DefaultApiResponse.error(403, "포인트 집계 시작 실패 - 권한 없음", "ACCESS_DENIED"));
        } catch (Exception e) {
            logger.error("포인트 집계 시작 실패 - 서버 오류", e);
            return ResponseEntity.internalServerError()
                    .body(DefaultApiResponse.error(500, "서버 내부 오류가 발생했습니다.", "SERVER_ERROR"));
        }
    }

    /**
     * 버퍼 시작 요청 API
     */
    @Operation(summary = "버퍼 시작 요청", description = "버퍼 시작을 요청합니다.")
    @ApiResponses(value = {
            @ApiResponse(responseCode = "200", description = "버퍼 시작 성공",
                    content = @Content(schema = @Schema(implementation = DefaultApiResponse.class))),
            @ApiResponse(responseCode = "400", description = "요청 파라미터 오류"),
            @ApiResponse(responseCode = "404", description = "레이어를 찾을 수 없음"),
            @ApiResponse(responseCode = "500", description = "서버 내부 오류")
    })
    @PostMapping("/buffer/start")
    public ResponseEntity<DefaultApiResponse<AnlsHstryVO>> startBuffer(
            @Valid @RequestBody BufferRequestDTO request) {

        logger.info("버퍼 시작 요청");
        try {
            AnlsHstryVO result = spatialAnalysisService.startBuffer(request);
            return ResponseEntity.ok(DefaultApiResponse.success(result, "버퍼 시작 성공"));
        } catch (IllegalArgumentException e) {
            logger.warn("버퍼 시작 실패 - 잘못된 요청", e);
            return ResponseEntity.badRequest()
                    .body(DefaultApiResponse.error(400, "버퍼 시작 실패 - 잘못된 요청", "INVALID_REQUEST"));
        } catch (SecurityException e) {
            logger.warn("버퍼 시작 실패 - 권한 없음", e);
            return ResponseEntity.status(403)
                    .body(DefaultApiResponse.error(403, "버퍼 시작 실패 - 잘못된 요청", "ACCESS_DENIED"));
        } catch (ResponseStatusException e){
            logger.warn("버퍼 시작 실패", e);
            return ResponseEntity.status(e.getStatus())
                    .body(DefaultApiResponse.error(e.getRawStatusCode(), e.getReason(), e.getStatus().getReasonPhrase().toUpperCase()));
        } catch (Exception e) {
            logger.error("버퍼 시작 실패 - 서버 오류", e);
            return ResponseEntity.internalServerError()
                    .body(DefaultApiResponse.error(500, "버퍼 시작 실패 - 서버 오류", "SERVER_ERROR"));
        }
    }

    /**
     * 유니온 시작 요청 API
     */
    @Operation(summary = "유니온 시작 요청", description = "유니온 시작을 요청합니다.")
    @ApiResponses(value = {
            @ApiResponse(responseCode = "200", description = "유니온 시작 성공",
                    content = @Content(schema = @Schema(implementation = DefaultApiResponse.class))),
            @ApiResponse(responseCode = "400", description = "요청 파라미터 오류"),
            @ApiResponse(responseCode = "404", description = "레이어를 찾을 수 없음"),
            @ApiResponse(responseCode = "500", description = "서버 내부 오류")
    })
    @PostMapping("/union/start")
    public ResponseEntity<DefaultApiResponse<AnlsHstryVO>> startUnion(
            @Valid @RequestBody UnionRequestDTO request) {

        logger.info("유니온 시작 요청");
        try {
            AnlsHstryVO result = spatialAnalysisService.startUnion(request);
            return ResponseEntity.ok(DefaultApiResponse.success(result, "유니온 시작 성공"));
        } catch (IllegalArgumentException e) {
            logger.warn("유니온 시작 실패 - 잘못된 요청", e);
            return ResponseEntity.badRequest()
                    .body(DefaultApiResponse.error(400, "유니온 시작 실패 - 잘못된 요청", "INVALID_REQUEST"));
        } catch (SecurityException e) {
            logger.warn("유니온 시작 실패 - 권한 없음", e);
            return ResponseEntity.status(403)
                    .body(DefaultApiResponse.error(403, "유니온 시작 실패 - 권한 없음", "ACCESS_DENIED"));
        } catch (ResponseStatusException e){
            logger.warn("유니온 시작 실패", e);
            return ResponseEntity.status(e.getStatus())
                    .body(DefaultApiResponse.error(e.getRawStatusCode(), e.getReason(), e.getStatus().getReasonPhrase().toUpperCase()));
        }
        catch (Exception e) {
            logger.error("유니온 시작 실패 - 서버 오류", e);
            return ResponseEntity.internalServerError()
                    .body(DefaultApiResponse.error(500, "유니온 시작 실패 - 서버 오류", "SERVER_ERROR"));
        }
    }

    /**
     * 클립 시작 요청 API
     */
    @Operation(summary = "클립 시작 요청", description = "클립 시작을 요청합니다.")
    @ApiResponses(value = {
            @ApiResponse(responseCode = "200", description = "클립 시작 성공",
                    content = @Content(schema = @Schema(implementation = DefaultApiResponse.class))),
            @ApiResponse(responseCode = "400", description = "요청 파라미터 오류"),
            @ApiResponse(responseCode = "404", description = "레이어를 찾을 수 없음"),
            @ApiResponse(responseCode = "500", description = "서버 내부 오류")
    })
    @PostMapping("/clip/start")
    public ResponseEntity<DefaultApiResponse<AnlsHstryVO>> startClip(
            @Valid @RequestBody ClipRequestDTO request) {

        logger.info("클립 시작 요청");
        try {
            AnlsHstryVO result = spatialAnalysisService.startClip(request);
            return ResponseEntity.ok(DefaultApiResponse.success(result, "클립 시작 성공"));
        } catch (IllegalArgumentException e) {
            logger.warn("클립 시작 실패 - 잘못된 요청", e);
            return ResponseEntity.badRequest()
                    .body(DefaultApiResponse.error(400, "클립 시작 실패 - 잘못된 요청", "INVALID_REQUEST"));
        } catch (SecurityException e) {
            logger.warn("클립 시작 실패 - 권한 없음", e);
            return ResponseEntity.status(403)
                    .body(DefaultApiResponse.error(403, "클립 시작 실패 - 잘못된 요청", "ACCESS_DENIED"));
        } catch (ResponseStatusException e){
            logger.warn("클립 시작 실패", e);
            return ResponseEntity.status(e.getStatus())
                    .body(DefaultApiResponse.error(e.getRawStatusCode(), e.getReason(), e.getStatus().getReasonPhrase().toUpperCase()));
        }
        catch (Exception e) {
            logger.error("클립 시작 실패 - 서버 오류", e);
            return ResponseEntity.internalServerError()
                    .body(DefaultApiResponse.error(500, "클립 시작 실패 - 서버 오류", "SERVER_ERROR"));
        }
    }

    /**
     * 클러스터링 시작 요청 API
     */
    @Operation(summary = "클러스터링 시작 요청", description = "클러스터링 시작을 요청합니다.")
    @ApiResponses(value = {
            @ApiResponse(responseCode = "200", description = "클러스터링 시작 성공",
                    content = @Content(schema = @Schema(implementation = DefaultApiResponse.class))),
            @ApiResponse(responseCode = "400", description = "요청 파라미터 오류"),
            @ApiResponse(responseCode = "404", description = "레이어를 찾을 수 없음"),
            @ApiResponse(responseCode = "500", description = "서버 내부 오류")
    })
    @PostMapping("/clustering/start")
    public ResponseEntity<DefaultApiResponse<AnlsHstryVO>> startClustering(
            @Valid @RequestBody ClusteringRequestDTO request) {

        logger.info("클러스터링 시작 요청");
        try {
            AnlsHstryVO result = spatialAnalysisService.startClustering(request);
            return ResponseEntity.ok(DefaultApiResponse.success(result, "클러스터링 시작 성공"));
        } catch (IllegalArgumentException e) {
            logger.warn("클러스터링 시작 실패 - 잘못된 요청", e);
            return ResponseEntity.badRequest()
                    .body(DefaultApiResponse.error(400, "클러스터링 시작 실패 - 잘못된 요청", "INVALID_REQUEST"));
        } catch (SecurityException e) {
            logger.warn("클러스터링 시작 실패 - 권한 없음", e);
            return ResponseEntity.status(403)
                    .body(DefaultApiResponse.error(403, "클러스터링 시작 실패 - 잘못된 요청", "ACCESS_DENIED"));
        } catch (ResponseStatusException e){
            logger.warn("클러스터링 시작 실패", e);
            return ResponseEntity.status(e.getStatus())
                    .body(DefaultApiResponse.error(e.getRawStatusCode(), e.getReason(), e.getStatus().getReasonPhrase().toUpperCase()));
        }
        catch (Exception e) {
            logger.error("클러스터링 시작 실패 - 서버 오류", e);
            return ResponseEntity.internalServerError()
                    .body(DefaultApiResponse.error(500, "클러스터링 시작 실패 - 서버 오류", "SERVER_ERROR"));
        }
    }

    /**
     * 디졸브 시작 요청 API
     */
    @Operation(summary = "디졸브 시작 요청", description = "디졸브 시작을 요청합니다.")
    @ApiResponses(value = {
            @ApiResponse(responseCode = "200", description = "디졸브 시작 성공",
                    content = @Content(schema = @Schema(implementation = DefaultApiResponse.class))),
            @ApiResponse(responseCode = "400", description = "요청 파라미터 오류"),
            @ApiResponse(responseCode = "404", description = "레이어를 찾을 수 없음"),
            @ApiResponse(responseCode = "500", description = "서버 내부 오류")
    })
    @PostMapping("/dissolve/start")
    public ResponseEntity<DefaultApiResponse<AnlsHstryVO>> startDissolve(
            @Valid @RequestBody DissolveRequestDTO request) {

        logger.info("디졸브 시작 요청");
        try {
            AnlsHstryVO result = spatialAnalysisService.startDissolve(request);
            return ResponseEntity.ok(DefaultApiResponse.success(result, "디졸브 시작 성공"));
        } catch (IllegalArgumentException e) {
            logger.warn("디졸브 시작 실패 - 잘못된 요청", e);
            return ResponseEntity.badRequest()
                    .body(DefaultApiResponse.error(400, "디졸브 시작 실패 - 잘못된 요청", "INVALID_REQUEST"));
        } catch (SecurityException e) {
            logger.warn("디졸브 시작 실패 - 권한 없음", e);
            return ResponseEntity.status(403)
                    .body(DefaultApiResponse.error(403, "디졸브 시작 실패 - 권한 없음", "ACCESS_DENIED"));
        } catch (ResponseStatusException e){
            logger.warn("디졸브 시작 실패", e);
            return ResponseEntity.status(e.getStatus())
                    .body(DefaultApiResponse.error(e.getRawStatusCode(), e.getReason(), e.getStatus().getReasonPhrase().toUpperCase()));
        }
        catch (Exception e) {
            logger.error("디졸브 시작 실패 - 서버 오류", e);
            return ResponseEntity.internalServerError()
                    .body(DefaultApiResponse.error(500, "디졸브 시작 실패 - 서버 오류", "SERVER_ERROR"));
        }
    }

    /**
     * 추출 시작 요청 API
     */
    @Operation(summary = "추출 시작 요청", description = "추출 시작을 요청합니다.")
    @ApiResponses(value = {
            @ApiResponse(responseCode = "200", description = "추출 시작 성공",
                    content = @Content(schema = @Schema(implementation = DefaultApiResponse.class))),
            @ApiResponse(responseCode = "400", description = "요청 파라미터 오류"),
            @ApiResponse(responseCode = "404", description = "레이어를 찾을 수 없음"),
            @ApiResponse(responseCode = "500", description = "서버 내부 오류")
    })
    @PostMapping("/extract/start")
    public ResponseEntity<DefaultApiResponse<AnlsHstryVO>> startExtract(
            @Valid @RequestBody ExtractRequestDTO request) {

        logger.info("추출 시작 요청");
        try {
            AnlsHstryVO result = spatialAnalysisService.startExtract(request);
            return ResponseEntity.ok(DefaultApiResponse.success(result, "추출 시작 성공"));
        } catch (IllegalArgumentException e) {
            logger.warn("추출 시작 실패 - 잘못된 요청", e);
            return ResponseEntity.badRequest()
                    .body(DefaultApiResponse.error(400, "추출 시작 실패 - 잘못된 요청", "INVALID_REQUEST"));
        } catch (SecurityException e) {
            logger.warn("추출 시작 실패 - 권한 없음", e);
            return ResponseEntity.status(403)
                    .body(DefaultApiResponse.error(403, "추출 시작 실패 - 권한 없음", "ACCESS_DENIED"));
        } catch (ResponseStatusException e){
            logger.warn("추출 시작 실패", e);
            return ResponseEntity.status(e.getStatus())
                    .body(DefaultApiResponse.error(e.getRawStatusCode(), e.getReason(), e.getStatus().getReasonPhrase().toUpperCase()));
        }
        catch (Exception e) {
            logger.error("추출 시작 실패 - 서버 오류", e);
            return ResponseEntity.internalServerError()
                    .body(DefaultApiResponse.error(500, "추출 시작 실패 - 서버 오류", "SERVER_ERROR"));
        }
    }

    /**
     * 핫스팟 시작 요청 API
     */
    @Operation(summary = "핫스팟 시작 요청", description = "핫스팟 시작을 요청합니다.")
    @ApiResponses(value = {
            @ApiResponse(responseCode = "200", description = "핫스팟 시작 성공",
                    content = @Content(schema = @Schema(implementation = DefaultApiResponse.class))),
            @ApiResponse(responseCode = "400", description = "요청 파라미터 오류"),
            @ApiResponse(responseCode = "404", description = "레이어를 찾을 수 없음"),
            @ApiResponse(responseCode = "500", description = "서버 내부 오류")
    })
    @PostMapping("/hotspot/start")
    public ResponseEntity<DefaultApiResponse<AnlsHstryVO>> startHotSpot(
            @Valid @RequestBody HotSpotRequestDTO request) {

        logger.info("핫스팟 시작 요청");
        try {
            AnlsHstryVO result = spatialAnalysisService.startHotSpot(request);
            return ResponseEntity.ok(DefaultApiResponse.success(result, "핫스팟 시작 성공"));
        } catch (IllegalArgumentException e) {
            logger.warn("핫스팟 시작 실패 - 잘못된 요청", e);
            return ResponseEntity.badRequest()
                    .body(DefaultApiResponse.error(400, "핫스팟 시작 실패 - 잘못된 요청", "INVALID_REQUEST"));
        } catch (SecurityException e) {
            logger.warn("핫스팟 시작 실패 - 권한 없음", e);
            return ResponseEntity.status(403)
                    .body(DefaultApiResponse.error(403, "핫스팟 시작 실패 - 권한 없음", "ACCESS_DENIED"));
        } catch (ResponseStatusException e){
            logger.warn("핫스팟 시작 실패", e);
            return ResponseEntity.status(e.getStatus())
                    .body(DefaultApiResponse.error(e.getRawStatusCode(), e.getReason(), e.getStatus().getReasonPhrase().toUpperCase()));
        }
        catch (Exception e) {
            logger.error("핫스팟 시작 실패 - 서버 오류", e);
            return ResponseEntity.internalServerError()
                    .body(DefaultApiResponse.error(500, "핫스팟 시작 실패 - 서버 오류", "SERVER_ERROR"));
        }
    }

    /**
     * 교차 시작 요청 API
     */
    @Operation(summary = "교차 시작 요청", description = "교차 시작을 요청합니다.")
    @ApiResponses(value = {
            @ApiResponse(responseCode = "200", description = "교차 시작 성공",
                    content = @Content(schema = @Schema(implementation = DefaultApiResponse.class))),
            @ApiResponse(responseCode = "400", description = "요청 파라미터 오류"),
            @ApiResponse(responseCode = "404", description = "레이어를 찾을 수 없음"),
            @ApiResponse(responseCode = "500", description = "서버 내부 오류")
    })
    @PostMapping("/intersect/start")
    public ResponseEntity<DefaultApiResponse<AnlsHstryVO>> startIntersect(
            @Valid @RequestBody IntersectRequestDTO request) {

        logger.info("교차 시작 요청");
        try {
            AnlsHstryVO result = spatialAnalysisService.startIntersect(request);
            return ResponseEntity.ok(DefaultApiResponse.success(result, "교차 시작 성공"));
        } catch (IllegalArgumentException e) {
            logger.warn("교차 시작 실패 - 잘못된 요청", e);
            return ResponseEntity.badRequest()
                    .body(DefaultApiResponse.error(400, "교차 시작 실패 - 잘못된 요청", "INVALID_REQUEST"));
        } catch (SecurityException e) {
            logger.warn("교차 시작 실패 - 권한 없음", e);
            return ResponseEntity.status(403)
                    .body(DefaultApiResponse.error(403, "교차 시작 실패 - 권한 없음", "ACCESS_DENIED"));
        } catch (ResponseStatusException e){
            logger.warn("교차 시작 실패", e);
            return ResponseEntity.status(e.getStatus())
                    .body(DefaultApiResponse.error(e.getRawStatusCode(), e.getReason(), e.getStatus().getReasonPhrase().toUpperCase()));
        }
        catch (Exception e) {
            logger.error("교차 시작 실패 - 서버 오류", e);
            return ResponseEntity.internalServerError()
                    .body(DefaultApiResponse.error(500, "교차 시작 실패 - 서버 오류", "SERVER_ERROR"));
        }
    }

    /**
     * 병합 시작 요청 API
     */
    @Operation(summary = "병합 시작 요청", description = "병합 시작을 요청합니다.")
    @ApiResponses(value = {
            @ApiResponse(responseCode = "200", description = "병합 시작 성공",
                    content = @Content(schema = @Schema(implementation = DefaultApiResponse.class))),
            @ApiResponse(responseCode = "400", description = "요청 파라미터 오류"),
            @ApiResponse(responseCode = "404", description = "레이어를 찾을 수 없음"),
            @ApiResponse(responseCode = "500", description = "서버 내부 오류")
    })
    @PostMapping("/merge/start")
    public ResponseEntity<DefaultApiResponse<AnlsHstryVO>> startMerge(
            @Valid @RequestBody MergeRequestDTO request) {

        logger.info("병합 시작 요청");
        try {
            AnlsHstryVO result = spatialAnalysisService.startMerge(request);
            return ResponseEntity.ok(DefaultApiResponse.success(result, "병합 시작 성공"));
        } catch (IllegalArgumentException e) {
            logger.warn("병합 시작 실패 - 잘못된 요청", e);
            return ResponseEntity.badRequest()
                    .body(DefaultApiResponse.error(400, "병합 시작 실패 - 잘못된 요청", "INVALID_REQUEST"));
        } catch (SecurityException e) {
            logger.warn("병합 시작 실패 - 권한 없음", e);
            return ResponseEntity.status(403)
                    .body(DefaultApiResponse.error(403, "병합 시작 실패 - 권한 없음", "ACCESS_DENIED"));
        } catch (ResponseStatusException e){
            logger.warn("병합 시작 실패", e);
            return ResponseEntity.status(e.getStatus())
                    .body(DefaultApiResponse.error(e.getRawStatusCode(), e.getReason(), e.getStatus().getReasonPhrase().toUpperCase()));
        }
        catch (Exception e) {
            logger.error("병합 시작 실패 - 서버 오류", e);
            return ResponseEntity.internalServerError()
                    .body(DefaultApiResponse.error(500, "병합 시작 실패 - 서버 오류", "SERVER_ERROR"));
        }
    }

    /**
     * 주변 요약 시작 요청 API
     */
    @Operation(summary = "주변 요약 시작 요청", description = "주변 요약 시작을 요청합니다.")
    @ApiResponses(value = {
            @ApiResponse(responseCode = "200", description = "주변 요약 시작 성공",
                    content = @Content(schema = @Schema(implementation = DefaultApiResponse.class))),
            @ApiResponse(responseCode = "400", description = "요청 파라미터 오류"),
            @ApiResponse(responseCode = "404", description = "레이어를 찾을 수 없음"),
            @ApiResponse(responseCode = "500", description = "서버 내부 오류")
    })
    @PostMapping("/sn/start")
    public ResponseEntity<DefaultApiResponse<AnlsHstryVO>> startSummarizeNearby(
            @Valid @RequestBody SummarizeNearbyRequestDTO request) {

        logger.info("주변 요약 시작 요청");
        try {
            AnlsHstryVO result = spatialAnalysisService.startSummarizeNearby(request);
            return ResponseEntity.ok(DefaultApiResponse.success(result, "주변 요약 시작 성공"));
        } catch (IllegalArgumentException e) {
            logger.warn("주변 요약 시작 실패 - 잘못된 요청", e);
            return ResponseEntity.badRequest()
                    .body(DefaultApiResponse.error(400, "주변 요약 시작 실패 - 잘못된 요청", "INVALID_REQUEST"));
        } catch (SecurityException e) {
            logger.warn("주변 요약 시작 실패 - 권한 없음", e);
            return ResponseEntity.status(403)
                    .body(DefaultApiResponse.error(403, "주변 요약 시작 실패 - 권한 없음", "ACCESS_DENIED"));
        } catch (ResponseStatusException e){
            logger.warn("주변 요약 시작 실패", e);
            return ResponseEntity.status(e.getStatus())
                    .body(DefaultApiResponse.error(e.getRawStatusCode(), e.getReason(), e.getStatus().getReasonPhrase().toUpperCase()));
        }
        catch (Exception e) {
            logger.error("주변 요약 시작 실패 - 서버 오류", e);
            return ResponseEntity.internalServerError()
                    .body(DefaultApiResponse.error(500, "주변 요약 시작 실패 - 서버 오류", "SERVER_ERROR"));
        }
    }

    /**
     * 범위 요약 시작 요청 API
     */
    @Operation(summary = "범위 요약 시작 요청", description = "범위 요약 시작을 요청합니다.")
    @ApiResponses(value = {
            @ApiResponse(responseCode = "200", description = "범위 요약 시작 성공",
                    content = @Content(schema = @Schema(implementation = DefaultApiResponse.class))),
            @ApiResponse(responseCode = "400", description = "요청 파라미터 오류"),
            @ApiResponse(responseCode = "404", description = "레이어를 찾을 수 없음"),
            @ApiResponse(responseCode = "500", description = "서버 내부 오류")
    })
    @PostMapping("/sw/start")
    public ResponseEntity<DefaultApiResponse<AnlsHstryVO>> startSummarizeWithin(
            @Valid @RequestBody SummarizeWithinRequestDTO request) {

        logger.info("범위 요약 시작 요청");
        try {
            AnlsHstryVO result = spatialAnalysisService.startSummarizeWithin(request);
            return ResponseEntity.ok(DefaultApiResponse.success(result, "범위 요약 시작 성공"));
        } catch (IllegalArgumentException e) {
            logger.warn("범위 요약 시작 실패 - 잘못된 요청", e);
            return ResponseEntity.badRequest()
                    .body(DefaultApiResponse.error(400,"범위 요약 시작 실패 - 잘못된 요청", "INVALID_REQUEST"));
        } catch (SecurityException e) {
            logger.warn("범위 요약 시작 실패 - 권한 없음", e);
            return ResponseEntity.status(403)
                    .body(DefaultApiResponse.error(403,"범위 요약 시작 실패 - 권한 없음", "ACCESS_DENIED"));
        } catch (ResponseStatusException e){
            logger.warn("범위 요약 시작 실패", e);
            return ResponseEntity.status(e.getStatus())
                    .body(DefaultApiResponse.error(e.getRawStatusCode(), e.getReason(), e.getStatus().getReasonPhrase().toUpperCase()));
        } catch (Exception e) {
            logger.error("범위 요약 시작 실패 - 서버 오류", e);
            return ResponseEntity.internalServerError()
                    .body(DefaultApiResponse.error(500, "범위 요약 시작 실패 - 서버 오류", "SERVER_ERROR"));
        }
    }

    /**
     * 밀도 분석 시작 요청 API
     */
    @Operation(summary = "밀도 분석 시작 요청", description = "밀도 분석 시작을 요청합니다.")
    @ApiResponses(value = {
            @ApiResponse(responseCode = "200", description = "밀도 분석 시작 성공",
                    content = @Content(schema = @Schema(implementation = DefaultApiResponse.class))),
            @ApiResponse(responseCode = "400", description = "요청 파라미터 오류"),
            @ApiResponse(responseCode = "404", description = "레이어를 찾을 수 없음"),
            @ApiResponse(responseCode = "500", description = "서버 내부 오류")
    })
    @PostMapping("/density/start")
    public ResponseEntity<DefaultApiResponse<AnlsHstryVO>> startDensity(
            @Valid @RequestBody DensityRequestDTO request) {

        logger.info("밀도 분석 시작 요청");
        logger.debug("  - kernelType: {}", request.getKernelType());
        logger.debug("  - method: {}", request.getMethod());
        logger.debug("  - numClasses: {}", request.getNumClasses());
        logger.debug("  - populationField: {}", request.getPopulationField());
        logger.debug("  - dissolve: {}", request.getDissolve());
        
        try {
            AnlsHstryVO result = spatialAnalysisService.startDensity(request);
            return ResponseEntity.ok(DefaultApiResponse.success(result, "밀도 분석 시작 성공"));
        } catch (IllegalArgumentException e) {
            logger.warn("밀도 분석 시작 실패 - 잘못된 요청", e);
            return ResponseEntity.badRequest()
                    .body(DefaultApiResponse.error(400,"밀도 분석 시작 실패 - 잘못된 요청", "INVALID_REQUEST"));
        } catch (SecurityException e) {
            logger.warn("밀도 분석 시작 실패 - 권한 없음", e);
            return ResponseEntity.status(403)
                    .body(DefaultApiResponse.error(403, "밀도 분석 시작 실패 - 권한 없음", "ACCESS_DENIED"));
        } catch (ResponseStatusException e){
            logger.warn("밀도 분석 시작 실패", e);
            return ResponseEntity.status(e.getStatus())
                    .body(DefaultApiResponse.error(e.getRawStatusCode(), e.getReason(), e.getStatus().getReasonPhrase().toUpperCase()));
        } catch (Exception e) {
            logger.error("밀도 분석 시작 실패 - 서버 오류", e);
            return ResponseEntity.internalServerError()
                    .body(DefaultApiResponse.error(500, "밀도 분석 시작 실패 - 서버 오류", "SERVER_ERROR"));
        }
    }

    /**
     * 조인 피처 시작 요청 API
     */
    @Operation(summary = "조인 피처 시작 요청", description = "조인 피처 시작을 요청합니다.")
    @ApiResponses(value = {
            @ApiResponse(responseCode = "200", description = "조인 피처 시작 성공",
                    content = @Content(schema = @Schema(implementation = DefaultApiResponse.class))),
            @ApiResponse(responseCode = "400", description = "요청 파라미터 오류"),
            @ApiResponse(responseCode = "404", description = "레이어를 찾을 수 없음"),
            @ApiResponse(responseCode = "500", description = "서버 내부 오류")
    })
    @PostMapping("/join/start")
    public ResponseEntity<DefaultApiResponse<AnlsHstryVO>> startJoinFeatures(
            @Valid @RequestBody JoinFeaturesRequestDTO request) {

        logger.info("조인 피처 시작 요청");
        try {
            AnlsHstryVO result = spatialAnalysisService.startJoinFeatures(request);
            return ResponseEntity.ok(DefaultApiResponse.success(result, "조인 피처 시작 성공"));
        } catch (IllegalArgumentException e) {
            logger.warn("조인 피처 시작 실패 - 잘못된 요청", e);
            return ResponseEntity.badRequest()
                    .body(DefaultApiResponse.error(400, "조인 피처 시작 실패 - 잘못된 요청", "INVALID_REQUEST"));
        } catch (SecurityException e) {
            logger.warn("조인 피처 시작 실패 - 권한 없음", e);
            return ResponseEntity.status(403)
                    .body(DefaultApiResponse.error(403, "조인 피처 시작 실패 - 권한 없음", "ACCESS_DENIED"));
        } catch (ResponseStatusException e){
            logger.warn("조인 피처 시작 실패", e);
            return ResponseEntity.status(e.getStatus())
                    .body(DefaultApiResponse.error(e.getRawStatusCode(), e.getReason(), e.getStatus().getReasonPhrase().toUpperCase()));
        } catch (Exception e) {
            logger.error("조인 피처 시작 실패 - 서버 오류", e);
            return ResponseEntity.internalServerError()
                    .body(DefaultApiResponse.error(500, "조인 피처 시작 실패 - 서버 오류", "SERVER_ERROR"));
        }
    }

    
}
