using OT.COM.LogisticsUtil;
using OT.COM.SignalerMessage;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Mail;
using System.Text;
using System.Text.RegularExpressions;

namespace CounsellorBL
{
    public class MailService : MessageBase
    {
        Util u = new Util();
        public CResponseMessage SendMail(CRequestMessage i_crm)
        {
            CResponseMessage crm = null;
            string sMsg = null;

            try
            {
                do
                {
                    string sSubject = _fetchString(i_crm, BLWording.SUBJECT);
                    string sBody = _fetchString(i_crm, BLWording.BODY);
                    string sSender = _fetchString(i_crm, BLWording.SENDERNAME);
                    string sReceiver = _fetchString(i_crm, BLWording.RECEIVERS);
                    string sUseSSL = u.GetSettingString("USESSL"); 

                    Mailer m = new Mailer();
                    m.SMTP = u.GetSettingString("SMTPURL"); // "smtp.gmail.com";
                    m.FromAddress = u.GetSettingString("MAILOWNERADDRESS"); //"ot.syssender@gmail.com";
                    m.Account = u.GetSettingString("MAILACCOUNT"); //"ot.syssender@gmail.com";
                    m.Password = u.GetSettingString("MAILPASS"); // "XXXXXX";
                    m.Name = sSender;
                    m.Port = Convert.ToInt32(u.GetSettingString("MAILPORT")); // "587"
                    m.SSL = sUseSSL != null ? sUseSSL.ToLower().StartsWith("y") : false;
                    m.MyEncoding = Encoding.GetEncoding("UTF-8");

                    string [] saMailAddress = sReceiver.Split(",;".ToCharArray());
                    List<Mailer.MailAccountInfo> l = new List<Mailer.MailAccountInfo>();

                    foreach (string sMailAddress in saMailAddress)
                    {
                        l.Add(new Mailer.MailAccountInfo() { EMail = sMailAddress });
                    }

                    sMsg = m.Send(sSubject, sBody, l);

                    if (null != sMsg)
                    {
                        break;
                    }

                    crm = new CSuccessResponseMessage(null, i_crm) { MSG = "SEND SUCCESS" };
                }
                while (false);                

            }
            catch (Exception e)
            {
                sMsg = u.GetLastExceptionMsg(e);
            }

            if (null != sMsg)
            {
                crm = new CResponseMessage(i_crm) { RESULT = EResponseResult.RR_FALSE, MSG = sMsg };
            }

            return crm;
        }

        /// <summary>
        /// 同步發送電子郵件
        /// </summary>
        /// <param name="o_myMessage">電子郵件</param>
        /// <returns></returns>
        public bool SendMailNET(System.Net.Mail.MailMessage o_myMessage)
        {
            try
            {
                //mo_Log.Debug("發送郵件開始");
                //重構在 GetEmailConfig()
                System.Net.Mail.SmtpClient o_myMailServer = GetEmailConfig(); //new SmtpClient(sServer);//寄件服務器地址,端口

                System.Net.Mail.MailAddress o_MailFrom = new System.Net.Mail.MailAddress("service@origtek-mail.com", o_myMessage.From.DisplayName);
                //Add by Alina  需要把發件者的信息添加到抄送人中
                Regex reg = new Regex(@"(\w*)(\()*");
                string strFromName = o_myMessage.From.DisplayName;//人員名稱
                Match m = reg.Match(strFromName);
                strFromName = m.Groups[1].Value;
                string strFromMail = o_myMessage.From.Address;//人員Mail
                System.Net.Mail.MailAddress o_MailTo = new System.Net.Mail.MailAddress(strFromMail, strFromName);
                o_myMessage.CC.Add(o_myMessage.From);//把發件者的信息添加到抄送人中
                o_myMessage.From = o_MailTo;//發件者的信息
                //發送Mail
                //mo_Log.Debug("FormName:" + o_myMessage.From.DisplayName);
                //mo_Log.Debug("FormMail:" + o_myMessage.From.Address);
                o_myMailServer.Send(o_myMessage);
                return true;
            }
            catch (System.Net.Mail.SmtpException ex)
            {
                //ErrorMessages = ex.Message;
                //mo_Log.Error(ex);
                return false;
            }

        }

