using System;
using System.Drawing;
using System.DrawingCore.Imaging;
using System.Globalization;
using System.IO;
using GxPress.Common.Exceptions;
using QRCoder;
using Bitmap = System.DrawingCore.Bitmap;
using Imazen.WebP;
namespace GxPress.Common.Tools
{
    /// <summary>
    ///     文件帮助类
    /// </summary>

    public class FileHelper
    {
        /// <summary>
        ///     得到图片的 Size 值
        /// </summary>
        /// <param name="bytes">图片的二进制数据</param>
        /// <returns>图片的 Size 值</returns>
        public static Size GetSize(byte[] bytes)
        {
            var size = Size.Empty;
            if (bytes != null && bytes.Length > 0)
            {
                using var ms = new MemoryStream(bytes);
                size = GetSize(ms);
            }

            return size;
        }

        /// <summary>
        ///     得到图片的 Size 值
        /// </summary>
        /// <param name="stream">图片的文件数据流</param>
        /// <returns>图片的 Size 值</returns>
        public static Size GetSize(Stream stream)
        {
            Size size;
            using (var originalImage = Image.FromStream(stream))
            {
                size = originalImage.Size;
            }

            return size;
        }

        /// <summary>
        ///     保存文件
        /// </summary>
        /// <param name="path">文件保存路径</param>
        /// <param name="bytes">文件二进制数据</param>
        /// <returns>保存文件是否成功！</returns>
        public static void Save(string path, byte[] bytes)
        {
            if (string.IsNullOrWhiteSpace(path))
                throw new ArgumentException("文件保存路径不能为空");
            if (bytes == null || bytes.Length == 0)
                throw new ArgumentException("文件二进制数据不能为空");
            var info = new FileInfo(path);
            if (info.Directory != null && !info.Directory.Exists) info.Directory.Create();
            info.Delete();
            File.WriteAllBytes(info.FullName, bytes);
        }

        /// <summary>
        ///     保存文件
        /// </summary>
        /// <param name="path">文件保存路径</param>
        /// <param name="fileName">文件名</param>
        /// <param name="bytes">文件二进制数据</param>
        /// <returns>保存后文件的路径，为空时，表示上传不成功！</returns>
        public static ResultPath SaveFile(string path, string fileName, byte[] bytes)
        {
            if (string.IsNullOrWhiteSpace(path))
                throw new BusinessException("文件保存路径不能为空");
            if (bytes == null || bytes.Length == 0)
                throw new BusinessException("上传文件不能为空");

            fileName = $"{FileNewName()}{Path.GetExtension(fileName)}";
            var saveDirectory = DateTime.Now.ToString("yyyyMMdd");
            var resultPath = new ResultPath
            {
                AbsolutePath = Path.Combine(path, "cache", saveDirectory, fileName),
                RelativePath = $"/cache/{saveDirectory}/{fileName}",
            };
            Save(resultPath.AbsolutePath, bytes);
            //压缩图片
            CompressImage.Execute(resultPath.AbsolutePath, 50);
            CompressImage.Execute(resultPath.AbsolutePath, 100);
            return resultPath;
        }

        /// <summary>
        /// 获取保存的路径
        /// </summary>
        /// <param name="path"></param>
        /// <param name="fileName"></param>
        /// <returns></returns>
        public static ResultPath GetSavePath(string path, string fileName)
        {
            var saveDirectory = DateTime.Now.ToString("yyyyMMdd");
            fileName = $"{FileNewName()}{Path.GetExtension(fileName)}";
            var resultPath = new ResultPath
            {
                AbsolutePath = Path.Combine(path, "cache", saveDirectory, fileName),
                RelativePath = $"/cache/{saveDirectory}/{fileName}",
            };

            return resultPath;
        }
        /// <summary>
        /// 获取图片保存地址
        /// </summary>
        /// <param name="path"></param>
        /// <param name="content"></param>
        /// <returns></returns>
        public static ResultPath SaveQRCodeFile(string path, string content)
        {
            //创建二维码
            QRCodeGenerator qrGenerator = new QRCodeGenerator();
            QRCodeData qrCodeData = qrGenerator.CreateQrCode(content, QRCodeGenerator.ECCLevel.Q);
            var qrCode = new QRCode(qrCodeData);
            Bitmap qrCodeImage = qrCode.GetGraphic(20);
            if (string.IsNullOrWhiteSpace(path))
                throw new BusinessException("文件保存路径不能为空");
            var fileName = $"{FileNewName()}.jpeg";
            var saveDirectory = DateTime.Now.ToString("yyyyMMdd");
            var resultPath = new ResultPath
            {
                AbsolutePath = Path.Combine(path, "cache", saveDirectory, fileName),
                RelativePath = $"/cache/{saveDirectory}/{fileName}",
            };
            var info = new FileInfo(resultPath.AbsolutePath);
            if (info.Directory != null && !info.Directory.Exists) info.Directory.Create();
            info.Delete();
            //保存位置
            qrCodeImage.Save(resultPath.AbsolutePath, ImageFormat.Jpeg);
            return resultPath;
        }

