using MailKit.Net.Smtp;
using MimeKit;
using System;
using System.Threading.Tasks;
using MimeKit.Text;
using System.IO;

namespace Sockeye.Util
{
    public interface IMailer
    {
        Task SendEmailAsync(string email, string subject, string body, Sockeye.Models.GlobalOpsNotificationSettings smtpSettings, string attachPDF = null, string forceFileName = null, string htmlBody = null);
    }

    public class Mailer : IMailer
    {
        public Mailer()
        {

        }

        public async Task SendEmailAsync(string email, string subject, string body, Sockeye.Models.GlobalOpsNotificationSettings smtpSettings, string attachPDFPath = null, string forceFileName = null, string htmlBody = null)
        {
#if (DEBUG)
            switch (email)
            {
                case "support@ayanova.com":
                case "johncrdnl@gmail.com":
                case "gzmailadmin@gmail.com":
                case "sales@ayanova.com":
                case "support@onayanova.com":
                case "techworks@shaw.ca":
                    break;
                default:
                    System.Diagnostics.Debug.WriteLine($"DANGER: about to email someone {email} outside our test network");
                    //DANGER: about to email someone outside our test network
                    System.Diagnostics.Debugger.Break();
                    break;
            }
#endif
            try
            {
                var message = new MimeMessage();
                message.From.Add(new MailboxAddress(smtpSettings.NotifyFromAddress, smtpSettings.NotifyFromAddress));
                message.To.Add(MailboxAddress.Parse(email));               
                message.Subject = subject;

                if (!string.IsNullOrWhiteSpace(attachPDFPath))
                {
                    var attachment = new MimePart("application/pdf", "pdf")
                    {
                        Content = new MimeContent(File.OpenRead(attachPDFPath), ContentEncoding.Default),
                        ContentDisposition = new ContentDisposition(ContentDisposition.Attachment),
                        ContentTransferEncoding = ContentEncoding.Base64,
                        FileName = Path.GetFileName(attachPDFPath)

                    };
                    if (!string.IsNullOrWhiteSpace(forceFileName))
                        attachment.FileName = forceFileName;

                    var multipart = new Multipart("mixed");
                    if (!string.IsNullOrWhiteSpace(body))
                        multipart.Add(new TextPart(TextFormat.Plain) { Text = body });
                    multipart.Add(attachment);
                    message.Body = multipart;
                }
                else
                {
                    // if (!string.IsNullOrWhiteSpace(body))
                    //     message.Body = new TextPart(TextFormat.Plain) { Text = body };

                    MimeKit.BodyBuilder builder = new BodyBuilder();

                    if (!string.IsNullOrWhiteSpace(body))
                        builder.TextBody = body;

                    if (!string.IsNullOrWhiteSpace(htmlBody))
                        builder.HtmlBody = htmlBody;

                    message.Body = builder.ToMessageBody();
                }

                using (var client = new SmtpClient())
                {
                    client.ServerCertificateValidationCallback = (s, c, h, e) => true;

                    bool UseSSL = smtpSettings.ConnectionSecurity != Biz.NotifyMailSecurity.None;
                    await client.ConnectAsync(smtpSettings.SmtpServerAddress, smtpSettings.SmtpServerPort, UseSSL);


                    await client.AuthenticateAsync(smtpSettings.SmtpAccount, smtpSettings.SmtpPassword);
                    await client.SendAsync(message);
                    await client.DisconnectAsync(true);
                    DisposeStreamsInMimeMessage(message);
                }


            }
            catch (Exception e)
            {
                throw new InvalidOperationException(e.Message);
            }
        }

        public static void DisposeStreamsInMimeMessage(MimeMessage msg) { foreach (var part in msg.BodyParts) (part as MimePart)?.Content?.Stream?.Dispose(); }

    }
}