using AlibabaCloud.SDK.Sts20150401;
using Aliyun.OSS;
using Aliyun.OSS.Common;
using Amazon;
using Amazon.Runtime;
using Amazon.S3;
using Amazon.S3.Model;
using Amazon.SecurityToken;
using Amazon.SecurityToken.Model;
using IRaCIS.Core.Infrastructure;
using IRaCIS.Core.Infrastructure.NewtonsoftJson;
using MassTransit;
using MassTransit.Caching.Internals;
using Microsoft.Extensions.Options;
using Minio;
using Minio.DataModel;
using Minio.DataModel.Args;
using Minio.Exceptions;
using System.Reactive.Linq;
using System.Runtime.InteropServices;

namespace IRaCIS.Core.Application.Helper;

#region 绑定和返回模型

[LowerCamelCaseJson]
public class MinIOOptions : AWSOptions
{
    public int Port { get; set; }

}


public class AWSOptions
{
    public string EndPoint { get; set; }
    public bool UseSSL { get; set; }
    public string AccessKeyId { get; set; }
    public string RoleArn { get; set; }
    public string SecretAccessKey { get; set; }
    public string BucketName { get; set; }
    public string ViewEndpoint { get; set; }
    public int DurationSeconds { get; set; }
    public string Region { get; set; }
}

public class AliyunOSSOptions
{
    public string RegionId { get; set; }
    public string AccessKeyId { get; set; }
    public string AccessKeySecret { get; set; }

    public string InternalEndpoint { get; set; }

    public string EndPoint { get; set; }
    public string BucketName { get; set; }

    public string RoleArn { get; set; }

    public string Region { get; set; }

    public string ViewEndpoint { get; set; }

    public int DurationSeconds { get; set; }

    public string PreviewEndpoint { get; set; }

}

public class ObjectStoreServiceOptions
{
    public string ObjectStoreUse { get; set; }

    public AliyunOSSOptions AliyunOSS { get; set; }


    public MinIOOptions MinIO { get; set; }

    public AWSOptions AWS { get; set; }

}

public class ObjectStoreDTO
{
    public string ObjectStoreUse { get; set; }


    public AliyunOSSTempToken AliyunOSS { get; set; }

    public MinIOOptions MinIO { get; set; }

    public AWSTempToken AWS { get; set; }

}

[LowerCamelCaseJson]
public class AliyunOSSTempToken
{
    public string AccessKeyId { get; set; }
    public string AccessKeySecret { get; set; }

    public string EndPoint { get; set; }
    public string BucketName { get; set; }

    public string Region { get; set; }

    public string ViewEndpoint { get; set; }

    public string SecurityToken { get; set; }
    public DateTime Expiration { get; set; }

    public string PreviewEndpoint { get; set; }

}

[LowerCamelCaseJson]
public class AWSTempToken
{
    public string Region { get; set; }
    public string SessionToken { get; set; }
    public string EndPoint { get; set; }
    public string AccessKeyId { get; set; }
    public string SecretAccessKey { get; set; }
    public string BucketName { get; set; }
    public string ViewEndpoint { get; set; }
    public DateTime Expiration { get; set; }
}

public enum ObjectStoreUse
{
    AliyunOSS = 0,
    MinIO = 1,
    AWS = 2,
}

#endregion

// aws 参考链接 https://github.com/awsdocs/aws-doc-sdk-examples/tree/main/dotnetv3/S3/S3_Basics

public interface IOSSService
{
    public Task<string> UploadToOSSAsync(Stream fileStream, string oosFolderPath, string fileRealName, bool isFileNameAddGuid = true);
    public Task<string> UploadToOSSAsync(string localFilePath, string oosFolderPath, bool isFileNameAddGuid = true);

    public Task DownLoadFromOSSAsync(string ossRelativePath, string localFilePath);

    public ObjectStoreServiceOptions ObjectStoreServiceOptions { get; set; }

    public Task<string> GetSignedUrl(string ossRelativePath);

    public Task DeleteFromPrefix(string prefix, bool isCache = false);

    public Task DeleteObjects(List<string> objectKeys);

    List<string> GetRootFolderNames();

    public ObjectStoreDTO GetObjectStoreTempToken();

    public Task MoveObject(string sourcePath, string destPath, bool overwrite = true);

    public Task<long> GetObjectSizeAsync(string sourcePath);
}


public class OSSService : IOSSService
{
    public ObjectStoreServiceOptions ObjectStoreServiceOptions { get; set; }

    private AliyunOSSTempToken AliyunOSSTempToken { get; set; }

    private AWSTempToken AWSTempToken { get; set; }


    public OSSService(IOptionsMonitor<ObjectStoreServiceOptions> options)
    {
        ObjectStoreServiceOptions = options.CurrentValue;

    }



