package com.bonus.oss.utils;

import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSClientBuilder;
import com.aliyun.oss.model.OSSObject;
import com.aliyun.oss.model.ObjectMetadata;
import com.bonus.common.core.domain.R;
import com.bonus.common.core.text.Convert;
import com.bonus.common.core.utils.file.FileUtils;
import com.bonus.oss.config.OSSConfig;
import com.bonus.oss.domain.OssInfo;
import org.apache.poi.ss.formula.functions.T;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import java.io.File;

/**
 * OSS存储服务类
 */
@Service
public class OssUtils {

    private static final Logger LOGGER = LoggerFactory.getLogger(OssUtils.class);

    @Resource
    private OSSConfig ossConfig;

    /**
     * OSS客户端
     */
    private OSS ossClient;

    /**
     * 初始化OSS客户端
     */
    @PostConstruct
    public void init() {
        ossClient = new OSSClientBuilder().build(ossConfig.getEndpoint(), ossConfig.getAccessKeyId(), ossConfig.getAccessKeySecret());
    }

    /**
     * 上传文件到OSS
     *
     * @param objectKey 文件在OSS中的键
     * @param file      要上传的文件
     * @return 包含上传文件信息的结果对象
     */
    public R<OssInfo> upload(String objectKey, File file) {
        try {
            ossClient.putObject(ossConfig.getBucket(), objectKey, file);
            return R.ok(getInfo(objectKey), "文件上传成功");
        } catch (Exception e) {
            LOGGER.error("文件上传失败", e);
            return R.fail("文件上传失败");
        } finally {
            if (!file.delete()) {
                LOGGER.warn("临时文件删除失败");
            }
        }
    }

    /**
     * 获取文件在OSS中的信息
     *
     * @param objectKey 文件路径
     * @return 文件信息对象
     */
    public OssInfo getInfo(String objectKey) {
        try {
            ObjectMetadata objectMetadata = ossClient.getObjectMetadata(ossConfig.getBucket(), objectKey);
            return OssInfo.builder()
                    .name(FileUtils.getName(objectKey))
                    .bucketName(ossConfig.getBucket())
                    .fileType(objectMetadata.getContentType())
                    .length(Convert.toStr(objectMetadata.getContentLength()))
                    .path(objectKey).build();
        } catch (Exception e) {
            LOGGER.error("获取文件信息失败", e);
            return OssInfo.builder().build();
        }
    }

    /**
     * 从OSS下载文件
     *
     * @param objectKey 文件路径
     * @return OSSObject对象，包含下载的文件
     */
    public R<OSSObject> download(String objectKey) {
        if (doesObjectExist(ossConfig.getBucket(), objectKey)) {
            return R.fail("文件不存在");
        }
        try {
            return R.ok(ossClient.getObject(ossConfig.getBucket(), objectKey));
        } catch (Exception e) {
            LOGGER.error("文件下载失败", e);
            return R.fail("文件下载失败");
        }
    }

    /**
     * 删除OSS中的文件
     *
     * @param objectKey 文件路径
     * @return 删除操作的结果
     */
    public R<T> delete(String objectKey) {
        try {
            if (doesObjectExist(ossConfig.getBucket(), objectKey)) {
                return R.fail("文件不存在");
            }
            ossClient.deleteObject(ossConfig.getBucket(), objectKey);
            return R.ok(null,"文件删除成功");
        } catch (Exception e) {
            LOGGER.error("文件删除失败", e);
            return R.fail("文件删除失败");
        }
    }

    /**
     * 检查OSS中是否存在指定的文件
     *
     * @param bucketName Bucket名称
     * @param objectKey  文件路径
     * @return 如果文件存在返回true，否则返回false
     */
    private boolean doesObjectExist(String bucketName, String objectKey) {
        try {
            return !ossClient.doesObjectExist(bucketName, objectKey);
        } catch (Exception e) {
            LOGGER.error("判断文件是否存在失败", e);
            return true;
        }
    }
}
