using Mall.Education.Models;
using RabbitMQ.Client;
using RabbitMQ.Client.Events;
using System;
using System.Text;
using Newtonsoft.Json;
using System.IO;
using Mall.Education.Offices;
using COSSnippet;
using Mall.Education.Helper;
using System.Collections.Generic;
using System.Linq;
using Quartz;
using Quartz.Impl;
using System.Collections.Specialized;
using System.Threading.Tasks;

namespace Mall.Education.RabbitMQ
{
    /// <summary>
    /// RabbitMq消息队列
    /// </summary>
    public static class RabbiMQManager
    {
        /// <summary>
        /// 获取连接
        /// </summary>
        /// <param name="rabbitConfig">连接配置实体</param>
        /// <returns></returns>
        private static ConnectionFactory GetConnectionFactory(RabbitConfig rabbitConfig)
        {
            ConnectionFactory factory = new ConnectionFactory
            {
                HostName = rabbitConfig.HostName,
                //默认端口
                Port = rabbitConfig.Port,
                UserName = rabbitConfig.UserName,
                Password = rabbitConfig.Password
            };
            return factory;
        }

        /// <summary>
        /// 处理消息队列
        /// </summary>
        /// <param name="rabbitConfig"></param>
        [Obsolete]
        public static void DealWithMessage(RabbitConfig rabbitConfig)
        {
            using (IConnection conn = GetConnectionFactory(rabbitConfig).CreateConnection())
            {
                using (IModel channel = conn.CreateModel())
                {
                    //在MQ上定义一个持久化队列，如果名称相同不会重复创建
                    channel.QueueDeclare(rabbitConfig.QueenName, true, false, false, null);
                    //输入1，那如果接收一个消息，但是没有应答，则客户端不会收到下一个消息
                    channel.BasicQos(0, 1, false);
                    //在队列上定义一个消费者
                    QueueingBasicConsumer consumer = new QueueingBasicConsumer(channel);
                    //消费队列，并设置应答模式为程序主动应答
                    channel.BasicConsume(rabbitConfig.QueenName, false, consumer);

                    while (true)
                    {
                        //阻塞函数，获取队列中的消息
                        BasicDeliverEventArgs ea = (BasicDeliverEventArgs)consumer.Queue.Dequeue();
                        byte[] bytes = ea.Body;
                        string msg = Encoding.UTF8.GetString(bytes);
                        try
                        {
                            Console.WriteLine("进来一个：" + msg);
                            var GoodsModel = JsonConvert.DeserializeObject<GoodsModel>(msg);
                            //处理
                            if (GoodsModel != null)
                            {
                                ImageConvertData(GoodsModel);
                            }
                            Console.WriteLine("处理一个：" + msg);
                        }
                        catch (Exception ex)
                        {
                            Console.WriteLine(ex.Message);
                            LogHelper.Write(ex, "出问题咯");
                        }
                        //回复确认
                        channel.BasicAck(ea.DeliveryTag, false);
                    }
                }
            }
        }

        /// <summary>
        /// 处理文件
        /// </summary>
        /// <param name="GoodsModel"></param>
        private static void ImageConvertData(GoodsModel GoodsModel)
        {
            if (string.IsNullOrEmpty(GoodsModel.FilePath)) {
                return;
            }
            string tempDir = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "tempfile/Image");
            if (!Directory.Exists(tempDir))
                Directory.CreateDirectory(tempDir);
            //是否需要先把文件下载到服务器
            //GoodsModel.FilePath = "https://viitto-1301420277.cos.ap-chengdu.myqcloud.com/Test/Upload/Education/wkxq.docx";
            //文件生成图片暂存本地
            string FileExtension = Path.GetExtension(GoodsModel.FilePath);
            string FileName = Path.GetFileNameWithoutExtension(GoodsModel.FilePath);
            string FileDirectory = Path.GetDirectoryName(GoodsModel.FilePath).Replace("\\", "/").Replace("http:/", "http://").Replace("https:/", "https://");
            string[] patharr = GoodsModel.FilePath.Split('/');
            string FileDirNot = "";
            for (var i = 3; i < patharr.Length - 1; i++)
            {
                FileDirNot += patharr[i] + "/";
            }
            int PageNum;
            System.Drawing.Imaging.ImageFormat imageFormat = System.Drawing.Imaging.ImageFormat.Jpeg;
            if (FileExtension == ".doc" || FileExtension == ".docx")
            {
                new Word2ImageConverter().ConvertToImage(GoodsModel.FilePath, tempDir + "/", imageFormat, out PageNum);
            }
            else if (FileExtension == ".pdf")
            {
                new Pdf2ImageConverter().ConvertToImage(GoodsModel.FilePath, tempDir + "/", imageFormat, out PageNum);
            }
            else if (FileExtension == ".ppt" || FileExtension == ".pptx")
            {
                new Ppt2ImageConverter().ConvertToImage(GoodsModel.FilePath, tempDir + "/", imageFormat, out PageNum);
            }
            else {
                return;
            }