        /// <summary>
        ///     删除指定的文件
        /// </summary>
        /// <param name="path">文件路径</param>
        /// <returns>删除是否成功</returns>
        public static bool Delete(string path)
        {
            if (string.IsNullOrWhiteSpace(path))
                throw new ArgumentException("文件路径不能为空");

            if (File.Exists(path)) File.Delete(path);
            return true;
        }
        /// <summary>
        /// webp
        /// </summary>
        /// <param name="path"></param>
        /// <param name="fileName"></param>
        /// <param name="webpUrl"></param>
        /// <returns></returns>

        public static ResultPath WebPToImage(string path, string fileName, ResultPath resultPath, string absolutePathUrl)
        {

            // using (Bitmap image = WebPFormat.LoadFromStream(new FileStream("image.webp", FileMode.Open, FileAccess.Read)))
            // {
            //     image.Save("image.png", ImageFormat.Png);
            // }
            var dim = System.IO.File.ReadAllBytes("wwwroot/" + resultPath.RelativePath);
            //Imazen.WebP.Extern.LoadLibrary.LoadWebPOrFail();
            var simpleDecoder = new SimpleDecoder();
            var bitmap = simpleDecoder.DecodeFromBytes(dim, dim.Length);
            var saveDirectory = DateTime.Now.ToString("yyyyMMdd");
            fileName = fileName.Split('.')[0] + ".jpg";
            resultPath.AbsolutePath = Path.Combine(path, "cache", saveDirectory, fileName);
            resultPath.RelativePath = $"/cache/{saveDirectory}/{fileName}";
            using (MemoryStream stream = new MemoryStream())
            {
                bitmap.Save(resultPath.AbsolutePath, System.Drawing.Imaging.ImageFormat.Jpeg); // 坑点：格式选Bmp时，不带透明度
                stream.Close();
            }
            resultPath.AbsolutePath = absolutePathUrl + resultPath.RelativePath;
            resultPath.FileName = fileName;
            resultPath.MinAbsolutePath = StringUtils.AddDomainMin(resultPath.AbsolutePath);
            //压缩图片
            CompressImage.Execute(resultPath.AbsolutePath, 50);
            CompressImage.Execute(resultPath.AbsolutePath, 100);
            return resultPath;
        }
        /// <summary>
        ///     判断文件是否存在
        /// </summary>
        /// <param name="path">文件路径</param>
        /// <returns>是否存在</returns>
        public static bool Exists(string path)
        {
            if (string.IsNullOrWhiteSpace(path))
                throw new ArgumentException("文件路径不能为空");

            return File.Exists(path);
        }

        /// <summary>
        ///     读取文件
        /// </summary>
        /// <param name="path">文件路径</param>
        /// <returns>文件的二进制数据</returns>
        public static byte[] Read(string path)
        {
            if (string.IsNullOrWhiteSpace(path))
                throw new ArgumentException("文件路径不能为空");

            byte[] result = null;
            if (File.Exists(path))
                result = File.ReadAllBytes(path);

            return result;
        }

        /// <summary>
        ///     得到文件新名称
        /// </summary>
        /// <returns></returns>
        public static string FileNewName()
        {
            return Guid.NewGuid().ToString("N", CultureInfo.InvariantCulture);
        }
    }

    /// <summary>
    ///     文件结果
    /// </summary>
    public class ResultPath
    {
        /// <summary>相对路径</summary>
        public string RelativePath { get; set; }

        /// <summary>绝对路径</summary>
        public string AbsolutePath { get; set; }
        /// <summary>
        /// 文件名称
        /// </summary>
        public string FileName { get; set; }
        /// <summary>
        /// 文件类型
        /// </summary>
        public string FileType { get; set; }
        public int FileId { get; set; }

        public long Size { get; set; }
        /// <summary>
        /// 缩略图
        /// </summary>
        /// <value></value>
        public string MinAbsolutePath { get; set; }
    }
}