package com.bio.bio_backend.domain.base.file.controller;

import com.bio.bio_backend.domain.base.file.dto.FileUploadRequestDto;
import com.bio.bio_backend.domain.base.file.dto.FileUploadResponseDto;
import com.bio.bio_backend.domain.base.file.dto.MultipleFileUploadRequestDto;
import com.bio.bio_backend.domain.base.file.dto.MultipleFileUploadResponseDto;
import com.bio.bio_backend.domain.base.file.service.FileService;
import com.bio.bio_backend.global.dto.ApiResponseDto;
import com.bio.bio_backend.global.constants.ApiResponseCode;
import com.bio.bio_backend.global.annotation.LogExecution;
import com.bio.bio_backend.global.utils.FileUtils;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import io.swagger.v3.oas.annotations.responses.ApiResponses;
import io.swagger.v3.oas.annotations.media.Content;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.core.io.ByteArrayResource;
import org.springframework.http.HttpHeaders;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import com.bio.bio_backend.domain.base.file.entity.File;


@Tag(name = "File", description = "파일 업로드/다운로드 API")
@RestController
@RequestMapping("/files")
@RequiredArgsConstructor
@Slf4j
public class FileController {

    private final FileService fileService;
    
    @LogExecution("파일 업로드")
    @Operation(summary = "파일 업로드", description = "단일 파일을 업로드합니다.")
    @ApiResponses({
        @ApiResponse(responseCode = "200", description = "파일 업로드 성공"),
        @ApiResponse(responseCode = "400", description = "잘못된 요청 데이터", content = @Content),
        @ApiResponse(responseCode = "500", description = "파일 업로드 실패", content = @Content)
    })
    @PostMapping("/upload")
    public ResponseEntity<ApiResponseDto<FileUploadResponseDto>> uploadFile(
            @ModelAttribute FileUploadRequestDto requestDto) {
        
        FileUploadResponseDto responseDto = fileService.uploadFile(requestDto);
        
        return ResponseEntity.ok(ApiResponseDto.success(ApiResponseCode.FILE_UPLOAD_SUCCESS, responseDto));
    }

    @LogExecution("다중 파일 업로드")
    @Operation(summary = "다중 파일 업로드", description = "여러 파일을 동시에 업로드합니다.")
    @ApiResponses({
        @ApiResponse(responseCode = "200", description = "다중 파일 업로드 성공"),
        @ApiResponse(responseCode = "400", description = "잘못된 요청 데이터", content = @Content),
        @ApiResponse(responseCode = "500", description = "다중 파일 업로드 실패", content = @Content)
    })
    @PostMapping("/upload-multiple")
    public ResponseEntity<ApiResponseDto<MultipleFileUploadResponseDto>> uploadMultipleFiles(
            @ModelAttribute MultipleFileUploadRequestDto requestDto) {
        
        MultipleFileUploadResponseDto responseDto = fileService.uploadMultipleFiles(requestDto);
        
        return ResponseEntity.ok(ApiResponseDto.success(ApiResponseCode.FILE_UPLOAD_SUCCESS, responseDto));
    }
    
    @LogExecution("파일 다운로드")
    @Operation(summary = "파일 다운로드", description = "파일 ID로 파일을 다운로드합니다.")
    @ApiResponses({
        @ApiResponse(responseCode = "200", description = "파일 다운로드 성공"),
        @ApiResponse(responseCode = "404", description = "파일을 찾을 수 없음", content = @Content),
        @ApiResponse(responseCode = "500", description = "파일 다운로드 실패", content = @Content)
    })
    @GetMapping("/download/{oid}")
    public ResponseEntity<ByteArrayResource> downloadFile(@PathVariable Long oid) {
        // 파일 정보 먼저 조회
        File file = fileService.getFileByOid(oid);
        byte[] fileData = fileService.downloadFile(oid);
        ByteArrayResource resource = new ByteArrayResource(fileData);
        
        return ResponseEntity.ok()
                .header(HttpHeaders.CONTENT_DISPOSITION, 
                    "attachment; filename=\"" + file.getOriginalFileName() + "\"")
                .header(HttpHeaders.CONTENT_TYPE, file.getContentType())
                .body(resource);
    }
    
    @LogExecution("파일 논리적 삭제")
    @Operation(summary = "파일 논리적 삭제", description = "파일 ID로 파일을 논리적으로 삭제합니다. (use_flag를 false로 변경)")
    @ApiResponses({
        @ApiResponse(responseCode = "200", description = "파일 논리적 삭제 성공"),
        @ApiResponse(responseCode = "404", description = "파일을 찾을 수 없음", content = @Content),
        @ApiResponse(responseCode = "500", description = "파일 논리적 삭제 실패", content = @Content)
    })
    @DeleteMapping("/{oid}")
    public ResponseEntity<ApiResponseDto<Void>> deleteFile(@PathVariable Long oid) {
        fileService.deleteFile(oid);
        return ResponseEntity.ok(ApiResponseDto.success(ApiResponseCode.FILE_DELETE_SUCCESS));
    }
}
