using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Microsoft.Exchange.WebServices.Data;
using Microsoft.Identity.Client;
using System.IO;

namespace ZionRobot.WebService
{
    class ZionOutlookManager
    {
        public string UserName;
        public string AppClientId;
        public string ApiKey;
        public string AppTenentId;

        public string ScopeUrl;
        public string ExchangeServiceUrl;

        public ZionOutlookManager(string userName, string appClientId, string apiKey, string appTenentId, string scopeUrl = null, string exchangeServiceUrl = null)
        {
            UserName = userName;
            AppClientId = appClientId;
            ApiKey = apiKey;
            AppTenentId = appTenentId;
            ScopeUrl = scopeUrl ?? "https://outlook.office365.com/.default";
            ExchangeServiceUrl = exchangeServiceUrl ?? "https://outlook.office365.com/EWS/Exchange.asmx";
        }

        public void blah()
        {
            ExchangeService service = makeConnectionApiKey().Result;

            SearchFilter searchFilter = new SearchFilter.IsEqualTo(EmailMessageSchema.IsRead, false);
            ItemView view = new ItemView(100);
            view.OrderBy.Add(ItemSchema.DateTimeReceived, SortDirection.Descending);
            FindItemsResults<Item> findResults = service.FindItems(WellKnownFolderName.Inbox, searchFilter, view);

            foreach (EmailMessage email in findResults)
            {
                email.Load(new PropertySet(ItemSchema.Id));
            }
        }

        public void SendEmail(string to, string subject, string body, string saveEmlDir = "")
        {
            var sendTask = Send(to, "Teste", "testetetetetetetete");
            sendTask.Wait();

            var result = sendTask.Result;

            if (!String.IsNullOrEmpty(saveEmlDir))
            {
                ExchangeService service = makeConnectionApiKey().Result;

                if (service != null)
                {
                    Directory.CreateDirectory(saveEmlDir);
                    string bar = saveEmlDir.Contains(@"/") ? @"/" : @"\";
                    saveEmlDir = saveEmlDir.EndsWith(bar) ? saveEmlDir : saveEmlDir + bar;

                    ItemView itemView = new ItemView(20);
                    itemView.PropertySet = new PropertySet(BasePropertySet.IdOnly);

                    FindItemsResults<Item> findResults = service.FindItems(WellKnownFolderName.SentItems, itemView);

                    foreach (var item in findResults)
                    {
                        string i = item.Id.UniqueId;
                        if (i == result)
                        {
                            PropertySet prop = new PropertySet(EmailMessageSchema.MimeContent);
                            //EmailMessage mail = EmailMessage.Bind(service, item.Id, prop);
                            item.Load(prop);

                        }


                    }

                    string emailId = result;
                    //string emailId = "AAMkADMwNGE3NzVlLWQxOTEtNGViOS1hZTIxLTY3Mjk0ZDY1ZTU2NABGAAAAAABgBUchHCfsTqs+IYH8OdhHBwBehQvOTkF+S4z2QRks1vPqAAAAAAEMAABehQvOTkF+S4z2QRks1vPqAABPiiVjAAA=";
                    EmailMessage email = EmailMessage.Bind(service, emailId);
                    email.Load(new PropertySet(ItemSchema.MimeContent));
                    MimeContent mimeContent = email.MimeContent;

                    using (FileStream fileStream = new FileStream(saveEmlDir + $"{subject}.eml", FileMode.Create))
                    {
                        fileStream.Write(mimeContent.Content, 0, mimeContent.Content.Length);
                    }
                }
            }

            /*ExchangeService service = makeConnectionApiKey().Result;

            if (service != null)
            {
                try
                {
                    EmailMessage message = new EmailMessage(service);

                    message.Subject = subject;
                    message.Body = body;
                    message.ToRecipients.Add(to);

                    message.Save();
                    message.SendAndSaveCopy();

                    if (!String.IsNullOrEmpty(saveEmlDir))
                    {
                        Directory.CreateDirectory(saveEmlDir);
                        string bar = saveEmlDir.Contains(@"/") ? @"/" : @"\";
                        saveEmlDir = saveEmlDir.EndsWith(bar) ? saveEmlDir : saveEmlDir + bar;

                        string emailId = message.Id.UniqueId;
                        //string emailId = "AAMkADMwNGE3NzVlLWQxOTEtNGViOS1hZTIxLTY3Mjk0ZDY1ZTU2NABGAAAAAABgBUchHCfsTqs+IYH8OdhHBwBehQvOTkF+S4z2QRks1vPqAAAAAAEMAABehQvOTkF+S4z2QRks1vPqAABPiiVjAAA=";
                        EmailMessage email = EmailMessage.Bind(service, emailId);
                        email.Load(new PropertySet(ItemSchema.MimeContent));
                        MimeContent mimeContent = email.MimeContent;

                        using (FileStream fileStream = new FileStream(saveEmlDir + $"{subject}.eml", FileMode.Create))
                        {
                            fileStream.Write(mimeContent.Content, 0, mimeContent.Content.Length);
                        }
                    }

                    

                    return message;
                }
                catch (Exception e)
                {
                    return null;
                }
            }
            return null;*/
        }

        private async System.Threading.Tasks.Task<ExchangeService> makeConnectionApiKey()
        {
            var cca = ConfidentialClientApplicationBuilder
                .Create(AppClientId)
                .WithClientSecret(ApiKey)
                .WithTenantId(AppTenentId)
                .Build();

            var ewsScopes = new string[] { ScopeUrl };
            ExchangeService service = null;
            try
            {
                var authResult = await cca.AcquireTokenForClient(ewsScopes)
                    .ExecuteAsync();

                // Configure the ExchangeService with the access token
                service = new ExchangeService();
                service.Url = new Uri(ExchangeServiceUrl);
                service.Credentials = new OAuthCredentials(authResult.AccessToken);
                service.ImpersonatedUserId =
                    new ImpersonatedUserId(ConnectingIdType.SmtpAddress, UserName);

                //Include x-anchormailbox header
                service.HttpHeaders.Add("X-AnchorMailbox", UserName);
            }
            catch (Exception e)
            {
            }
            return service;
        }

        private async System.Threading.Tasks.Task<string> Send(string to, string subject, string body)
        {
            ExchangeService service = makeConnectionApiKey().Result;

            if (service != null)
            {
                try
                {
                    EmailMessage message = new EmailMessage(service);

                    message.Subject = subject;
                    message.Body = body;
                    message.ToRecipients.Add(to);

                    message.Save();
                    message.SendAndSaveCopy();
                    return message.Id.UniqueId;
                }
                catch (Exception e)
                {
                    return "";
                }
            }
            return "";
        }
    }
}