            if (PageNum > 0)
            {
                //List<string> DelFile = new List<string>();
                List<GoodsImage> goodsImages = new List<GoodsImage>();
                //开始上传图片至服务器
                if (GoodsModel.PathType == 1)
                {
                    TransferUploadObjectModel m = new TransferUploadObjectModel(GoodsModel.MallBaseId);
                    for (var i = 1; i <= PageNum; i++)
                    {
                        string newName = FileName + "_" + i.ToString("000") + "." + imageFormat.ToString();
                        if (!m.SelectFile(FileDirNot + newName))
                        {
                            m.TransferUploadFile(tempDir + "/" + newName, FileDirNot + newName);
                        }

                        //上传之后 写入商品课程图片数据
                        goodsImages.Add(new GoodsImage
                        {
                            Sort = i,
                            Path = FileDirectory + "/" + newName
                        });

                        //上传之后 删除本地临时文件
                        //File.Delete(tempDir + "/" + newName);
                        //DelFile.Add(tempDir + "/" + newName);
                    }
                }
                else if (GoodsModel.PathType == 2) {
                    AliOSSUploadObject upload = new AliOSSUploadObject(GoodsModel.MallBaseId);
                    for (var i = 1; i <= PageNum; i++)
                    {
                        string newName = FileName + "_" + i.ToString("000") + "." + imageFormat.ToString();
                        if (!upload.SelectFile(FileDirNot + newName))
                        {
                            upload.TransferUploadFile(tempDir + "/" + newName, FileDirNot + newName);
                        }

                        //上传之后 写入商品课程图片数据
                        goodsImages.Add(new GoodsImage
                        {
                            Sort = i,
                            Path = FileDirectory + "/" + newName
                        });

                        //上传之后 删除本地临时文件
                        //File.Delete(tempDir + "/" + newName);
                        //DelFile.Add(tempDir + "/" + newName);
                    }
                }

                //更新图片数据
                bool flag = FileDataHelper.InsertGoodsFileImage(GoodsModel.CourseId, JsonConvert.SerializeObject(goodsImages)) > 0;
                if (flag == false) {
                    LogHelper.Write("更新课程图片列表失败：CourseId:" + GoodsModel.CourseId);
                }

                //if (DelFile.Any()) {
                //    System.Threading.Tasks.Task.Run(() => {
                //        System.Threading.Thread.Sleep(100000);
                //        foreach (var item in DelFile) {
                //            File.Delete(item);
                //        }
                //    });
                //}
            }
        }
    }

    /// <summary>
    /// 定时器
    /// </summary>
    public class QuarzHelper
    {
        /// <summary>
        /// 营收报表
        /// </summary>
        /// <returns></returns>
        public async Task StartDelTemporaryFile()
        {
            NameValueCollection props = new NameValueCollection
                {
                    { "quartz.serializer.type", "binary" }
                };
            StdSchedulerFactory factory = new StdSchedulerFactory(props);
            IScheduler scheduler = await factory.GetScheduler();
            await scheduler.Start();
            IJobDetail job = JobBuilder.Create<DelTemporaryFile>()
                .WithIdentity("job4", "group4")
                .Build();
            ITrigger trigger = TriggerBuilder.Create()
                .WithIdentity("trigger4", "group4")
                .StartNow()
                .WithSimpleSchedule(x => x
                    .WithIntervalInHours(2)
                    .RepeatForever())
                .Build();
            await scheduler.ScheduleJob(job, trigger);
        }

    }

    /// <summary>
    /// 删除临时文件
    /// </summary>
    public class DelTemporaryFile : IJob
    {

        /// <summary>
        /// 这里是作业调度每次定时执行方法
        /// </summary>
        /// <param name="context"></param>
        public Task Execute(IJobExecutionContext context)
        {
            try
            {
                string tempDir = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "tempfile/Image");
                DirectoryInfo dir = new DirectoryInfo(tempDir);
                DirectoryInfo[] dirArr = dir.GetDirectories();
                foreach (DirectoryInfo item in dirArr)
                {
                    if (item.CreationTime < DateTime.Now.AddDays(-1))
                        item.Delete(true);
                }
                foreach (FileInfo fi in dir.GetFiles())
                {
                    if (fi.CreationTime < DateTime.Now.AddHours(-1))
                        fi.Delete();
                }
                LogHelper.Write("DelTemporaryFile清理一次");
            }
            catch (Exception ex)
            {
                LogHelper.Write(ex, "DelTemporaryFile");
            }
            return null;
        }

    }
}
