using System;
using System.Data;
using System.Configuration;
using System.IO;
using System.Text;
using System.Text.RegularExpressions;
using System.Web;
using TABS.MailCarrier.WebSDK;
using TABS.MailCarrier.WebSDK.Mail;

/// <summary>
/// 메일 부분에서 사용되는 유틸리티 메서드 제공
/// </summary>
public class MailUtil
{
    // 폴더 형식을 정의한다.
    public static Guid AllMails = new Guid("00000000-0000-0000-0000-000000000001");
    public static Guid UnreadMails = new Guid("00000000-0000-0000-0000-000000000002");
    public static Guid FlaggedMails = new Guid("00000000-0000-0000-0000-000000000003");
    public static Guid ReadRecipients = new Guid("3aa4b3c6-4304-4bec-8d98-9dd3e3eb7c74");
    public static Guid MailToApprove = new Guid("182e285e-9824-437b-aa4b-5e60331161d2");
    public static Guid MailToApprove_Delegate = new Guid("66619a7a-5bb4-4b17-940c-80dad87b88a8");
    public static Guid MailWaitForApproval = new Guid("836021e5-3cc6-463a-8dd4-ea24a8ab54bf");
    public static Guid SpamNotification = new Guid("c1697410-5080-4942-8ea5-ff2081768011");

    public const string AllMailsMailboxName = "mcAllMails";
    public const string UnreadMailsMailboxName = "mcUnreadMails";
    public const string FlaggedMailsMailboxName = "mcFlaggedMails";
    public const string ReadRecipientsMailboxName = "mcRecipients";
    public const string MailToApproveMailboxName = "mcMailToApprove";
    public const string MailWaitForApprovalMailboxName = "mcMailWaitForApproval";
    public const string SpamNotificationMailboxName = "mcSpamNotification";

    /// <summary>
    /// E-mail 주소 검출 정규식
    /// Ex) khkim@tabslab.com
    /// </summary>
    public static string EmailPattern = @"[-+.'!#$%&=/\w\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]+@\w+([-.]\w+)*\.\w+([-.]\w+)*";

    /// <summary>
    /// E-mail 주소 검출 정규식
    /// Ex) (khkim@tabslab.com)
    /// </summary>
    public static string EmailPatternWithBracket = @"[\x28]([-+.'!#$%&=/\w\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]+@\w+([-.]\w+)*\.\w+([-.]\w+)*)[\x29]";

    /// <summary>
    /// E-mail 주소 검출 정규식
    /// Ex) "홍길동" <khkim@tabslab.com>
    /// Ex) "홍길동" (khkim@tabslab.com)
    /// </summary>
    public static string EmailPatternWithName = @"(\x22[^\x22]*\x22)?(\s*)[<\x28]?([-+.'!#$%&=/\w\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]+@\w+([-.]\w+)*\.\w+([-.]\w+)*)[>\x29]?";


    public MailUtil()
    {
    }

    /// <summary>
    /// 메일함에 따른 이미지 이름을 반환한다.
    /// </summary>
    /// <param name="mailboxName">메일함 이름</param>
    /// <returns>이미지 파일 이름</returns>
    public static string GetMailboxImageName(string mailboxName)
    {
        string imageName;
        switch (mailboxName)
        {
            case Mailbox.INBOX:
                imageName = "recvbox_16.gif";
                break;
            case Mailbox.SENTBOX:
                imageName = "sentbox_16.gif";
                break;
            case Mailbox.SPAMBOX:
                imageName = "spambox_16.gif";
                break;
            case Mailbox.TEMPBOX:
                imageName = "tempbox_16.gif";
                break;
            case Mailbox.TRASHBOX:
                imageName = "trashbox_16.gif";
                break;
            case AllMailsMailboxName:
                imageName = "allmails_16.gif";
                break;
            case UnreadMailsMailboxName:
                imageName = "unread_16.gif";
                break;
            case FlaggedMailsMailboxName:
                imageName = "msgflag1.gif";
                break;
            case ReadRecipientsMailboxName:
                imageName = "readrecpients_16.gif";
                break;
            case MailToApproveMailboxName:
            case MailWaitForApprovalMailboxName:
                imageName = "mailapproval_16.gif";
                break;
            default:
                imageName = "folder_16.gif";
                break;
        }
        return imageName;
    }

