package com.rj.service;

import com.rj.config.MinIOConfig;
import com.rj.utils.MinIOUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.InputStream;
import java.util.List;

/**
 * MinIO 服务类
 * 封装MinIO相关业务逻辑
 * 
 * @author rj
 * @date 2025-10-02
 */
@Slf4j
@Service
public class MinIOService {

    @Autowired
    private MinIOUtil minioUtil;

    @Autowired
    private MinIOConfig minioConfig;

    /**
     * 上传文件到默认存储桶
     * 
     * @param file 文件
     * @return 文件访问URL
     */
    public String uploadFile(MultipartFile file) {
        String objectName = minioUtil.uploadFile(file, minioConfig.getBucketName());
        return getFileUrl(objectName);
    }

    /**
     * 上传文件到指定存储桶
     * 
     * @param file 文件
     * @param bucketName 存储桶名称
     * @return 文件访问URL
     */
    public String uploadFile(MultipartFile file, String bucketName) {
        String objectName = minioUtil.uploadFile(file, bucketName);
        return getFileUrl(bucketName, objectName);
    }
    
    /**
     * 上传字节数组到默认存储桶
     * 
     * @param data 字节数组
     * @param fileName 文件名
     * @param contentType 内容类型
     * @return 文件访问URL
     */
    public String uploadFile(byte[] data, String fileName, String contentType) {
        String objectName = minioUtil.uploadFile(data, fileName, contentType);
        return getFileUrl(objectName);
    }
    
    /**
     * 上传字节数组到指定存储桶
     * 
     * @param data 字节数组
     * @param bucketName 存储桶名称
     * @param fileName 文件名
     * @param contentType 内容类型
     * @return 文件访问URL
     */
    public String uploadFile(byte[] data, String bucketName, String fileName, String contentType) {
        String objectName = minioUtil.uploadFile(data,  fileName, contentType);
        return getFileUrl(objectName);
    }

    /**
     * 上传文件并指定文件名
     * 
     * @param file 文件
     * @param fileName 文件名
     * @return 文件访问URL
     */
    public String uploadFileWithName(MultipartFile file, String fileName) {
        String objectName = minioUtil.uploadFile(file, minioConfig.getBucketName(), fileName);
        return getFileUrl(objectName);
    }

    /**
     * 上传文件并生成7天临时访问链接
     * 
     * @param file 文件
     * @return 7天有效期的临时访问URL
     */
    public String uploadFileWithTempUrl(MultipartFile file) {
        String objectName = minioUtil.uploadFile(file, minioConfig.getBucketName());
        return minioUtil.getPresignedObjectUrl(minioConfig.getBucketName(), objectName);
    }

    /**
     * 为已上传的文件生成7天临时访问链接
     * 
     * @param objectName 对象名称
     * @return 7天有效期的临时访问URL
     */
    public String generateTempUrl(String objectName) {
        return minioUtil.getPresignedObjectUrl(minioConfig.getBucketName(), objectName);
    }

    /**
     * 上传文件流
     * 
     * @param inputStream 文件流
     * @param fileName 文件名
     * @param contentType 内容类型
     * @return 文件访问URL
     */
    public String uploadFile(InputStream inputStream, String fileName, String contentType) {
        boolean success = minioUtil.uploadFile(inputStream, minioConfig.getBucketName(), fileName, contentType);
        if (success) {
            return getFileUrl(fileName);
        }
        throw new RuntimeException("文件上传失败");
    }

    /**
     * 下载文件
     * 
     * @param fileName 文件名
     * @return 文件流
     */
    public InputStream downloadFile(String fileName) {
        return minioUtil.downloadFile(minioConfig.getBucketName(), fileName);
    }

    /**
     * 下载文件
     * 
     * @param bucketName 存储桶名称
     * @param fileName 文件名
     * @return 文件流
     */
    public InputStream downloadFile(String bucketName, String fileName) {
        return minioUtil.downloadFile(bucketName, fileName);
    }

    /**
     * 删除文件
     * 
     * @param fileName 文件名
     * @return 是否删除成功
     */
    public boolean deleteFile(String fileName) {
        return minioUtil.removeFile(minioConfig.getBucketName(), fileName);
    }

