package com.kamco.cd.training.hyperparam;

import com.kamco.cd.training.common.dto.HyperParam;
import com.kamco.cd.training.common.enums.ModelType;
import com.kamco.cd.training.config.api.ApiResponseDto;
import com.kamco.cd.training.hyperparam.dto.HyperParamDto;
import com.kamco.cd.training.hyperparam.dto.HyperParamDto.List;
import com.kamco.cd.training.hyperparam.service.HyperParamService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
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 jakarta.validation.Valid;
import java.time.LocalDate;
import java.util.UUID;
import lombok.RequiredArgsConstructor;
import org.springframework.data.domain.Page;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

@Tag(name = "하이퍼파라미터 관리", description = "하이퍼파라미터 관리 API")
@RestController
@RequiredArgsConstructor
@RequestMapping("/api/hyper-param")
public class HyperParamApiController {

  private final HyperParamService hyperParamService;

  @Operation(summary = "하이퍼파라미터 등록", description = "파라미터를 신규 저장")
  @ApiResponses(
      value = {
        @ApiResponse(
            responseCode = "200",
            description = "등록 성공",
            content =
                @Content(
                    mediaType = "application/json",
                    schema = @Schema(implementation = String.class))),
        @ApiResponse(responseCode = "400", description = "잘못된 요청", content = @Content),
        @ApiResponse(responseCode = "500", description = "서버 오류", content = @Content)
      })
  @PostMapping
  public ApiResponseDto<String> createHyperParam(@Valid @RequestBody HyperParam createReq) {
    String newVersion = hyperParamService.createHyperParam(createReq);
    return ApiResponseDto.ok(newVersion);
  }

  @Operation(summary = "하이퍼파라미터 수정", description = "파라미터를 수정")
  @ApiResponses(
      value = {
        @ApiResponse(
            responseCode = "200",
            description = "등록 성공",
            content =
                @Content(
                    mediaType = "application/json",
                    schema = @Schema(implementation = String.class))),
        @ApiResponse(responseCode = "400", description = "잘못된 요청", content = @Content),
        @ApiResponse(responseCode = "422", description = "default는 삭제불가", content = @Content),
        @ApiResponse(responseCode = "500", description = "서버 오류", content = @Content)
      })
  @PutMapping("/{uuid}")
  public ApiResponseDto<String> updateHyperParam(
      @PathVariable UUID uuid, @Valid @RequestBody HyperParam createReq) {
    return ApiResponseDto.ok(hyperParamService.updateHyperParam(uuid, createReq));
  }

  @Operation(summary = "하이퍼파라미터 목록 조회", description = "하이퍼파라미터 목록 조회")
  @ApiResponses(
      value = {
        @ApiResponse(
            responseCode = "200",
            description = "조회 성공",
            content =
                @Content(
                    mediaType = "application/json",
                    schema = @Schema(implementation = Page.class))),
        @ApiResponse(responseCode = "404", description = "하이퍼파라미터를 찾을 수 없음", content = @Content),
        @ApiResponse(responseCode = "500", description = "서버 오류", content = @Content)
      })
  @GetMapping("/list")
  public ApiResponseDto<Page<List>> getHyperParam(
      @Parameter(
              description = "구분 CREATE_DATE(생성일), LAST_USED_DATE(최근사용일)",
              example = "CREATE_DATE")
          @RequestParam(required = false)
          String type,
      @Parameter(description = "시작일", example = "2026-02-01") @RequestParam(required = false)
          LocalDate startDate,
      @Parameter(description = "종료일", example = "2026-03-31") @RequestParam(required = false)
          LocalDate endDate,
      @Parameter(description = "버전명", example = "G1_000019") @RequestParam(required = false)
          String hyperVer,
      @Parameter(description = "모델 타입 (G1, G2, G3, G4 중 하나)", example = "G1")
          @RequestParam(required = false)
          ModelType model,
      @Parameter(
              description = "정렬",
              example = "createdDttm desc",
              schema =
                  @Schema(
                      allowableValues = {
                        "createdDttm,desc",
                        "lastUsedDttm,desc",
                        "totalUseCnt,desc"
                      }))
          @RequestParam(required = false)
          String sort,
      @Parameter(description = "페이지 번호 (0부터 시작)", example = "0") @RequestParam(defaultValue = "0")
          int page,
      @Parameter(description = "페이지 크기", example = "20") @RequestParam(defaultValue = "20")
          int size) {
    HyperParamDto.SearchReq searchReq = new HyperParamDto.SearchReq();
    searchReq.setType(type);
    searchReq.setStartDate(startDate);
    searchReq.setEndDate(endDate);
    searchReq.setHyperVer(hyperVer);
    searchReq.setSort(sort);
    searchReq.setPage(page);
    searchReq.setSize(size);
    Page<List> list = hyperParamService.getHyperParamList(model, searchReq);

    return ApiResponseDto.ok(list);
  }

  @Operation(summary = "하이퍼파라미터 삭제", description = "하이퍼파라미터 삭제")
  @ApiResponses(
      value = {
        @ApiResponse(responseCode = "200", description = "삭제 성공", content = @Content),
        @ApiResponse(responseCode = "422", description = "default 삭제 불가", content = @Content),
        @ApiResponse(responseCode = "404", description = "하이퍼파라미터를 찾을 수 없음", content = @Content),
      })
  @DeleteMapping("/{uuid}")
  public ApiResponseDto<Void> deleteHyperParam(
      @Parameter(description = "하이퍼파라미터 uuid", example = "57fc9170-64c1-4128-aa7b-0657f08d6d10")
          @PathVariable
          UUID uuid) {
    hyperParamService.deleteHyperParam(uuid);
    return ApiResponseDto.ok(null);
  }

  @Operation(summary = "하이퍼파라미터 상세 조회", description = "특정 버전의 하이퍼파라미터 상세 정보를 조회합니다")
  @ApiResponses(
      value = {
        @ApiResponse(
            responseCode = "200",
            description = "조회 성공",
            content =
                @Content(
                    mediaType = "application/json",
                    schema = @Schema(implementation = HyperParamDto.Basic.class))),
        @ApiResponse(responseCode = "404", description = "하이퍼파라미터를 찾을 수 없음", content = @Content),
        @ApiResponse(responseCode = "500", description = "서버 오류", content = @Content)
      })
  @GetMapping("/{uuid}")
  public ApiResponseDto<HyperParamDto.Basic> getHyperParam(
      @Parameter(description = "하이퍼파라미터 uuid", example = "57fc9170-64c1-4128-aa7b-0657f08d6d10")
          @PathVariable
          UUID uuid) {
    return ApiResponseDto.ok(hyperParamService.getHyperParam(uuid));
  }

  @Operation(summary = "하이퍼파라미터 최적화 값 조회", description = "하이퍼파라미터 최적화 값 조회 API")
  @ApiResponses(
      value = {
        @ApiResponse(
            responseCode = "200",
            description = "조회 성공",
            content =
                @Content(
                    mediaType = "application/json",
                    schema = @Schema(implementation = Page.class))),
        @ApiResponse(responseCode = "404", description = "하이퍼파라미터를 찾을 수 없음", content = @Content),
        @ApiResponse(responseCode = "500", description = "서버 오류", content = @Content)
      })
  @GetMapping("/init/{model}")
  public ApiResponseDto<HyperParamDto.Basic> getInitHyperParam(@PathVariable ModelType model) {

    return ApiResponseDto.ok(hyperParamService.getInitHyperParam(model));
  }
}