    public static string GetMailboxFontIcon(string mailboxName)
    {
        string imageName;
        switch (mailboxName)
        {
            case Mailbox.INBOX:
                imageName = FontIcon.EmailInbox;
                break;
            case Mailbox.SENTBOX:
                imageName = FontIcon.EmailSent;
                break;
            case Mailbox.SPAMBOX:
                imageName = FontIcon.EmailSpambox;
                break;
            case Mailbox.TEMPBOX:
                imageName = FontIcon.EmailTempbox;
                break;
            case Mailbox.TRASHBOX:
                imageName = FontIcon.EmailTrash;
                break;
            case AllMailsMailboxName:
                imageName = FontIcon.EmailAllBox;
                break;
            case UnreadMailsMailboxName:
                imageName = FontIcon.EmailUnread;
                break;
            case FlaggedMailsMailboxName:
                imageName = FontIcon.EmailFlagged;
                break;
            case ReadRecipientsMailboxName:
                imageName = FontIcon.EmailReadReceipt;
                break;
            case MailToApproveMailboxName:
            case MailWaitForApprovalMailboxName:
                imageName = FontIcon.EmailApproval;
                break;
            case SpamNotificationMailboxName:
                imageName = FontIcon.EmailSpambox;
                break;
            default:
                imageName = FontIcon.EmailFolder;
                break;
        }
        return imageName;
    }

    public static string GetMailboxFontIcon2(string mailboxName)
    {
        string imageName;
        switch (mailboxName)
        {
            case Mailbox.INBOX:
                imageName = FontIcon2.EmailInbox;
                break;
            case Mailbox.SENTBOX:
                imageName = FontIcon2.EmailSent;
                break;
            case Mailbox.SPAMBOX:
                imageName = FontIcon2.EmailSpambox;
                break;
            case Mailbox.TEMPBOX:
                imageName = FontIcon2.EmailTempbox;
                break;
            case Mailbox.TRASHBOX:
                imageName = FontIcon2.EmailTrash;
                break;
            default:
                imageName = FontIcon2.EmailFolder;
                break;
        }
        return imageName;
    }

    /// <summary>
    /// 메일함에 따른 표시 이름을 반환한다.
    /// </summary>
    /// <param name="mailboxName">메일함 이름</param>
    /// <returns>메일함 표시 이름</returns>
    public static string GetMailboxDisplayName(string mailboxName)
    {
        string displayName;
        switch (mailboxName)
        {
            case Mailbox.INBOX:
                displayName = Resources.Mail.Recvbox;
                break;
            case Mailbox.SENTBOX:
                displayName = Resources.Mail.Sentbox;
                break;
            case Mailbox.SPAMBOX:
                displayName = Resources.Mail.Spambox;
                break;
            case Mailbox.TEMPBOX:
                displayName = Resources.Mail.Tempbox;
                break;
            case Mailbox.TRASHBOX:
                displayName = Resources.Mail.Trashbox;
                break;
            case AllMailsMailboxName:
                displayName = Resources.Mail.AllMails;
                break;
            case UnreadMailsMailboxName:
                displayName = Resources.Mail.UnreadMails;
                break;
            case FlaggedMailsMailboxName:
                displayName = Resources.Mail.FlaggedMails;
                break;
            case ReadRecipientsMailboxName:
                displayName = Resources.Mail.ReadRecipientsMailbox;
                break;
            default:
                displayName = mailboxName;
                break;
        }
        return displayName;
    }