    /// <summary>
    ///  oosFolderPath  不要 "/ "开头   应该: TempFolder/ChildFolder
    /// </summary>
    /// <param name="fileStream"></param>
    /// <param name="oosFolderPath"></param>
    /// <param name="fileRealName"></param>
    /// <param name="isFileNameAddGuid"></param>
    /// <returns></returns>
    public async Task<string> UploadToOSSAsync(Stream fileStream, string oosFolderPath, string fileRealName, bool isFileNameAddGuid = true)
    {
        GetObjectStoreTempToken();

        var ossRelativePath = isFileNameAddGuid ? $"{oosFolderPath}/{Guid.NewGuid()}_{fileRealName}" : $"{oosFolderPath}/{fileRealName}";

        try
        {
            using (var memoryStream = new MemoryStream())
            {
                fileStream.Seek(0, SeekOrigin.Begin);

                fileStream.CopyTo(memoryStream);

                memoryStream.Seek(0, SeekOrigin.Begin);


                if (ObjectStoreServiceOptions.ObjectStoreUse == "AliyunOSS")
                {
                    var aliConfig = ObjectStoreServiceOptions.AliyunOSS;

                    var _ossClient = new OssClient(RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? aliConfig.EndPoint : aliConfig.InternalEndpoint, AliyunOSSTempToken.AccessKeyId, AliyunOSSTempToken.AccessKeySecret, AliyunOSSTempToken.SecurityToken);



                    // 上传文件
                    var result = _ossClient.PutObject(aliConfig.BucketName, ossRelativePath, memoryStream);

                }
                else if (ObjectStoreServiceOptions.ObjectStoreUse == "MinIO")
                {
                    var minIOConfig = ObjectStoreServiceOptions.MinIO;


                    var minioClient = new MinioClient().WithEndpoint($"{minIOConfig.EndPoint}:{minIOConfig.Port}")
                        .WithCredentials(minIOConfig.AccessKeyId, minIOConfig.SecretAccessKey).WithSSL(minIOConfig.UseSSL)
                        .Build();

                    var putObjectArgs = new PutObjectArgs()
                           .WithBucket(minIOConfig.BucketName)
                           .WithObject(ossRelativePath)
                           .WithStreamData(memoryStream)
                           .WithObjectSize(memoryStream.Length);

                    await minioClient.PutObjectAsync(putObjectArgs);
                }
                else if (ObjectStoreServiceOptions.ObjectStoreUse == "AWS")
                {
                    var awsConfig = ObjectStoreServiceOptions.AWS;

                    var credentials = new SessionAWSCredentials(AWSTempToken.AccessKeyId, AWSTempToken.SecretAccessKey, AWSTempToken.SessionToken);



                    //提供awsEndPoint(域名)进行访问配置
                    var clientConfig = new AmazonS3Config
                    {
                        RegionEndpoint = RegionEndpoint.USEast1,
                        UseHttp = true,
                    };

                    var amazonS3Client = new AmazonS3Client(credentials, clientConfig);

                    var putObjectRequest = new Amazon.S3.Model.PutObjectRequest()
                    {
                        BucketName = awsConfig.BucketName,
                        InputStream = memoryStream,
                        Key = ossRelativePath,
                    };

                    await amazonS3Client.PutObjectAsync(putObjectRequest);
                }
                else
                {
                    throw new BusinessValidationFailedException("未定义的存储介质类型");
                }
            }
        }
        catch (Exception ex)
        {

            throw new BusinessValidationFailedException($"上传发生异常:{ex.Message}");
        }




        return "/" + ossRelativePath;

    }



    /// <summary>
    /// oosFolderPath  不要 "/ "开头   应该: TempFolder/ChildFolder
    /// </summary>
    /// <param name="localFilePath"></param>
    /// <param name="oosFolderPath"></param>
    /// <param name="isFileNameAddGuid"></param>
    /// <returns></returns>
    /// <exception cref="BusinessValidationFailedException"></exception>
    public async Task<string> UploadToOSSAsync(string localFilePath, string oosFolderPath, bool isFileNameAddGuid = true)
    {
        GetObjectStoreTempToken();

        var localFileName = Path.GetFileName(localFilePath);

        var ossRelativePath = isFileNameAddGuid ? $"{oosFolderPath}/{Guid.NewGuid()}_{localFileName}" : $"{oosFolderPath}/{localFileName}";


        if (ObjectStoreServiceOptions.ObjectStoreUse == "AliyunOSS")
        {
            var aliConfig = ObjectStoreServiceOptions.AliyunOSS;

            var _ossClient = new OssClient(RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? aliConfig.EndPoint : aliConfig.InternalEndpoint, AliyunOSSTempToken.AccessKeyId, AliyunOSSTempToken.AccessKeySecret, AliyunOSSTempToken.SecurityToken);

            // 上传文件
            var result = _ossClient.PutObject(aliConfig.BucketName, ossRelativePath, localFilePath);

        }
        else if (ObjectStoreServiceOptions.ObjectStoreUse == "MinIO")
        {
            var minIOConfig = ObjectStoreServiceOptions.MinIO;


            var minioClient = new MinioClient().WithEndpoint($"{minIOConfig.EndPoint}:{minIOConfig.Port}")
                .WithCredentials(minIOConfig.AccessKeyId, minIOConfig.SecretAccessKey).WithSSL(minIOConfig.UseSSL)
                .Build();

            var putObjectArgs = new PutObjectArgs()
                   .WithBucket(minIOConfig.BucketName)
                   .WithObject(ossRelativePath)
                   .WithFileName(localFilePath);

            await minioClient.PutObjectAsync(putObjectArgs);
        }
        else if (ObjectStoreServiceOptions.ObjectStoreUse == "AWS")
        {
            var awsConfig = ObjectStoreServiceOptions.AWS;

            // 提供awsAccessKeyId和awsSecretAccessKey构造凭证
            var credentials = new SessionAWSCredentials(AWSTempToken.AccessKeyId, AWSTempToken.SecretAccessKey, AWSTempToken.SessionToken);

            //提供awsEndPoint(域名)进行访问配置
            var clientConfig = new AmazonS3Config
            {
                RegionEndpoint = RegionEndpoint.USEast1,
                UseHttp = true,
            };

            var amazonS3Client = new AmazonS3Client(credentials, clientConfig);

            var putObjectRequest = new Amazon.S3.Model.PutObjectRequest()
            {
                BucketName = awsConfig.BucketName,
                FilePath = localFilePath,
                Key = ossRelativePath,
            };

            await amazonS3Client.PutObjectAsync(putObjectRequest);

        }
        else
        {
            throw new BusinessValidationFailedException("未定义的存储介质类型");
        }
        return "/" + ossRelativePath;

    }


