using Aliyun.OSS;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using Mall.ThirdCore.Commom;
using System;
using System.Collections.Generic;
using System.IO;
using Mall.Common.Plugin;

namespace Mall.ThirdCore.Oss
{
    /// <summary>
    /// 阿里云存储服务
    /// 文件路径名前不能以/开头
    /// </summary>
    public class AliOssService : IOssService
    {
        private string endpoint = "";
        private string accessKeyId = "";
        private string accessKeySecret = "";
        private string bucketName = "";

        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="endpoint"></param>
        /// <param name="accessKeyId"></param>
        /// <param name="accessKeySecret"></param>
        /// <param name="bucketName"></param>
        public AliOssService(string endpoint, string accessKeyId, string accessKeySecret, string bucketName)
        {
            if (!endpoint.Contains(".aliyuncs.com")) {
                endpoint += ".aliyuncs.com";
            }
            this.endpoint = endpoint;
            this.accessKeyId = accessKeyId;
            this.accessKeySecret = accessKeySecret;
            this.bucketName = bucketName;
        }

        /// <summary>
        /// 创建实例
        /// </summary>
        /// <returns></returns>
        public static AliOssService Instance(string endpoint, string accessKeyId, string accessKeySecret, string bucketName)
        {
            JObject aliOss = Config.AliOss;
            endpoint ??= aliOss["endpoint"].ToString();
            accessKeyId ??= aliOss["accessKeyId"].ToString();
            accessKeySecret ??= aliOss["accessKeySecret"].ToString();
            bucketName ??= aliOss["bucketName"].ToString();
            return new AliOssService(endpoint, accessKeyId, accessKeySecret, bucketName);
        }

        /// <summary>
        /// 上传文件
        /// </summary>
        /// <param name="filePath">文件路径</param>
        /// <param name="stream">文件流</param>
        /// <returns></returns>
        public OssResult UploadFile(string filePath, System.IO.Stream stream)
        {
            OssClient client = new OssClient(this.endpoint, this.accessKeyId, this.accessKeySecret);
            OssResult result;
            try
            {
                string fileExtention = System.IO.Path.GetExtension(filePath);
                string key = @"SaleBefore/Goods/" + DateTime.Now.Ticks.ToString() + fileExtention; //对象在存储桶中的位置，即称对象键                
                
                client.PutObject(bucketName, key, filePath);
                result = new OssResult
                {
                    resultCode = 1,
                    message = "上传成功",
                    data = "/" + key
                };
            }
            catch (System.Exception ex)
            {
                Mall.Common.Plugin.LogHelper.Write(ex, "AliOssService_UploadFile");
                result = new OssResult
                {
                    resultCode = 2,
                    message = ex.Message
                };
            }
            return result;
        }

        /// <summary>
        /// 删除文件
        /// </summary>
        /// <param name="fileName"></param>
        /// <returns></returns>
        public OssResult DeleteFile(string fileName)
        {
            OssClient client = new OssClient(this.endpoint, this.accessKeyId, this.accessKeySecret);
            OssResult result;
            try
            {
                fileName = fileName.Substring(0, 1) == "/" ? fileName.TrimStart('/') : fileName;
                client.DeleteObject(bucketName, fileName);
                result = new OssResult()
                {
                    resultCode = 1
                };
            }
            catch (Exception ex)
            {
                result = new OssResult()
                {
                    resultCode = 2,
                    message = ex.Message
                };
            }
            return result;
        }
        
        /// <summary>
        /// 批量删除文件
        /// </summary>
        /// <param name="fileNameList"></param>
        /// <returns></returns>

        public OssResult DeleteFile(List<string> fileNameList)
        {
            OssClient client = new OssClient(this.endpoint, this.accessKeyId, this.accessKeySecret);
            OssResult result;
            try
            {
                List<string> tempNames = new List<string>();
                foreach (var item in fileNameList)
                {
                    string name = item.Substring(0, 1) == "/" ? item.TrimStart('/') : item;
                    tempNames.Add(name);
                }
                var request = new DeleteObjectsRequest(bucketName, tempNames, false);
                client.DeleteObjects(request);
                result = new OssResult()
                {
                    resultCode = 1
                };
            }
            catch (Exception ex)
            {
                result = new OssResult()
                {
                    resultCode = 2,
                    message = ex.Message
                };
            }
            return result;
        }


        /// <summary>
        /// 拷贝文件
        /// </summary>
        /// <param name="sourceFileName">源文件</param>
        /// <param name="targetFileName">目标文件</param>
        /// <returns></returns>
        public OssResult FileCopy(string sourceFileName, string targetFileName)
        {
            OssClient client = new OssClient(this.endpoint, this.accessKeyId, this.accessKeySecret);
            OssResult result;
            try
            {
                sourceFileName = sourceFileName.Substring(0, 1) == "/" ? sourceFileName.TrimStart('/') : sourceFileName;
                targetFileName = targetFileName.Substring(0, 1) == "/" ? targetFileName.TrimStart('/') : targetFileName;
                var metadata = new ObjectMetadata();
                var req = new CopyObjectRequest(bucketName, sourceFileName, bucketName, targetFileName)
                {
                    NewObjectMetadata = metadata
                };
                var ret = client.CopyObject(req);
                if (ret.HttpStatusCode.ToString().Equals("OK"))
                {
                    result = new OssResult { resultCode = 1, message = "移动成功" };
                }
                else
                {
                    result = new OssResult { resultCode = 2, message = $"移动失败,状态码是：{ret.HttpStatusCode}" };
                }
                return result;
            }
            catch (Exception ex)
            {
                result = new OssResult { resultCode = 2, message = $"移动成功,原因是：{ex.Message}" };
                return result;
            }
        }

 
        /// <summary>
        /// 判断文件是否存在
        /// </summary>
        /// <param name="fileName"></param>
        /// <returns></returns>
        public bool FileIsExist(string fileName)
        {
            OssClient client = new OssClient(this.endpoint, this.accessKeyId, this.accessKeySecret);
            try
            {
                fileName = fileName.Substring(0, 1) == "/" ? fileName.TrimStart('/') : fileName;
                return client.DoesObjectExist(bucketName, fileName);
            }
            catch
            {
                return false;
            }
        }
    }
}