    /// <summary>
    /// 메일함에 따른 표시 이름을 반환한다.
    /// </summary>
    /// <param name="mailboxName">메일함 이름</param>
    /// <returns>메일함 표시 이름</returns>
    public static string GetMailboxDisplayName(int indent, string mailboxName)
    {
        string displayName;
        switch (mailboxName)
        {
            case Mailbox.INBOX:
                displayName = Resources.Mail.Recvbox;
                break;
            case Mailbox.SENTBOX:
                displayName = Resources.Mail.Sentbox;
                break;
            case Mailbox.SPAMBOX:
                displayName = Resources.Mail.Spambox;
                break;
            case Mailbox.TEMPBOX:
                displayName = Resources.Mail.Tempbox;
                break;
            case Mailbox.TRASHBOX:
                displayName = Resources.Mail.Trashbox;
                break;
            default:
                displayName = WebUtil.GetTrimmedName(indent, mailboxName);
                break;
        }
        return displayName;
    }

    /// <summary>
    /// 메시지 처리 플래그에 따른 이미지 이름을 반환한다.
    /// </summary>
    /// <param name="actionFlag"></param>
    /// <returns></returns>
    public static string GetActionFlagImageName(bool newMsg, Message.MsgActionFlag actionFlag)
    {
        string imageName = "msg_opened.gif";
        if (newMsg)
            imageName = "msg_new.gif";
        else
        {
            if ((actionFlag & Message.MsgActionFlag.Editing) > 0)
                imageName = "msg_edit.gif";
            else
            {
                if ((actionFlag & Message.MsgActionFlag.Forward) > 0)
                    imageName = "msg_fwd.gif";
                else if ((actionFlag & Message.MsgActionFlag.Reply) > 0)
                    imageName = "msg_reply.gif";
                else if ((actionFlag & Message.MsgActionFlag.ReplyAll) > 0)
                    imageName = "msg_replyall.gif";
            }
        }
        return imageName;
    }

    public static string GetActionFlagFontIcon(bool newMsg, Message.MsgActionFlag actionFlag)
    {
        string imageName = "";
        if (newMsg)
        {
            imageName = "<span class='fa-solid fa-envelope'></span>";
        }
        else
        {
            if ((actionFlag & Message.MsgActionFlag.Editing) > 0)
            {
                imageName = "<span class='fa-solid fa-pen-to-square'></span>";
            }
            else
            {
                if ((actionFlag & Message.MsgActionFlag.Forward) > 0)
                    imageName = "<span class='fa-solid fa-share'></span>";
                else if ((actionFlag & Message.MsgActionFlag.Reply) > 0)
                    imageName = "<span class='fa-solid fa-reply'></span>";
                else if ((actionFlag & Message.MsgActionFlag.ReplyAll) > 0)
                    imageName = "<span class='fa-solid fa-reply-all'></span>";
            }
        }
        return imageName;
    }

    /// <summary>
    /// 우선 순위에 따른 이미지 이름을 반환한다.
    /// </summary>
    /// <param name="priority">메시지 우선 순위</param>
    /// <returns>이미지 이름</returns>
    public static string GetPriorityImageName(int priority)
    {
        string imageName;
        switch (priority)
        {
            case 1:
                 imageName = "priorityhigh.gif";
                break;
            case 5:
                 imageName = "prioritylow.gif";
                break;
            default:
                 imageName = "prioritynormal.gif";
                break;
        }
        return imageName;
    }

    /// <summary>
    /// 첨부 파일 이미지를 반환한다.
    /// </summary>
    /// <param name="attachNum">첨부 파일 개수</param>
    /// <returns>이미지 이름</returns>
    public static string GetAttachImageName(int attachNum)
    {
        return (attachNum > 0) ? "attach.gif" : "noattach.gif";
    }

    /// <summary>
    /// 첨부 파일 폰트 아이콘을 반환한다.
    /// </summary>
    /// <param name="attachNum">첨부 파일 개수</param>
    /// <returns>폰트 아이콘 태그</returns>
    public static string GetAttachFontIcon(int attachNum)
    {
        return (attachNum > 0) ? "<i class=\"fa-solid fa-paperclip\"></i>" : "";
    }

    /// <summary>
    /// 메일 발송자를 HTML 출력용 문자열로 변환한다.
    /// </summary>
    /// <param name="name"></param>
    /// <param name="address"></param>
    /// <returns></returns>
    public static string GetMailFromString4Html(string name, string address)
    {
        if (name != "")            
            return HttpUtility.HtmlEncode(name);
        else
            return address;
    }