    public async Task DownLoadFromOSSAsync(string ossRelativePath, string localFilePath)
    {
        GetObjectStoreTempToken();

        ossRelativePath = ossRelativePath.TrimStart('/');
        try
        {


            if (ObjectStoreServiceOptions.ObjectStoreUse == "AliyunOSS")
            {
                var aliConfig = ObjectStoreServiceOptions.AliyunOSS;

                var _ossClient = new OssClient(RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? aliConfig.EndPoint : aliConfig.InternalEndpoint, AliyunOSSTempToken.AccessKeyId, AliyunOSSTempToken.AccessKeySecret, AliyunOSSTempToken.SecurityToken);

                // 上传文件
                var result = _ossClient.GetObject(aliConfig.BucketName, ossRelativePath);

                // 将下载的文件流保存到本地文件
                using (var fs = File.OpenWrite(localFilePath))
                {
                    result.Content.CopyTo(fs);
                    fs.Close();
                }

            }
            else if (ObjectStoreServiceOptions.ObjectStoreUse == "MinIO")
            {
                var minIOConfig = ObjectStoreServiceOptions.MinIO;

                var minioClient = new MinioClient().WithEndpoint($"{minIOConfig.EndPoint}:{minIOConfig.Port}")
                    .WithCredentials(minIOConfig.AccessKeyId, minIOConfig.SecretAccessKey).WithSSL(minIOConfig.UseSSL)
                    .Build();

                var getObjectArgs = new GetObjectArgs()
                .WithBucket(minIOConfig.BucketName)
                .WithObject(ossRelativePath)
                .WithFile(localFilePath);

                await minioClient.GetObjectAsync(getObjectArgs);

            }
            else if (ObjectStoreServiceOptions.ObjectStoreUse == "AWS")
            {
                var awsConfig = ObjectStoreServiceOptions.AWS;

                // 提供awsAccessKeyId和awsSecretAccessKey构造凭证
                var credentials = new SessionAWSCredentials(AWSTempToken.AccessKeyId, AWSTempToken.SecretAccessKey, AWSTempToken.SessionToken);

                //提供awsEndPoint(域名)进行访问配置
                var clientConfig = new AmazonS3Config
                {
                    RegionEndpoint = RegionEndpoint.USEast1,
                    UseHttp = true,
                };

                var amazonS3Client = new AmazonS3Client(credentials, clientConfig);

                var getObjectArgs = new Amazon.S3.Model.GetObjectRequest()
                {
                    BucketName = awsConfig.BucketName,
                    Key = ossRelativePath,
                };


                await (await amazonS3Client.GetObjectAsync(getObjectArgs)).WriteResponseStreamToFileAsync(localFilePath, true, CancellationToken.None);


            }
            else
            {
                throw new BusinessValidationFailedException("未定义的存储介质类型");
            }
        }
        catch (Exception ex)
        {

            throw new BusinessValidationFailedException("oss下载失败!" + ex.Message);
        }





    }