        #region SendMailNET_NoSelf

        /// <summary>
        /// 同步發送電子郵件
        /// </summary>
        /// <param name="o_myMessage">電子郵件</param>
        /// <returns></returns>
        public bool SendMailNET_NoSelf(System.Net.Mail.MailMessage o_myMessage)
        {
            try
            {
                //mo_Log.Debug("發送郵件開始");
                System.Net.Mail.SmtpClient o_myMailServer = GetEmailConfig(); //new SmtpClient(sServer);//寄件服務器地址,端口

                System.Net.Mail.MailAddress o_MailFrom = new System.Net.Mail.MailAddress("service@origtek-mail.com", o_myMessage.From.DisplayName);
                //發送Mail
                //mo_Log.Debug("FormName:" + o_myMessage.From.DisplayName + ";FormMail:" + o_myMessage.From.Address);
                o_myMailServer.Send(o_myMessage);
                return true;
            }
            catch (System.Net.Mail.SmtpException ex)
            {
                //ErrorMessages = ex.Message;
                //mo_Log.Error(ex);
                return false;
            }

        }

        #endregion

        #region "GetEmailConfig"
        /// <summary>
        /// 提供本類中其它公有郵件功能,取得基本smtp設定.
        /// </summary>
        /// <returns></returns>
        private SmtpClient GetEmailConfig()
        {
            string sMailEncoding = u.GetSettingString("MailEncoding"); //設置字集防止亂碼
            string sFromName = u.GetSettingString("FromName").Trim();         //顯示發件人的名字代替Mail地址
            string sFromEmail = u.GetSettingString("FromEmail").Trim();       //發件人地址
            string sFromUserid = u.GetSettingString("FromUserId").Trim(); //發件人的帳號
            string sFromPassword = u.GetSettingString("FromPassword").Trim(); //發件人的密碼

            string sServer = u.GetSettingString("Server").Trim();             //發送郵件服務器的IP地址
            int i32ServerPort = 0;
            int.TryParse(u.GetSettingString("ServerPort"), out i32ServerPort);       //發送郵件服務器的端口
            int iTimeout = 0;
            int.TryParse(u.GetSettingString("Timeout"), out iTimeout);               //發送郵件超時時間
            bool blSSLYES = u.GetSettingString("SSL").Trim().Equals("true") ? true : false;//是否開啟SSL驗證

            System.Net.Mail.SmtpClient o_myMailServer = new SmtpClient(sServer);//寄件服務器地址,端口
            o_myMailServer.Host = sServer;
            if (i32ServerPort != 0)
            {
                o_myMailServer.Port = i32ServerPort;
            }
            o_myMailServer.EnableSsl = blSSLYES;//是否開啟SSL驗證
            if (iTimeout != 0)
            {
                o_myMailServer.Timeout = iTimeout * 1000;  //若郵件過大,請手動加長時間, 1000約等於1秒
            }
            if (!sFromPassword.Equals(""))
            {
                o_myMailServer.UseDefaultCredentials = false;
                o_myMailServer.Credentials = new System.Net.NetworkCredential(sFromUserid, sFromPassword);//登錄會員名和密碼
            }
            return o_myMailServer;
        }
        #endregion

        private class Mailer
        {
            public class MailAccountInfo
            {
                public string EMail { get; set; }

                public string Name { get; set; }
            }

            public string SMTP { get; set; }
            public string FromAddress { get; set; }
            public string Account { get; set; }
            public string Password { get; set; }
            public string Name { get; set; }
            public int Port { get; set; }
            public string ErrorMessage { get; set; }
            public bool SSL { get; set; }
            public Encoding MyEncoding { get; set; }