    /// <summary>
    /// 받는 사람 목록을 HTML 출력용 문자열로 변환한다.
    ///  - to, cc 출력에 사용
    /// </summary>
    /// <param name="recipients">받는 사람 목록</param>
    /// <returns></returns>
    public static string GetRecipientsString4Html(Recipient[] recipients, int maxRecipients, bool shortFormat = true)
    {
        StringBuilder sb = new StringBuilder(1024);
        for (int i = 0; i < recipients.Length && i < maxRecipients; i++)
        {
            Recipient recipient = recipients[i];
            if (i != 0) sb.Append(" ");
            sb.Append(string.Format("<span class='label label-default'>{0}</span>", MailUtil.GetRecipientString4Html(recipient.Name, recipient.Address, shortFormat)));
        }
        if (recipients.Length > maxRecipients)
        {
            string fmt = string.Format(" <small class='text-muted'>{0}</small>", Resources.Mail.AndOthers);     // 외 {0}명
            sb.Append(string.Format(fmt, recipients.Length - maxRecipients));
        }

        return sb.ToString();
    }

    // 수신자 메일 정보를 HTML 츨력용으로 반환한다.
    public static string GetRecipientString4Html(string name, string address, bool shortFormat = true)
    {
        string rcptStr;
        if (name != "")
        {
            // 이름 전후에 붙은 따옴표 및 공백 제거
            char[] trimChars = { ' ', '"', '\'' };
            name = name.Trim(trimChars);
            if (shortFormat)
                rcptStr = HttpUtility.HtmlEncode(name);
            else
                rcptStr = string.Format("{0} ({1})", HttpUtility.HtmlEncode(name), address);
        }
        else
        {
            rcptStr = address;
        }
        return rcptStr;
    }

    /// <summary>
    /// 이름과 메일 주소를 받아 이름(메일주소) 형식으로 만들어서 반환한다.
    /// 메일 작성 페이지에서 호출한다.
    /// </summary>
    /// <param name="name"></param>
    /// <param name="address"></param>
    /// <returns></returns>
    public static string GetRecipientString(string name, string address)
    {
        string rcptStr;
        // 이름 전후에 붙은 따옴표 및 공백 제거
        char[] trimChars = { ' ', '"', '\'' };
        name = name.Trim(trimChars);
        if (name != "" && address != "")
            rcptStr = string.Format("\"{0}\" ({1})", name, address);
        else if (name != "")
            rcptStr = name;
        else
            rcptStr = address;
        return rcptStr;
    }

    // <summary>
    /// img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEU 와 같은 인라인 이미지 태그를 메일 인라인 이미지로 변환한다.
    /// </summary>
    /// <param name="html"></param>
    /// <param name="message"></param>
    /// <returns></returns>
    public static string ConvertBinaryImgTagToCidImgTag(string html, NewMessage message)
    {
        string[] ext = { "png", "jpeg", "gif", "bmp", "" };
        try
        {
            for (int i = 0; ext[i].Length > 0; i++)
            {
                string pattern = string.Format(@"src=""data:image/{0};base64,(.*?)""", ext[i]);
                Regex r = new Regex(pattern, RegexOptions.IgnoreCase);
                Match m = r.Match(html);
                while (m.Success)
                {
                    string base64 = m.Groups[1].Value;
                    string imgName = string.Format("{0:N}.{1}", Guid.NewGuid(), ext[i]);
                    byte[] imgData = System.Convert.FromBase64String(base64);
                    string imgPath = string.Format("{0}\\{1}", GlobalConfig.WebShareTempPath, imgName);
                    using (FileStream fs = new FileStream(imgPath, FileMode.Create, FileAccess.Write))
                    {
                        fs.Write(imgData, 0, imgData.Length);
                        fs.Close();

                        string imgTag = string.Format("src=\"{0}\"", imgName);
                        html = html.Remove(m.Index, m.Length).Insert(m.Index, imgTag);
                        Attachment attachment = new Attachment(imgName, imgPath);
                        message.Inlines.Add(attachment);
                    }
                    m = r.Match(html);
                }
            }
        }
        catch
        {
        }
        return html;
    }
}