    public async Task<string> GetSignedUrl(string ossRelativePath)
    {
        GetObjectStoreTempToken();

        ossRelativePath = ossRelativePath.TrimStart('/');
        try
        {


            if (ObjectStoreServiceOptions.ObjectStoreUse == "AliyunOSS")
            {
                var aliConfig = ObjectStoreServiceOptions.AliyunOSS;

                var _ossClient = new OssClient(RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? aliConfig.EndPoint : aliConfig.InternalEndpoint, AliyunOSSTempToken.AccessKeyId, AliyunOSSTempToken.AccessKeySecret, AliyunOSSTempToken.SecurityToken);

                // 生成签名URL。
                var req = new GeneratePresignedUriRequest(aliConfig.BucketName, ossRelativePath, SignHttpMethod.Get)
                {
                    // 设置签名URL过期时间,默认值为3600秒。
                    Expiration = DateTime.Now.AddHours(1),
                };
                var uri = _ossClient.GeneratePresignedUri(req);

                return uri.PathAndQuery;

            }
            else if (ObjectStoreServiceOptions.ObjectStoreUse == "MinIO")
            {
                var minIOConfig = ObjectStoreServiceOptions.MinIO;

                var minioClient = new MinioClient().WithEndpoint($"{minIOConfig.EndPoint}:{minIOConfig.Port}")
                    .WithCredentials(minIOConfig.AccessKeyId, minIOConfig.SecretAccessKey).WithSSL(minIOConfig.UseSSL)
                    .Build();


                var args = new PresignedGetObjectArgs()
                    .WithBucket(minIOConfig.BucketName)
                    .WithObject(ossRelativePath)
                    .WithExpiry(3600)
                    /*.WithHeaders(reqParams)*/;

                var presignedUrl = await minioClient.PresignedGetObjectAsync(args);

                Uri uri = new Uri(presignedUrl);

                string relativePath = uri.PathAndQuery;


                return relativePath;

            }
            else if (ObjectStoreServiceOptions.ObjectStoreUse == "AWS")
            {
                var awsConfig = ObjectStoreServiceOptions.AWS;


                // 提供awsAccessKeyId和awsSecretAccessKey构造凭证
                var credentials = new SessionAWSCredentials(AWSTempToken.AccessKeyId, AWSTempToken.SecretAccessKey, AWSTempToken.SessionToken);

                //提供awsEndPoint(域名)进行访问配置
                var clientConfig = new AmazonS3Config
                {
                    RegionEndpoint = RegionEndpoint.USEast1,
                    UseHttp = true,
                };

                var amazonS3Client = new AmazonS3Client(credentials, clientConfig);

                var presignedUrl = await amazonS3Client.GetPreSignedURLAsync(new GetPreSignedUrlRequest()
                {
                    BucketName = awsConfig.BucketName,
                    Key = ossRelativePath,
                    Expires = DateTime.UtcNow.AddMinutes(120)
                });

                Uri uri = new Uri(presignedUrl);

                string relativePath = uri.PathAndQuery;


                return relativePath;
            }
            else
            {
                throw new BusinessValidationFailedException("未定义的存储介质类型");
            }
        }
        catch (Exception ex)
        {

            throw new BusinessValidationFailedException("oss授权url失败!" + ex.Message);
        }

    }


