using Atomx.Utils.Json;
using Atomx.Utils.Models;
using Microsoft.AspNetCore.Http;
using System.Net;

namespace Atomx.Utils.Extension
{
    public class UploadExtension
    {
        /// <summary>
        /// 上传
        /// </summary>
        /// <param name="file">文件</param>
        /// <param name="rootPath">站点根目录</param>
        /// <param name="path">存储目录</param>
        /// <param name="fixedPath">是否固定存储在根目录，如果不固定，将自动根据时间生成子文件夹进行存储</param>
        /// <param name="fileName">文件名</param>
        /// <param name="currentPath">覆盖上传的路径</param>
        /// <param name="extension">文件类型</param>
        /// <returns></returns>
        public Result<string> LocalUpload(IFormFile file, string rootPath, string path, bool fixedPath, string fileName, string currentPath, string extension)
        {
            var result = new Result<string>();
            var filepath = string.Empty;
            if (!string.IsNullOrEmpty(currentPath))
            {
                filepath = currentPath;
            }
            else
            {
                filepath = PathExtension.GetFileNameByData(path, fixedPath, fileName, extension);
            }

            var savepath = Path.Combine(rootPath, filepath.Replace("/", "\\"));
            var newpath = Path.GetDirectoryName(savepath);

            if (string.IsNullOrEmpty(newpath))
            {
                result.Message = "Storage path exception";
                result.Success = false;
                return result;
            }

            try
            {
                if (!Directory.Exists(newpath))
                {
                    Directory.CreateDirectory(newpath);
                }
            }
            catch
            {

                result.Message = "Folder failure is established";
                result.Success = false;
                return result;

            }
            try
            {
                using (FileStream fs = File.Create(savepath))
                {
                    file.CopyTo(fs);
                    fs.Flush();
                }
            }
            catch (Exception ex)
            {
                result.Message = ex.Message;
                result.Success = false;
            }
            result.Data = filepath;
            return result;
        }

        /// <summary>
        /// 上传
        /// </summary>
        /// <param name="file">文件</param>
        /// <param name="rootPath">站点根目录</param>
        /// <param name="path">存储目录</param>
        /// <param name="fixedPath">是否固定存储在根目录，如果不固定，将自动根据时间生成子文件夹进行存储</param>
        /// <param name="fileName">文件名</param>
        /// <param name="currentPath">覆盖上传的路径</param>
        /// <param name="extension">文件类型</param>
        /// <returns></returns>
        public async Task<Result<string>> LocalUploadEncryptAsync(IFormFile file, string rootPath, string path, bool fixedPath, string fileName, string currentPath, string extension)
        {
            var result = new Result<string>();
            var filepath = string.Empty;
            if (!string.IsNullOrEmpty(currentPath))
            {
                filepath = currentPath;
            }
            else
            {
                filepath = PathExtension.GetFileNameByData(path, fixedPath, fileName, extension);
            }

            var savepath = Path.Combine(rootPath, filepath.Replace("/", "\\"));
            var newpath = Path.GetDirectoryName(savepath);
            if(string.IsNullOrEmpty(newpath))
            {
                result.Message = "Storage path exception";
                result.Success = false;
                return result;
            }
            try
            {
                if (!Directory.Exists(newpath))
                {
                    Directory.CreateDirectory(newpath);
                }
            }
            catch
            {
                result.Message = "Folder failure is established";
                result.Success = false;
                return result;

            }
            try
            {
                var stream = file.OpenReadStream();
                byte[] bytes = new byte[stream.Length];
                await stream.ReadAsync(bytes, 0, bytes.Length);
                for (int i = 0; i < bytes.Length; i++)
                {
                    ++bytes[i];
                }

                var fsw = new FileStream(savepath, FileMode.Create, FileAccess.Write);
                fsw.Write(bytes, 0, bytes.Length);
                fsw.Close();
            }
            catch (Exception ex)
            {
                result.Message = ex.Message;
                result.Success = false;
            }
            result.Data = filepath;
            return result;
        }

        /// <summary>
        /// 远程上传文件
        /// </summary>
        /// <param name="file"></param>
        /// <param name="url"></param>
        /// <param name="rootpath"></param>
        /// <param name="fixedpath"></param>
        /// <param name="filename"></param>
        /// <param name="currentpath"></param>
        /// <returns></returns>
        public async Task<UploadResult> RemoteUploadAsync(IFormFile file, string url, string rootpath, bool fixedpath, string filename, string currentpath)
        {
            var result = new UploadResult();
            var dic = new Dictionary<string, string>();
            dic.Add("rootpath", rootpath);
            dic.Add("fixedpath", fixedpath.ToString().ToLower());
            dic.Add("filename", filename);
            dic.Add("currentpath", currentpath);
            using (var client = new HttpClient())
            {
                using (var content = new MultipartFormDataContent())
                {

                    content.Add(new StreamContent(file.OpenReadStream()), "file", file.FileName);
                    foreach (var item in dic)
                    {
                        content.Add(new StringContent(item.Value), item.Key);
                    }
                    var response = await client.PostAsync(url, content);
                    if (response.StatusCode == HttpStatusCode.OK)
                    {
                        var uploadresult = await response.Content.ReadAsStringAsync();
                        result = uploadresult.FromJson<UploadResult>();
                    }
                    else
                    {
                        //result.Code = UploadCodes.Failure;
                        //result.Message = "remote server is error";
                    }
                }
            }
            return result;
        }
    }
}
