using MailKit;
using MailKit.Net.Imap;
using MailKit.Net.Smtp;
using MailKit.Search;
using MimeKit;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace MadRunFabric.Common
{

    /// <summary>
    /// send email
    /// </summary>
    public class MailUtil
    {
        private async static Task<bool> SendMail(MimeMessage mailMessage, MailConfig config)
        {
            try
            {
                var smtpClient = new SmtpClient();
                smtpClient.Timeout = 10 * 1000;   //设置超时时间
                smtpClient.Connect(config.SMPTHost, config.Port, MailKit.Security.SecureSocketOptions.None);//连接到远程smtp服务器
                smtpClient.Authenticate(config.Address, config.Password);
                await smtpClient.SendAsync(mailMessage);//发送邮件
                smtpClient.Disconnect(true);
                return true;

            }
            catch
            {
                throw;
            }

        }

        /// <summary>
        ///发送邮件
        /// </summary>
        /// <param name="config">配置</param>
        /// <param name="receives">接收人</param>
        /// <param name="sender">发送人</param>
        /// <param name="subject">标题</param>
        /// <param name="body">内容</param>
        /// <param name="attachments">附件</param>
        /// <param name="fileName">附件名</param>
        /// <returns></returns>
        public async static Task<bool> SendMail(MailConfig config, List<string> receives, string subject, string body, List<Stream> attachmentsList = null, List<string> fileNameList = null)
        {
            var fromMailAddress = new MailboxAddress(config.Name, config.Address);

            var mailMessage = new MimeMessage();
            mailMessage.From.Add(fromMailAddress);

            foreach (var add in receives)
            {
                var toMailAddress = new MailboxAddress(add);
                mailMessage.To.Add(toMailAddress);
            }
            var bodyBuilder = new BodyBuilder() { HtmlBody = body };

            //附件
            if (attachmentsList != null && attachmentsList.Count > 0)
            {

                for (int i = 0; i < attachmentsList.Count; i++)
                {
                    var fileName = fileNameList != null && fileNameList.Count > 0 ? fileNameList[i] : "";
                    if (string.IsNullOrEmpty(fileName))
                    {
                        fileName = "未命名文件.txt";
                    }
                    var attachment = new MimePart(new ContentType("image", "png"))
                    {
                        Content = new MimeContent(attachmentsList[i]),
                        ContentDisposition = new ContentDisposition(ContentDisposition.Attachment),
                        ContentTransferEncoding = ContentEncoding.Base64,
                    };
                    attachment.ContentType.Parameters.Add("GB18030", "name", fileName);
                    attachment.ContentDisposition.Parameters.Add("GB18030", "filename", fileName);

                    bodyBuilder.Attachments.Add(attachment);

                }
            }

            mailMessage.Body = bodyBuilder.ToMessageBody();
            mailMessage.Subject = subject;

            return await SendMail(mailMessage, config);

        }

        /// <summary>
        /// 接收邮件
        /// </summary>
        /// <param name="config"></param>
        /// <param name="webRootPath"></param>
        /// <returns></returns>
        public async static Task<List<MailOutput>> GetMail(MailConfig config, string webRootPath)
        {
            List<MailOutput> list = new List<MailOutput>();
            using (var client = new ImapClient())
            {
                client.ServerCertificateValidationCallback = (s, c, h, e) => true;

                await client.ConnectAsync(config.IMAPHost, config.IMAPPort, true);

                await client.AuthenticateAsync(config.IMAPAddress, config.IMAPPassword);

                var inbox = client.Inbox;
                await inbox.OpenAsync(FolderAccess.ReadOnly);

                var unids = await inbox.SearchAsync(SearchQuery.NotSeen);



                foreach (var summary in await inbox.FetchAsync(unids, MessageSummaryItems.UniqueId | MessageSummaryItems.Envelope | MessageSummaryItems.BodyStructure))
                {
                    var directory = Path.Combine(webRootPath, summary.UniqueId.ToString());

                    if (!Directory.Exists(directory))
                    {
                        Directory.CreateDirectory(directory);
                    }

                    //邮件列表
                    list.Add(new MailOutput
                    {
                        Id = summary.UniqueId.ToString(),
                        Date = summary.Date.DateTime,
                        Subject = summary.Envelope.Subject
                    });

                    //if (summary.TextBody != null)
                    //{
                    //    // this will download *just* the text/plain part
                    //    var text = await inbox.GetBodyPartAsync(summary.UniqueId, summary.TextBody);
                    //    var part = (MimePart)text;
                    //    var fileName = "TextBody.txt";
                    //    var path = Path.Combine(directory, fileName);
                    //    using (var stream = System.IO.File.Create(path))
                    //    {
                    //        await part.Content.DecodeToAsync(stream);
                    //    }
                    //}

                    if (summary.HtmlBody != null)
                    {
                        // this will download *just* the text/html part
                        var html = await inbox.GetBodyPartAsync(summary.UniqueId, summary.HtmlBody);
                        var part = (MimePart)html;
                        var fileName = "HtmlBody.txt";
                        var path = Path.Combine(directory, fileName);
                        using (var stream = System.IO.File.Create(path))
                        {
                            await part.Content.DecodeToAsync(stream);
                        }
                    }


                    if (summary.Body is BodyPartMultipart)
                    {
                        foreach (var attachment in summary.Attachments)
                        {
                            // this will download *just* the attachment
                            var entity = await inbox.GetBodyPartAsync(summary.UniqueId, attachment);

                            if (entity is MessagePart)
                            {
                                var rfc822 = (MessagePart)entity;
                                var path = Path.Combine(directory, attachment.PartSpecifier + ".eml");
                                rfc822.Message.WriteTo(path);
                            }
                            else
                            {
                                var part = (MimePart)entity;
                                var fileName = part.FileName;
                                var path = Path.Combine(directory, fileName);
                                using (var stream = System.IO.File.Create(path))
                                {
                                    await part.Content.DecodeToAsync(stream);
                                }
                            }
                        }
                    }
                }

                await client.DisconnectAsync(true);
            }

            return list;

        }
    }
}