    /// <summary>
    /// 移动OSS文件到新路径
    /// </summary>
    /// <param name="sourcePath">原文件路径(格式:bucket/key)</param>
    /// <param name="destPath">新文件路径(格式:bucket/key)</param>
    /// <param name="overwrite">是否覆盖已存在的目标文件(默认true)</param>
    public async Task MoveObject(string sourcePath, string destPath, bool overwrite = true)
    {
        GetObjectStoreTempToken();

        switch (ObjectStoreServiceOptions.ObjectStoreUse)
        {
            case "AliyunOSS":
                #region 阿里云
                var aliConfig = ObjectStoreServiceOptions.AliyunOSS;
                var client = new OssClient(RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? aliConfig.EndPoint : aliConfig.InternalEndpoint, AliyunOSSTempToken.AccessKeyId, AliyunOSSTempToken.AccessKeySecret, AliyunOSSTempToken.SecurityToken);
                if (sourcePath.StartsWith("/"))
                {
                    sourcePath = sourcePath.Substring(1);
                }


                if (destPath.StartsWith("/"))
                {
                    destPath = destPath.Substring(1);
                }

                var sourceBucket = aliConfig.BucketName;
                var sourceKey = sourcePath;

                var destBucket = aliConfig.BucketName;

                var destKey = destPath;


                try
                {
                    // 检查目标是否存在(当不允许覆盖时)
                    if (!overwrite && client.DoesObjectExist(destBucket, destKey))
                    {
                        throw new InvalidOperationException("File Exist");
                    }


                    //var copyRequest = new Aliyun.OSS.CopyObjectRequest(sourceBucket, sourceKey, sourceBucket, destKey);
                    //var result = client.CopyObject(copyRequest);

                    //// 2. 删除原文件(可选,根据是否需要保留原文件)
                    //client.DeleteObject(sourceBucket, sourceKey);

                    // 执行复制
                    var copyRequestAli = new Aliyun.OSS.CopyObjectRequest(
                        sourceBucket, sourceKey,
                        destBucket, destKey);

                    // 保持原文件元数据
                    copyRequestAli.NewObjectMetadata = new ObjectMetadata
                    {
                        ContentType = client.GetObjectMetadata(sourceBucket, sourceKey).ContentType
                    };

                    var result = client.CopyObject(copyRequestAli);

                    // 删除原文件(仅在复制成功后)
                    client.DeleteObject(sourceBucket, sourceKey);
                }
                catch (OssException ex)
                {
                    throw new Exception($"[{ex.ErrorCode}] {ex.Message}", ex);
                }
                #endregion

                break;
            case "MinIO":
                #region MinIO
                var minIOConfig = ObjectStoreServiceOptions.MinIO;
                var minioClient = new MinioClient()
                 .WithEndpoint($"{minIOConfig.EndPoint}:{minIOConfig.Port}")
                 .WithCredentials(minIOConfig.AccessKeyId, minIOConfig.SecretAccessKey)
                 .WithSSL(minIOConfig.UseSSL)
                 .Build();

                // 定义源路径和目标路径
                string destinationKey = "b路径/文件名";

                try
                {
                    // 1. 复制文件到新路径[2,5](@ref)
                    using (var memoryStream = new MemoryStream())
                    {
                        // 下载源文件流
                        await minioClient.GetObjectAsync(new GetObjectArgs()
                            .WithBucket(minIOConfig.BucketName)
                            .WithObject(sourcePath)
                            .WithCallbackStream(stream => stream.CopyTo(memoryStream)));

                        memoryStream.Position = 0; // 重置流位置

                        // 上传到新路径
                        await minioClient.PutObjectAsync(new PutObjectArgs()
                            .WithBucket(minIOConfig.BucketName)
                            .WithObject(destinationKey)
                            .WithStreamData(memoryStream)
                            .WithObjectSize(memoryStream.Length));
                    }

                    // 2. 删除原文件[1,6](@ref)
                    await minioClient.RemoveObjectAsync(new RemoveObjectArgs()
                        .WithBucket(minIOConfig.BucketName)
                        .WithObject(sourcePath));
                }
                catch (MinioException ex)
                {
                    // 处理异常(例如:记录日志或抛出)
                    throw new Exception();
                }
                #endregion

                break;
            case "AWS":
                #region AWS
                var awsConfig = ObjectStoreServiceOptions.AWS;

                var credentials = new SessionAWSCredentials(
                    AWSTempToken.AccessKeyId,
                    AWSTempToken.SecretAccessKey,
                    AWSTempToken.SessionToken
                );

                var clientConfig = new AmazonS3Config
                {
                    RegionEndpoint = RegionEndpoint.USEast1,
                    UseHttp = true,
                };

                var amazonS3Client = new AmazonS3Client(credentials, clientConfig);

                // 定义原路径和目标路径


                // 1. 复制对象到新路径
                var copyRequest = new Amazon.S3.Model.CopyObjectRequest
                {
                    SourceBucket = awsConfig.BucketName,
                    SourceKey = sourcePath,
                    DestinationBucket = awsConfig.BucketName,
                    DestinationKey = destPath
                };

                try
                {
                    // 执行复制操作
                    await amazonS3Client.CopyObjectAsync(copyRequest);

                    // 2. 删除原对象
                    var deleteRequest = new Amazon.S3.Model.DeleteObjectRequest
                    {
                        BucketName = awsConfig.BucketName,
                        Key = sourcePath
                    };
                    await amazonS3Client.DeleteObjectAsync(deleteRequest);


                }
                catch (AmazonS3Exception ex)
                {
                    Console.WriteLine($"ERROR: {ex.Message}");
                    // 可根据异常类型细化处理(如文件不存在、权限问题等)
                }
                #endregion
                break;
            default:
                throw new BusinessValidationFailedException("ERROR");

        }

    }

    /// <summary>
    /// 获取所有根目录名称
    /// </summary>
    /// <returns></returns>
    public List<string> GetRootFolderNames()
    {
        GetObjectStoreTempToken();
        var aliConfig = ObjectStoreServiceOptions.AliyunOSS;
        var _ossClient = new OssClient(RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? aliConfig.EndPoint : aliConfig.InternalEndpoint,
                                        AliyunOSSTempToken.AccessKeyId,
                                        AliyunOSSTempToken.AccessKeySecret,
                                        AliyunOSSTempToken.SecurityToken);

        List<string> rootFolders = new List<string>();
        string nextMarker = null;

        try
        {
            ObjectListing objectListing = null;
            do
            {
                // 列出根目录下的对象和文件夹
                objectListing = _ossClient.ListObjects(new Aliyun.OSS.ListObjectsRequest(aliConfig.BucketName)
                {

                    MaxKeys = 1000,
                    Marker = nextMarker,
                    Delimiter = "/"  // 使用分隔符来模拟文件夹
                });

                // 遍历 CommonPrefixes 获取根文件夹名称
                foreach (var prefix in objectListing.CommonPrefixes)
                {
                    rootFolders.Add(prefix.TrimEnd('/')); // 去掉末尾的斜杠
                }

                // 设置 NextMarker 以获取下一页的数据
                nextMarker = objectListing.NextMarker;

            } while (objectListing.IsTruncated);
        }
        catch (Exception ex)
        {
            Console.WriteLine($"Error: {ex.Message}");
        }

        return rootFolders;
    }

