package com.kamco.cd.training.upload;

import com.kamco.cd.training.config.api.ApiResponseDto;
import com.kamco.cd.training.upload.dto.UploadDto;
import com.kamco.cd.training.upload.dto.UploadDto.DmlReturn;
import com.kamco.cd.training.upload.service.UploadService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.media.Content;
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 java.util.UUID;
import lombok.RequiredArgsConstructor;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

@Tag(name = "파일 업로드", description = "대용량 파일 업로드 API")
@RestController
@RequestMapping("/api/upload")
@RequiredArgsConstructor
public class UploadApiController {

  private final UploadService uploadService;

  /*
    @Operation(summary = "데이터셋 대용량 업로드 세션 시작", description = "데이터셋 대용량 파일 업로드 세션을 시작합니다.")
    @ApiResponses(
        value = {
          @ApiResponse(
              responseCode = "201",
              description = "세션 생성 성공",
              content =
                  @Content(
                      mediaType = "application/json",
                      schema = @Schema(implementation = UploadDto.InitRes.class))),
          @ApiResponse(responseCode = "400", description = "잘못된 요청 데이터", content = @Content),
          @ApiResponse(responseCode = "500", description = "서버 오류", content = @Content)
        })
    @PostMapping("/chunk-upload-init")
    public ApiResponseDto<DmlReturn> initUpload(
        @RequestBody @Valid UploadDto.InitReq initReq) {
      return ApiResponseDto.createOK(uploadService.initUpload(initReq));
    }
  */

  @Operation(summary = "데이터셋 대용량 파일 분할 전송", description = "데이터셋 파일 대용량 파일을 청크 단위로 전송합니다.")
  @ApiResponses(
      value = {
        @ApiResponse(responseCode = "200", description = "청크 업로드 성공", content = @Content),
        @ApiResponse(responseCode = "400", description = "잘못된 요청 데이터", content = @Content),
        @ApiResponse(responseCode = "404", description = "업로드 세션을 찾을 수 없음", content = @Content),
        @ApiResponse(responseCode = "500", description = "서버 오류", content = @Content)
      })
  @PostMapping(value = "/chunk-upload-dataset", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
  public ApiResponseDto<UploadDto.UploadRes> uploadChunkDataSetFile(
      //      @RequestParam("datasetUid") long datasetUid,
      @RequestParam("fileName") String fileName,
      @RequestParam("fileSize") long fileSize,
      // @RequestParam("fileHash") String fileHash,
      @RequestParam("chunkIndex") Integer chunkIndex,
      @RequestParam("chunkTotalIndex") Integer chunkTotalIndex,
      @RequestPart("chunkFile") MultipartFile chunkFile,
      @RequestParam("uuid") UUID uuid) {

    String uploadDivi = "dataset";

    UploadDto.UploadAddReq upAddReqDto = new UploadDto.UploadAddReq();
    //    upAddReqDto.setDatasetId(datasetUid);
    upAddReqDto.setFileName(fileName);
    upAddReqDto.setFileSize(fileSize);
    upAddReqDto.setChunkIndex(chunkIndex);
    upAddReqDto.setChunkTotalIndex(chunkTotalIndex);
    upAddReqDto.setUploadDivi(uploadDivi);
    // upAddReqDto.setFileHash(fileHash);
    upAddReqDto.setUuid(uuid);

    return ApiResponseDto.ok(uploadService.uploadChunk(upAddReqDto, chunkFile));
  }

  @Operation(summary = "업로드 완료된 파일 병합", description = "업로드 완료 및 파일 병합을 요청합니다.")
  @ApiResponses(
      value = {
        @ApiResponse(responseCode = "200", description = "업로드 완료 성공", content = @Content),
        @ApiResponse(responseCode = "400", description = "잘못된 요청", content = @Content),
        @ApiResponse(responseCode = "404", description = "업로드 세션을 찾을 수 없음", content = @Content),
        @ApiResponse(responseCode = "500", description = "서버 오류", content = @Content)
      })
  @PutMapping("/chunk-upload-complete/{uuid}")
  public ApiResponseDto<DmlReturn> completeUpload(@PathVariable String uuid) {
    return ApiResponseDto.ok(uploadService.completeUpload(uuid));
  }

  /*
  @Operation(summary = "업로드 상태 조회", description = "업로드 진행 상태를 조회합니다.")
  @ApiResponses(
      value = {
        @ApiResponse(
            responseCode = "200",
            description = "조회 성공",
            content =
                @Content(
                    mediaType = "application/json",
                    schema = @Schema(implementation = UploadDto.Status.class))),
        @ApiResponse(responseCode = "404", description = "업로드 세션을 찾을 수 없음", content = @Content),
        @ApiResponse(responseCode = "500", description = "서버 오류", content = @Content)
      })
  @PostMapping("/status")
  public ApiResponseDto<UploadDto.Status> getUploadStatus(
      @RequestBody @Valid UploadDto.StatusReq statusReq) {
    return ApiResponseDto.ok(uploadService.getUploadStatus(statusReq));
  }
  */

  @Operation(summary = "분류 데이터셋 대용량 파일 분할 전송", description = "분류 데이터셋 파일 대용량 파일을 청크 단위로 전송합니다.")
  @ApiResponses(
      value = {
        @ApiResponse(responseCode = "200", description = "청크 업로드 성공", content = @Content),
        @ApiResponse(responseCode = "400", description = "잘못된 요청 데이터", content = @Content),
        @ApiResponse(responseCode = "404", description = "업로드 세션을 찾을 수 없음", content = @Content),
        @ApiResponse(responseCode = "500", description = "서버 오류", content = @Content)
      })
  @PostMapping(value = "/chunk-upload-cls", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
  public ApiResponseDto<UploadDto.UploadRes> uploadChunkClsDataSetFile(
      @RequestParam("fileName") String fileName,
      @RequestParam("fileSize") long fileSize,
      @RequestParam("chunkIndex") Integer chunkIndex,
      @RequestParam("chunkTotalIndex") Integer chunkTotalIndex,
      @RequestPart("chunkFile") MultipartFile chunkFile,
      @RequestParam("uuid") UUID uuid) {

    String uploadDivi = "cls-dataset";

    UploadDto.UploadAddReq upAddReqDto = new UploadDto.UploadAddReq();
    upAddReqDto.setFileName(fileName);
    upAddReqDto.setFileSize(fileSize);
    upAddReqDto.setChunkIndex(chunkIndex);
    upAddReqDto.setChunkTotalIndex(chunkTotalIndex);
    upAddReqDto.setUploadDivi(uploadDivi);
    upAddReqDto.setUuid(uuid);

    return ApiResponseDto.ok(uploadService.uploadChunk(upAddReqDto, chunkFile));
  }
}