    /**
     * 删除文件
     * 
     * @param bucketName 存储桶名称
     * @param fileName 文件名
     * @return 是否删除成功
     */
    public boolean deleteFile(String bucketName, String fileName) {
        return minioUtil.removeFile(bucketName, fileName);
    }

    /**
     * 获取文件列表
     * 
     * @return 文件列表
     */
    public List<String> listFiles() {
        return minioUtil.listFiles(minioConfig.getBucketName());
    }

    /**
     * 获取文件列表
     * 
     * @param bucketName 存储桶名称
     * @return 文件列表
     */
    public List<String> listFiles(String bucketName) {
        return minioUtil.listFiles(bucketName);
    }

    /**
     * 获取文件详细信息列表
     * 
     * @return 文件详细信息列表
     */
    public List<MinIOUtil.FileInfo> listFileDetails() {
        return minioUtil.listFileDetails(minioConfig.getBucketName());
    }

    /**
     * 获取文件详细信息列表
     * 
     * @param bucketName 存储桶名称
     * @return 文件详细信息列表
     */
    public List<MinIOUtil.FileInfo> listFileDetails(String bucketName) {
        return minioUtil.listFileDetails(bucketName);
    }

    /**
     * 获取文件预签名URL
     * 
     * @param fileName 文件名
     * @param expires 过期时间（秒）
     * @return 预签名URL
     */
    public String getPresignedUrl(String fileName, int expires) {
        return minioUtil.getPresignedObjectUrl(minioConfig.getBucketName(), fileName, expires);
    }

    /**
     * 获取文件预签名URL（默认7天过期）
     * 
     * @param fileName 文件名
     * @return 预签名URL
     */
    public String getPresignedUrl(String fileName) {
        return minioUtil.getPresignedObjectUrl(minioConfig.getBucketName(), fileName);
    }

    /**
     * 复制文件
     * 
     * @param sourceFileName 源文件名
     * @param targetFileName 目标文件名
     * @return 是否复制成功
     */
    public boolean copyFile(String sourceFileName, String targetFileName) {
        return minioUtil.copyFile(minioConfig.getBucketName(), sourceFileName, 
                                 minioConfig.getBucketName(), targetFileName);
    }

    /**
     * 复制文件到其他存储桶
     * 
     * @param sourceFileName 源文件名
     * @param targetBucketName 目标存储桶名称
     * @param targetFileName 目标文件名
     * @return 是否复制成功
     */
    public boolean copyFile(String sourceFileName, String targetBucketName, String targetFileName) {
        return minioUtil.copyFile(minioConfig.getBucketName(), sourceFileName, 
                                 targetBucketName, targetFileName);
    }

    /**
     * 检查文件是否存在
     * 
     * @param fileName 文件名
     * @return 是否存在
     */
    public boolean fileExists(String fileName) {
        return minioUtil.getFileInfo(minioConfig.getBucketName(), fileName) != null;
    }

    /**
     * 检查文件是否存在
     * 
     * @param bucketName 存储桶名称
     * @param fileName 文件名
     * @return 是否存在
     */
    public boolean fileExists(String bucketName, String fileName) {
        return minioUtil.getFileInfo(bucketName, fileName) != null;
    }

    /**
     * 获取文件访问URL
     * 
     * @param fileName 文件名
     * @return 文件访问URL
     */
    public String getFileUrl(String fileName) {
        return minioConfig.getFileUrlPrefix() + fileName;
    }

    /**
     * 获取文件访问URL
     * 
     * @param bucketName 存储桶名称
     * @param fileName 文件名
     * @return 文件访问URL
     */
    public String getFileUrl(String bucketName, String fileName) {
        return minioConfig.getEndpoint() + "/" + bucketName + "/" + fileName;
    }

    /**
     * 创建存储桶
     * 
     * @param bucketName 存储桶名称
     * @return 是否创建成功
     */
    public boolean createBucket(String bucketName) {
        return minioUtil.createBucket(bucketName);
    }

    /**
     * 删除存储桶
     * 
     * @param bucketName 存储桶名称
     * @return 是否删除成功
     */
    public boolean deleteBucket(String bucketName) {
        return minioUtil.removeBucket(bucketName);
    }

    /**
     * 获取所有存储桶
     * 
     * @return 存储桶列表
     */
    public List<String> getAllBuckets() {
        return minioUtil.getAllBuckets();
    }
}