    /// <summary>
    /// 删除某个目录的文件
    /// </summary>
    /// <param name="prefix"></param>
    /// <returns></returns>
    public async Task DeleteFromPrefix(string prefix, bool isCache = false)
    {
        GetObjectStoreTempToken();

        if (ObjectStoreServiceOptions.ObjectStoreUse == "AliyunOSS")
        {
            var aliConfig = ObjectStoreServiceOptions.AliyunOSS;

            var _ossClient = new OssClient(RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? aliConfig.EndPoint : aliConfig.InternalEndpoint, AliyunOSSTempToken.AccessKeyId, AliyunOSSTempToken.AccessKeySecret, AliyunOSSTempToken.SecurityToken);

            var bucketName = string.Empty;

            if (isCache)
            {
                Uri uri = new Uri(aliConfig.ViewEndpoint);
                string host = uri.Host; // 获取 "zy-irc-test-dev-cache.oss-cn-shanghai.aliyuncs.com"
                string[] parts = host.Split('.');
                bucketName = parts[0];
            }
            else
            {
                bucketName = aliConfig.BucketName;
            }



            try
            {
                ObjectListing objectListing = null;
                string nextMarker = null;
                do
                {
                    // 使用 prefix 模拟目录结构,设置 MaxKeys 和 NextMarker
                    objectListing = _ossClient.ListObjects(new Aliyun.OSS.ListObjectsRequest(bucketName)
                    {
                        Prefix = prefix,
                        MaxKeys = 1000,
                        Marker = nextMarker
                    });

                    List<string> keys = objectListing.ObjectSummaries.Select(t => t.Key).ToList();

                    // 删除获取到的文件
                    if (keys.Count > 0)
                    {
                        _ossClient.DeleteObjects(new Aliyun.OSS.DeleteObjectsRequest(bucketName, keys, false));
                    }

                    // 设置 NextMarker 以获取下一页的数据
                    nextMarker = objectListing.NextMarker;

                } while (objectListing.IsTruncated);
            }
            catch (Exception ex)
            {
                Console.WriteLine($"Error: {ex.Message}");
            }


        }
        else if (ObjectStoreServiceOptions.ObjectStoreUse == "MinIO")
        {
            var minIOConfig = ObjectStoreServiceOptions.MinIO;


            var minioClient = new MinioClient().WithEndpoint($"{minIOConfig.EndPoint}:{minIOConfig.Port}")
                .WithCredentials(minIOConfig.AccessKeyId, minIOConfig.SecretAccessKey).WithSSL(minIOConfig.UseSSL)
                .Build();


            var listArgs = new ListObjectsArgs().WithBucket(minIOConfig.BucketName).WithPrefix(prefix).WithRecursive(true);



            // 创建一个空列表用于存储对象键
            var objects = new List<string>();

            // 使用 await foreach 来异步迭代对象列表
            await foreach (var item in minioClient.ListObjectsEnumAsync(listArgs))
            {
                objects.Add(item.Key);
            }


            if (objects.Count > 0)
            {
                var objArgs = new RemoveObjectsArgs()
              .WithBucket(minIOConfig.BucketName)
              .WithObjects(objects);

                // 删除对象
                await minioClient.RemoveObjectsAsync(objArgs);
            }



        }
        else if (ObjectStoreServiceOptions.ObjectStoreUse == "AWS")
        {

            var awsConfig = ObjectStoreServiceOptions.AWS;

            // 提供awsAccessKeyId和awsSecretAccessKey构造凭证
            var credentials = new SessionAWSCredentials(AWSTempToken.AccessKeyId, AWSTempToken.SecretAccessKey, AWSTempToken.SessionToken);

            //提供awsEndPoint(域名)进行访问配置
            var clientConfig = new AmazonS3Config
            {
                RegionEndpoint = RegionEndpoint.USEast1,
                UseHttp = true,
            };

            var amazonS3Client = new AmazonS3Client(credentials, clientConfig);

            // 列出指定前缀下的所有对象
            var listObjectsRequest = new ListObjectsV2Request
            {
                BucketName = awsConfig.BucketName,
                Prefix = prefix
            };

            var listObjectsResponse = await amazonS3Client.ListObjectsV2Async(listObjectsRequest);

            if (listObjectsResponse.S3Objects.Count > 0)
            {
                // 准备删除请求
                var deleteObjectsRequest = new Amazon.S3.Model.DeleteObjectsRequest
                {
                    BucketName = awsConfig.BucketName,
                    Objects = new List<KeyVersion>()
                };

                foreach (var s3Object in listObjectsResponse.S3Objects)
                {
                    deleteObjectsRequest.Objects.Add(new KeyVersion
                    {
                        Key = s3Object.Key
                    });
                }

                // 批量删除对象
                var deleteObjectsResponse = await amazonS3Client.DeleteObjectsAsync(deleteObjectsRequest);
            }



        }
        else
        {
            throw new BusinessValidationFailedException("未定义的存储介质类型");
        }
    }

