package com.bio.bio_backend.global.utils;

import org.springframework.util.StringUtils;
import org.springframework.web.multipart.MultipartFile;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.UUID;
import org.springframework.stereotype.Component;
import lombok.RequiredArgsConstructor;
import com.bio.bio_backend.domain.base.file.dto.FileUploadDto;
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 java.util.List;

/**
 * 파일 관련 유틸리티 클래스
 */
@Component
@RequiredArgsConstructor
public class FileUtils {
    
    private final FileService fileService;
    
    /**
     * 파일 유효성 검사
     */
    public static void validateFile(MultipartFile multipartFile) {
        if (multipartFile == null || multipartFile.isEmpty()) {
            throw new IllegalArgumentException("업로드할 파일이 없습니다.");
        }
    }
    
    /**
     * 파일 리스트 유효성 검사
     */
    public static void validateFileList(java.util.List<MultipartFile> files) {
        if (files == null || files.isEmpty()) {
            throw new IllegalArgumentException("업로드할 파일이 없습니다.");
        }
    }
    
    /**
     * 년월 기반 업로드 디렉토리 생성
     * 예: uploads/2024/01/
     */
    public static Path createYearMonthUploadDirectory(String baseUploadPath) throws IOException {
        LocalDate today = LocalDate.now();
        String yearMonth = today.format(DateTimeFormatter.ofPattern("yyyy/MM"));
        
        Path yearMonthPath = Paths.get(baseUploadPath, yearMonth);
        if (!Files.exists(yearMonthPath)) {
            Files.createDirectories(yearMonthPath);
        }
        return yearMonthPath;
    }
    
    /**
     * 파일 확장자 추출
     */
    public static String extractFileExtension(String originalFileName) {
        if (originalFileName == null || !originalFileName.contains(".")) {
            return "";
        }
        return originalFileName.substring(originalFileName.lastIndexOf("."));
    }
    
    /**
     * 고유한 파일명 생성
     */
    public static String generateUniqueFileName(String fileExtension) {
        return UUID.randomUUID().toString() + fileExtension;
    }
    
    /**
     * 파일을 디스크에 저장
     */
    public static Path saveFileToDisk(MultipartFile multipartFile, Path uploadDir, String storedFileName) throws IOException {
        Path targetLocation = uploadDir.resolve(storedFileName);
        Files.copy(multipartFile.getInputStream(), targetLocation, java.nio.file.StandardCopyOption.REPLACE_EXISTING);
        return targetLocation;
    }
    
    /**
     * 원본 파일명 정리 (경로 정보 제거)
     */
    public static String cleanFileName(String originalFileName) {
        return StringUtils.cleanPath(originalFileName);
    }

    
    /**
     * 파일 업로드 (단일/다중 파일 모두 지원)
     * 사용 예시:
     * // 단일 파일 업로드
     * FileUploadDto fileResult = fileUtils.uploadFile(
     *     requestDto.getFile(),
     *     "프로필 이미지"
     * );
     * member.setFileGroupId(fileResult.getGroupOid());
     * // 다중 파일 업로드
     * FileUploadDto filesResult = fileUtils.uploadFiles(
     *     requestDto.getFiles(), 
     *     "게시판 첨부파일: " + board.getTitle()
     * );
     * board.setFileGroupId(filesResult.getGroupOid());
     */
    public FileUploadDto uploadFile(MultipartFile file, String description) {
        // 단일 파일도 List로 감싸서 다중 파일 업로드 방식 사용
        List<MultipartFile> files = List.of(file);
        return uploadFiles(files, description);
    }
    
    public FileUploadDto uploadFiles(List<MultipartFile> files, String description) {
        MultipleFileUploadRequestDto requestDto = MultipleFileUploadRequestDto.builder()
            .files(files)
            .description(description)
            .build();
        
        MultipleFileUploadResponseDto response = fileService.uploadMultipleFiles(requestDto);
        
        return FileUploadDto.builder()
            .groupOid(response.getGroupOid())
            .files(response.getFiles())
            .totalCount(response.getTotalCount())
            .successCount(response.getSuccessCount())
            .failureCount(response.getFailureCount())
            .errorMessages(response.getErrorMessages())
            .build();
    }
}
