package com.nailart.utils;

/**
 * @Classname AliyunOSSUtils
 * @Description 阿里云对象存储工具类
 * @Date 2025/7/10 19:11
 * @Created by 21616
 */

import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSClientBuilder;
import com.aliyun.oss.model.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;

import java.io.*;
import java.net.URL;
import java.util.Date;
import java.util.List;
import java.util.UUID;

/**
 * 阿里云OSS操作工具类
 */
@Component
public class AliyunOSSUtils {

    private static final Logger logger = LoggerFactory.getLogger(AliyunOSSUtils.class);

    @Value("${aliyun.oss.endpoint}")
    private String endpoint;

    @Value("${aliyun.oss.access-key-id}")
    private String accessKeyId;

    @Value("${aliyun.oss.access-key-secret}")
    private String accessKeySecret;

    @Value("${aliyun.oss.bucket-name}")
    private String bucketName;

    @Value("${aliyun.oss.file-host}")
    private String fileHost;

    /**
     * 上传文件到OSS
     *
     * @param file      上传的文件
     * @param directory 存储目录
     * @return 文件访问URL
     */
    public String uploadFile(MultipartFile file, String directory) {
        OSS ossClient = null;
        try {
            // 生成文件名
            String originalFilename = file.getOriginalFilename();
            String fileExtension = originalFilename.substring(originalFilename.lastIndexOf("."));
            String fileName = UUID.randomUUID().toString().replace("-", "") + fileExtension;

            // 构建完整路径
            if (directory != null && !directory.isEmpty()) {
                if (!directory.endsWith("/")) {
                    directory = directory + "/";
                }
                fileName = directory + fileName;
            }

            // 创建OSSClient实例
            ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);

            // 上传文件
            ossClient.putObject(bucketName, fileName, new ByteArrayInputStream(file.getBytes()));

            // 返回访问URL
            return fileHost + "/" + fileName;
        } catch (Exception e) {
            logger.error("上传文件失败: {}", e.getMessage(), e);
            return null;
        } finally {
            // 关闭OSSClient
            if (ossClient != null) {
                ossClient.shutdown();
            }
        }
    }

    /**
     * 上传本地文件到OSS
     *
     * @param filePath       文件路径
     * @param targetFileName 目标文件名
     * @return 文件访问URL
     */
    public String uploadLocalFile(String filePath, String targetFileName) {
        OSS ossClient = null;
        try {
            // 创建OSSClient实例
            ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);

            // 上传文件
            ossClient.putObject(bucketName, targetFileName, new File(filePath));

            // 返回访问URL
            return fileHost + "/" + targetFileName;
        } catch (Exception e) {
            logger.error("上传本地文件失败: {}", e.getMessage(), e);
            return null;
        } finally {
            // 关闭OSSClient
            if (ossClient != null) {
                ossClient.shutdown();
            }
        }
    }

    /**
     * 下载文件
     *
     * @param objectName    对象名称
     * @param localFilePath 本地文件路径
     * @return 是否下载成功
     */
    public boolean downloadFile(String objectName, String localFilePath) {
        OSS ossClient = null;
        try {
            // 创建OSSClient实例
            ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);

            // 下载OSS文件到本地文件
            ossClient.getObject(new GetObjectRequest(bucketName, objectName), new File(localFilePath));

            return true;
        } catch (Exception e) {
            logger.error("下载文件失败: {}", e.getMessage(), e);
            return false;
        } finally {
            // 关闭OSSClient
            if (ossClient != null) {
                ossClient.shutdown();
            }
        }
    }

    /**
     * 删除文件
     *
     * @param objectName 对象名称
     * @return 是否删除成功
     */
    public boolean deleteFile(String objectName) {
        OSS ossClient = null;
        try {
            // 创建OSSClient实例
            ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);

            // 删除文件
            ossClient.deleteObject(bucketName, objectName);

            return true;
        } catch (Exception e) {
            logger.error("删除文件失败: {}", e.getMessage(), e);
            return false;
        } finally {
            // 关闭OSSClient
            if (ossClient != null) {
                ossClient.shutdown();
            }
        }
    }

    /**
     * 批量删除文件
     *
     * @param objectNames 对象名称列表
     * @return 删除结果
     */
    public DeleteObjectsResult deleteFiles(List<String> objectNames) {
        OSS ossClient = null;
        try {
            // 创建OSSClient实例
            ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);

            // 批量删除文件
            DeleteObjectsRequest deleteObjectsRequest = new DeleteObjectsRequest(bucketName)
                    .withKeys(objectNames);
            return ossClient.deleteObjects(deleteObjectsRequest);
        } catch (Exception e) {
            logger.error("批量删除文件失败: {}", e.getMessage(), e);
            return null;
        } finally {
            // 关闭OSSClient
            if (ossClient != null) {
                ossClient.shutdown();
            }
        }
    }

    /**
     * 获取文件URL（带签名，用于临时访问）
     *
     * @param objectName 对象名称
     * @param expires    过期时间（秒）
     * @return 带签名的URL
     */
    public String getSignedUrl(String objectName, long expires) {
        OSS ossClient = null;
        try {
            // 创建OSSClient实例
            ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);

            // 设置URL过期时间
            Date expiration = new Date(System.currentTimeMillis() + expires * 1000);

            // 生成签名URL
            URL url = ossClient.generatePresignedUrl(bucketName, objectName, expiration);

            return url.toString();
        } catch (Exception e) {
            logger.error("获取签名URL失败: {}", e.getMessage(), e);
            return null;
        } finally {
            // 关闭OSSClient
            if (ossClient != null) {
                ossClient.shutdown();
            }
        }
    }

    /**
     * 判断文件是否存在
     *
     * @param objectName 对象名称
     * @return 是否存在
     */
    public boolean doesObjectExist(String objectName) {
        OSS ossClient = null;
        try {
            // 创建OSSClient实例
            ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);

            // 判断文件是否存在
            return ossClient.doesObjectExist(bucketName, objectName);
        } catch (Exception e) {
            logger.error("检查文件是否存在失败: {}", e.getMessage(), e);
            return false;
        } finally {
            // 关闭OSSClient
            if (ossClient != null) {
                ossClient.shutdown();
            }
        }
    }

    /**
     * 获取文件元信息
     *
     * @param objectName 对象名称
     * @return 文件元信息
     */
    public ObjectMetadata getObjectMetadata(String objectName) {
        OSS ossClient = null;
        try {
            // 创建OSSClient实例
            ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);

            // 获取文件元信息
            return ossClient.getObjectMetadata(bucketName, objectName);
        } catch (Exception e) {
            logger.error("获取文件元信息失败: {}", e.getMessage(), e);
            return null;
        } finally {
            // 关闭OSSClient
            if (ossClient != null) {
                ossClient.shutdown();
            }
        }
    }

    /**
     * 列出指定目录下的文件
     *
     * @param prefix  前缀（目录）
     * @param maxKeys 最大返回数量
     * @return 文件列表
     */
    public ListObjectsV2Result listObjects(String prefix, int maxKeys) {
        OSS ossClient = null;
        try {
            // 创建OSSClient实例
            ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);

            // 构造ListObjects请求
            ListObjectsV2Request listObjectsV2Request = new ListObjectsV2Request();
            listObjectsV2Request.setBucketName(bucketName);
            listObjectsV2Request.setPrefix(prefix);
            listObjectsV2Request.setMaxKeys(maxKeys);

            // 列出文件
            return ossClient.listObjectsV2(listObjectsV2Request);
        } catch (Exception e) {
            logger.error("列出文件失败: {}", e.getMessage(), e);
            return null;
        } finally {
            // 关闭OSSClient
            if (ossClient != null) {
                ossClient.shutdown();
            }
        }
    }
}