    public async Task DeleteObjects(List<string> objectKeys)
    {
        GetObjectStoreTempToken();

        if (ObjectStoreServiceOptions.ObjectStoreUse == "AliyunOSS")
        {
            var aliConfig = ObjectStoreServiceOptions.AliyunOSS;

            var _ossClient = new OssClient(RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? aliConfig.EndPoint : aliConfig.InternalEndpoint, AliyunOSSTempToken.AccessKeyId, AliyunOSSTempToken.AccessKeySecret, AliyunOSSTempToken.SecurityToken);

            if (objectKeys.Count > 0)
            {
                var result = _ossClient.DeleteObjects(new Aliyun.OSS.DeleteObjectsRequest(aliConfig.BucketName, objectKeys, false));

            }
        }
        else if (ObjectStoreServiceOptions.ObjectStoreUse == "MinIO")
        {
            var minIOConfig = ObjectStoreServiceOptions.MinIO;


            var minioClient = new MinioClient().WithEndpoint($"{minIOConfig.EndPoint}:{minIOConfig.Port}")
                .WithCredentials(minIOConfig.AccessKeyId, minIOConfig.SecretAccessKey).WithSSL(minIOConfig.UseSSL)
            .Build();


            if (objectKeys.Count > 0)
            {
                var objArgs = new RemoveObjectsArgs()
              .WithBucket(minIOConfig.BucketName)
              .WithObjects(objectKeys);

                // 删除对象
                await minioClient.RemoveObjectsAsync(objArgs);
            }
        }
        else if (ObjectStoreServiceOptions.ObjectStoreUse == "AWS")
        {

            var awsConfig = ObjectStoreServiceOptions.AWS;


            // 提供awsAccessKeyId和awsSecretAccessKey构造凭证
            var credentials = new SessionAWSCredentials(AWSTempToken.AccessKeyId, AWSTempToken.SecretAccessKey, AWSTempToken.SessionToken);

            //提供awsEndPoint(域名)进行访问配置
            var clientConfig = new AmazonS3Config
            {
                RegionEndpoint = RegionEndpoint.USEast1,
                UseHttp = true,
            };

            var amazonS3Client = new AmazonS3Client(credentials, clientConfig);

            if (objectKeys.Count > 0)
            {
                // 准备删除请求
                var deleteObjectsRequest = new Amazon.S3.Model.DeleteObjectsRequest
                {
                    BucketName = awsConfig.BucketName,
                    Objects = objectKeys.Select(t => new KeyVersion() { Key = t }).ToList()
                };


                // 批量删除对象
                var deleteObjectsResponse = await amazonS3Client.DeleteObjectsAsync(deleteObjectsRequest);
            }

        }
        else
        {
            throw new BusinessValidationFailedException("未定义的存储介质类型");
        }
    }

    private bool isFirstCall = true;
    public async Task<long> GetObjectSizeAsync(string sourcePath)
    {
        if (isFirstCall)
        {
            GetObjectStoreTempToken();
            isFirstCall = false;
        }


        var objectkey = sourcePath.Trim('/');

        if (ObjectStoreServiceOptions.ObjectStoreUse == "AliyunOSS")
        {
            var aliConfig = ObjectStoreServiceOptions.AliyunOSS;

            var _ossClient = new OssClient(RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? aliConfig.EndPoint : aliConfig.InternalEndpoint, AliyunOSSTempToken.AccessKeyId, AliyunOSSTempToken.AccessKeySecret, AliyunOSSTempToken.SecurityToken);

            var metadata = _ossClient.GetObjectMetadata(aliConfig.BucketName, objectkey);

            long fileSize = metadata.ContentLength; // 文件大小(字节)

            return fileSize;
        }
        else if (ObjectStoreServiceOptions.ObjectStoreUse == "MinIO")
        {
            var minIOConfig = ObjectStoreServiceOptions.MinIO;


            var minioClient = new MinioClient().WithEndpoint($"{minIOConfig.EndPoint}:{minIOConfig.Port}")
                .WithCredentials(minIOConfig.AccessKeyId, minIOConfig.SecretAccessKey).WithSSL(minIOConfig.UseSSL)
            .Build();


            var stat = await minioClient.StatObjectAsync(new Minio.DataModel.Args.StatObjectArgs()
                 .WithBucket(minIOConfig.BucketName)
                 .WithObject(objectkey));

            return stat.Size; // 文件大小(字节)
        }
        else if (ObjectStoreServiceOptions.ObjectStoreUse == "AWS")
        {

            var awsConfig = ObjectStoreServiceOptions.AWS;


            // 提供awsAccessKeyId和awsSecretAccessKey构造凭证
            var credentials = new SessionAWSCredentials(AWSTempToken.AccessKeyId, AWSTempToken.SecretAccessKey, AWSTempToken.SessionToken);

            //提供awsEndPoint(域名)进行访问配置
            var clientConfig = new AmazonS3Config
            {
                RegionEndpoint = RegionEndpoint.USEast1,
                UseHttp = true,
            };

            var request = new Amazon.S3.Model.GetObjectMetadataRequest
            {
                BucketName = awsConfig.BucketName,
                Key = objectkey
            };

            var amazonS3Client = new AmazonS3Client(credentials, clientConfig);

            var response = await amazonS3Client.GetObjectMetadataAsync(request);

            long fileSize = response.ContentLength; // 文件大小(字节)

            return fileSize;

        }
        else
        {
            throw new BusinessValidationFailedException("未定义的存储介质类型");
        }
    }