            /// <summary>
            /// 建構子
            /// </summary>
            public Mailer()
            {
                MyEncoding = Encoding.GetEncoding("UTF-8");
            }

            /// <summary>
            /// 寄信動作
            /// </summary>
            /// <param name="strSubject">主旨</param>
            /// <param name="strBody">信件內容</param>
            /// <param name="arrayStrToAddressAndName">收件者</param>
            /// <param name="bHTML"></param>
            /// <param name="arrayStrAttached">附件</param>
            /// <param name="arrayStrCCAddressAndName">CC</param>
            /// <param name="arrayStrBCCAddressAndName">BCC</param>                
            /// <returns></returns>
            public string Send(string strSubject, string strBody, List<MailAccountInfo> arrayStrToAddressAndName,
                bool bHTML = true,
                List<MailAccountInfo> arrayStrCCAddressAndName = null,
                List<MailAccountInfo> arrayStrBCCAddressAndName = null)
            {
                
                string sMsg = null;

                try
                {
                    System.Net.Mail.MailMessage mm = new System.Net.Mail.MailMessage();
                    if (string.IsNullOrWhiteSpace(this.FromAddress) == false)
                    {
                        mm.Sender = new System.Net.Mail.MailAddress(string.Format("{1}<{0}>", this.FromAddress, this.Name));
                        mm.From = new System.Net.Mail.MailAddress(string.Format("{1}<{0}>", this.FromAddress, this.Name));
                    }
                    mm.Subject = strSubject;
                    mm.IsBodyHtml = bHTML;
                    mm.Body = strBody;
                    mm.BodyEncoding = this.MyEncoding;

                    //加入收件者
                    if (arrayStrToAddressAndName != null)
                    {
                        for (int i = 0; i < arrayStrToAddressAndName.Count; i++)
                        {
                            MailAccountInfo mai = arrayStrToAddressAndName[i];
                            if (null != mai.EMail)
                            {
                                mm.To.Add(mai.EMail);
                            }
                        }
                    }


                    //加入CC
                    //string strCC = "";
                    if (arrayStrCCAddressAndName != null)
                    {
                        for (int i = 0; i < arrayStrCCAddressAndName.Count; i++)
                        {
                            //strCC += (i == 0 ? "" : ",") + string.Format("{1}<{0}>", arrayStrCCAddressAndName[i, 0], arrayStrCCAddressAndName[i, 1]);
                            MailAccountInfo mai = arrayStrCCAddressAndName[i];
                            if (null != mai.EMail)
                            {
                                mm.CC.Add(mai.EMail);
                            }
                        }
                    }
                    //if (strCC != "")
                    //    mm.CC.Add(strCC);

                    //string strBCC = "";
                    //加入BCC
                    if (arrayStrBCCAddressAndName != null)
                    {
                        for (int i = 0; i < arrayStrBCCAddressAndName.Count; i++)
                        {
                            //strBCC += (i == 0 ? "" : ",") + string.Format("{1}<{0}>", arrayStrBCCAddressAndName[i, 0], arrayStrBCCAddressAndName[i, 1]);
                            MailAccountInfo mai = arrayStrBCCAddressAndName[i];
                            if (null != mai.EMail)
                            {
                                mm.Bcc.Add(mai.EMail);
                            }
                        }
                    }
                    //if (strBCC != "")
                    //    mm.Bcc.Add(strBCC);

                   
                    System.Net.Mail.SmtpClient smtp = new System.Net.Mail.SmtpClient(this.SMTP, this.Port);
                    if (!string.IsNullOrWhiteSpace(this.Account) && !string.IsNullOrWhiteSpace(this.Password))
                    {
                        smtp.Credentials = new NetworkCredential(this.Account, this.Password);
                    }
                    smtp.EnableSsl = this.SSL;

                    mm.Body = strBody;

                    smtp.Send(mm);
                    mm.Dispose();
                }
                catch (Exception ex)
                {
                    sMsg = new Util().GetLastExceptionMsg(ex);
                }

                return sMsg;
            }
        }
    
    }
}