    public ObjectStoreDTO GetObjectStoreTempToken()
    {

        var ossOptions = ObjectStoreServiceOptions.AliyunOSS;

        if (ObjectStoreServiceOptions.ObjectStoreUse == "AliyunOSS")
        {
            var client = new Client(new AlibabaCloud.OpenApiClient.Models.Config()
            {
                AccessKeyId = ossOptions.AccessKeyId,
                AccessKeySecret = ossOptions.AccessKeySecret,
                //AccessKeyId = "LTAI5tJV76pYX5yPg1N9QVE8",
                //AccessKeySecret = "roRNLa9YG1of4pYruJGCNKBXEWTAWa",

                Endpoint = "sts.cn-hangzhou.aliyuncs.com"
            });

            var assumeRoleRequest = new AlibabaCloud.SDK.Sts20150401.Models.AssumeRoleRequest();
            // 将<YOUR_ROLE_SESSION_NAME>设置为自定义的会话名称,例如oss-role-session。
            assumeRoleRequest.RoleSessionName = $"session-name-{NewId.NextGuid()}";
            // 将<YOUR_ROLE_ARN>替换为拥有上传文件到指定OSS Bucket权限的RAM角色的ARN。
            assumeRoleRequest.RoleArn = ossOptions.RoleArn;
            //assumeRoleRequest.RoleArn = "acs:ram::1899121822495495:role/webdirect";
            assumeRoleRequest.DurationSeconds = ossOptions.DurationSeconds;
            var runtime = new AlibabaCloud.TeaUtil.Models.RuntimeOptions();
            var response = client.AssumeRoleWithOptions(assumeRoleRequest, runtime);
            var credentials = response.Body.Credentials;

            var tempToken = new AliyunOSSTempToken()
            {
                AccessKeyId = credentials.AccessKeyId,
                AccessKeySecret = credentials.AccessKeySecret,

                //转为服务器时区,最后统一转为客户端时区
                Expiration = TimeZoneInfo.ConvertTimeFromUtc(DateTime.Parse(credentials.Expiration), TimeZoneInfo.Local),
                SecurityToken = credentials.SecurityToken,


                Region = ossOptions.Region,
                BucketName = ossOptions.BucketName,
                EndPoint = ossOptions.EndPoint,
                ViewEndpoint = ossOptions.ViewEndpoint,
                PreviewEndpoint = ossOptions.PreviewEndpoint

            };

            AliyunOSSTempToken = tempToken;

            return new ObjectStoreDTO() { ObjectStoreUse = ObjectStoreServiceOptions.ObjectStoreUse, AliyunOSS = tempToken };
        }
        else if (ObjectStoreServiceOptions.ObjectStoreUse == "MinIO")
        {
            return new ObjectStoreDTO() { ObjectStoreUse = ObjectStoreServiceOptions.ObjectStoreUse, MinIO = ObjectStoreServiceOptions.MinIO };
        }
        else if (ObjectStoreServiceOptions.ObjectStoreUse == "AWS")
        {
            var awsOptions = ObjectStoreServiceOptions.AWS;

            //aws 临时凭证
            // 创建 STS 客户端
            var stsClient = new AmazonSecurityTokenServiceClient(awsOptions.AccessKeyId, awsOptions.SecretAccessKey);

            // 使用 AssumeRole 请求临时凭证
            var assumeRoleRequest = new AssumeRoleRequest
            {

                RoleArn = awsOptions.RoleArn, // 角色 ARN
                RoleSessionName = $"session-name-{NewId.NextGuid()}",
                DurationSeconds = awsOptions.DurationSeconds          // 临时凭证有效期
            };

            var assumeRoleResponse = stsClient.AssumeRoleAsync(assumeRoleRequest).Result;

            var credentials = assumeRoleResponse.Credentials;

            var tempToken = new AWSTempToken()
            {
                AccessKeyId = credentials.AccessKeyId,
                SecretAccessKey = credentials.SecretAccessKey,
                SessionToken = credentials.SessionToken,
                Expiration = credentials.Expiration,
                Region = awsOptions.Region,
                BucketName = awsOptions.BucketName,
                EndPoint = awsOptions.EndPoint,
                ViewEndpoint = awsOptions.ViewEndpoint,

            };

            AWSTempToken = tempToken;
            return new ObjectStoreDTO() { ObjectStoreUse = ObjectStoreServiceOptions.ObjectStoreUse, AWS = tempToken };
        }
        else
        {
            throw new BusinessValidationFailedException("未定义的存储介质类型");
        }
    }

}