using System;
using System.Collections.Generic;
using System.Data;
using System.Data.SqlClient;
using System.Globalization;
using System.Threading;
using System.Text;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using TABS.MailCarrier.AuxLib;
using TABS.MailCarrier.WebSDK;
using TABS.MailCarrier.WebSDK.Filebox;
using TABS.MailCarrier.WebSDK.Mail;
using TABS.MailCarrier.WebSDK.User;
using System.Text.RegularExpressions;

public partial class Mail_PermitSend_View : System.Web.UI.Page
{
    private const int MAX_RECIPIENTS = 10;      // 최대 수신자 출력 수
    protected Guid _clId;                       // 메시지 ID
    protected string _listPageParams;
    protected string _ccCssClass = "";          // 참조 영역 class 값
    protected string _bccCssClass = "";         // 숨은 참조 영역 class 값
    protected string _attachCssClass = "";      // 첨부 영역 class 값
    protected string _approveButtonText = "";
    protected string _declineButtonText = "";

    protected override void InitializeCulture()
    {
        string defLang = WebUser.CurrentUser.UiLanguage;
        Thread.CurrentThread.CurrentCulture = CultureInfo.CreateSpecificCulture(defLang);
        Thread.CurrentThread.CurrentUICulture = new CultureInfo(defLang);
        base.InitializeCulture();
    }

    protected void Page_Init(object sender, EventArgs e)
    {
        WebUtil.SetMcCommonCss2(Page.Header);
    }

    protected void Page_Load(object sender, EventArgs e)
    {
        _clId = WebParam.GetGuidParamValue("clid");
        if (_clId == Guid.Empty) return;

        if (!IsPostBack)
        {
            Page.Title = AppSetting.GetTitleInfo(Request).Title;
            _approveButtonText = GetLocalResourceObject("Approve").ToString();
            _declineButtonText = GetLocalResourceObject("Decline").ToString();

            string validKey1 = "delegate=" + _clId.ToString();
            string validKey2 = "clid=" + _clId.ToString();
            Session.Remove(validKey1);
            Session.Remove(validKey2);

            bool dgRequest = WebParam.GetStrParamValue("delegate") != "";
            Guid senderId = Guid.Empty;
            PermitSendEx ps = new PermitSendEx(WebUser.CurrentUser.DomainID);
            if (dgRequest)
            {
                // 대리자에 의한 페이지 호출 시 해당 메일을 처리할 수 있는 지 여부를 확인한다.
                if (ps.CanConfirmByDelegate(_clId, WebUser.CurrentUser.DomainUserID))
                {
                    // 승인 대기 상태가 아니거나 대리자 본인 발송 메일은 승인할 수 없다.
                    bool agentCannotApproveOwnMail = AppSetting.GetAppSettingValue("AMS-AgentCannotApproveOwnMail", false);
                    int psFlag = GetPsFlag(_clId, ref senderId);
                    if (psFlag != 0 || (agentCannotApproveOwnMail && WebUser.CurrentUser.DomainUserID == senderId))
                    {
                        confirmToolButton.Disabled = true;
                        rejectToolButton.Disabled = true;
                    }
                    else
                    {
                        // 해당 대기 메일을 처리할 수 있다고 세션에 표시(DecideSend.aspx에서 검사하지 않기 위함)
                        Session[validKey1] = true;
                    }
                    LoadMailMessage("auto");
                }
                else
                {
                    Response.Redirect("~/Error.aspx?code=0");
                    return;
                }
            }
            else
            {
                if (ps.IsConfirmer(WebUser.CurrentUser.DomainUserID))
                {
                    int psFlag = GetPsFlag(_clId, ref senderId);
                    if (psFlag != 0)
                    {
                        confirmToolButton.Disabled = true;
                        rejectToolButton.Disabled = true;
                    }
                    else
                    {
                        // 해당 대기 메일을 처리할 수 있다고 세션에 표시(DecideSend.aspx에서 검사하지 않기 위함)
                        Session[validKey2] = true;
                    }
                    LoadMailMessage("auto");
                }
                else
                {
                    confirmToolButton.Disabled = true;
                    rejectToolButton.Disabled = true;
                }
            }
        }

        _listPageParams = string.Format("mode={0}&page={1}&delegate={2}", WebParam.GetStrParamValue("mode"), WebParam.GetIntParamValue("page"), WebParam.GetStrParamValue("delegate"));
    }

    private void LoadMailMessage(string charset)
    {
        string emlPath = "";
        SqlConnection conn = new SqlConnection(GlobalConfig.ConnString);
        PermitSendEx ps = new PermitSendEx(WebUser.CurrentUser.DomainID);

        Guid flid = ps.GetEmlFileID(conn, _clId);
        if (flid != Guid.Empty)
        {
            FileboxFile ff = new FileboxFile(flid);
            ff.Load();
            emlPath = ff.Path;
        }
        if (emlPath == "") return;

        // 실제 메일을 받는 모든 수신자를 찾는다.
        //  - 숨은 참조, 포워드로 인해 헤더에는 드러나지 않는 수신자를 별도로 출력하기 위함
        DataSet ds = ps.PsConfirmListMsgSelect(conn, _clId);
        Dictionary<string, int> toAddrs = new Dictionary<string, int>();
        foreach (DataRow r in ds.Tables[0].Rows)
            toAddrs.Add((r["cm_to"] as string).ToLower(), 0);

        Message message = new Message(emlPath);
        try
        {
            message.Charset = charset;
            message.Load();

            // 메시지를 출력한다.
            ShowMailMessage(message, toAddrs);
        }
        catch (LoadFailException)
        {
        }
    }

    private int GetPsFlag(Guid clid, ref Guid senderId)
    {
        int flag = 0;
        SqlConnection conn = new SqlConnection(GlobalConfig.ConnString);
        PermitSendEx ps = new PermitSendEx(WebUser.CurrentUser.DomainID);
        try
        {
            conn.Open();
            DataSet ds = ps.PsConfirmListSelectById(conn, clid);
            if (ds.Tables[0].Rows.Count > 0)
            {
                DataRow row = ds.Tables[0].Rows[0];
                flag = (int)row["cl_flag"];
                senderId = (Guid)row["cl_senderid"];
            }
        }
        finally
        {
            conn.Close();
        }
        return flag;
    }

    private void ShowMailMessage(Message message, Dictionary<string, int> toAddrs)
    {
        // 제목 출력
        SubjectLabel.Text = message.Subject;

        // 보낸 사람 출력
        FromAddrLabel.Text = MailUtil.GetRecipientString4Html(message.FromName, message.FromAddress, false);

        // 받는 사람 출력
        ToAddrTag.Text = MailUtil.GetRecipientsString4Html(message.To, MAX_RECIPIENTS, false);

        // 참조 출력
        CcAddrTag.Text = MailUtil.GetRecipientsString4Html(message.Cc, MAX_RECIPIENTS, false);
        _ccCssClass = (CcAddrTag.Text.Length == 0) ? "collapse" : "";

        // 숨은 참조, 포워드로 인해 헤더에는 들어나지 않는 수신자를 별도로 출력하기 위함
        List<Recipient> others = new List<Recipient>();
        foreach (Recipient r in message.To)
        {
            string key = r.Address.ToLower();
            if (toAddrs.ContainsKey(key)) toAddrs[key] = 1;
        }
        foreach (Recipient r in message.Cc)
        {
            string key = r.Address.ToLower();
            if (toAddrs.ContainsKey(key)) toAddrs[key] = 1;
        }
        foreach (KeyValuePair<string, int> kvp in toAddrs)
        {
            if (kvp.Value == 0) others.Add(new Recipient("", kvp.Key));
        }
        BccAddrTag.Text = MailUtil.GetRecipientsString4Html(others.ToArray(), MAX_RECIPIENTS, false);
        _bccCssClass = (BccAddrTag.Text.Length == 0) ? "collapse" : "";

        // 받은 날짜 출력 - Date 부분이 잘못 구성된 메시지가 있으므로 예외를 처리한다.
        try
        {
            RecvDateLabel.Text = string.Format("{0:f}", WebUser.CurrentUser.ToLocalTime(message.SentTime));
        }
        catch
        {
            RecvDateLabel.Text = message.GetHeader("Date");
        }

        // 첨부 파일 출력
        int attachCount = 0, attachSize = 0;
        bool relatedAttach = false;
        if (message.Attachments.Length > 0)
        {
            ExtIconMap extIconMap = new ExtIconMap();
            StringBuilder attchSb = new StringBuilder();
            foreach (Attachment attach in message.Attachments)
            {
                if (attach.ContentType == "message/rfc822")
                {
                    string item = (!attach.Deleted) ?
                        string.Format("<a href='#' class='list-group-item' onclick='OpenViewEmlWindow(\"{1}\")'><img src='../../Images/Ext/{0}'/>{2} ({3})</a>",
                            extIconMap.GetIconName(attach.FilePath), Server.UrlEncode(attach.FilePath), attach.FileName, WebUtil.GetFormattedFileSize(attach.Size)) :
                        string.Format("<div class='list-group-item'><img src='../../Images/Ext/{0}'/><del>{1} ({2})</del></div>",
                            extIconMap.GetIconName(attach.FilePath), attach.FileName, WebUtil.GetFormattedFileSize(attach.Size));

                    attchSb.Append(item);
                    attachCount++;
                    attachSize += attach.Size;
                }
                else if (attach.ContentID != "" && message.HtmlBody.IndexOf(attach.ContentID) > 0)
                {
                    relatedAttach = true;
                }
                else
                {
                    // 잘못 구성된 인라인 파일이더라도 ContentID만 존재하면 HTML 구성시 인라인이 처리될 수 있도록 relatedAttach = true로 지정한다.
                    //  - ContentID가 존재하고 attachment로 명시되어 있지만 실제는 inline으로 사용되는 메시지가 있다.
                    if (attach.ContentID != "") relatedAttach = true;

                    string item = (!attach.Deleted) ?
                        string.Format("<a href='../Download.ashx?file={1}&name={2}' class='list-group-item'><img src='../../Images/Ext/{0}'/>{3} ({4})</a>",
                            extIconMap.GetIconName(attach.FilePath), attach.FilePath, Server.UrlEncode(attach.FileName), attach.FileName, WebUtil.GetFormattedFileSize(attach.Size)) :
                        string.Format("<div class='list-group-item'><img src='../../Images/Ext/{0}'/><del>{1} ({2})</del></div>",
                            extIconMap.GetIconName(attach.FilePath), attach.FileName, WebUtil.GetFormattedFileSize(attach.Size));
                    attchSb.Append(item);
                    attachCount++;
                    attachSize += attach.Size;

                    if (attach.ContentType == "application/ms-tnef" && !attach.Deleted)
                    {
                        if (AppSetting.SupportParseTNEF)
                        {
                            string webTempPath = GlobalConfig.WebShareTempPath;
                            TnefParser tnefParser = new TnefParser();
                            List<TnefAttachFile> tnefAttachments = tnefParser.Parse(webTempPath + "\\" + attach.FilePath, webTempPath, message.ID.ToString());
                            foreach (TnefAttachFile tnefAttach in tnefAttachments)
                            {
                                item = string.Format("<a href='#' class='list-group-item'><img src='../Images/Ext/{0}'/>TNEF_{3} ({4})</a>",
                                        extIconMap.GetIconName(tnefAttach.FileName), tnefAttach.SaveName,
                                        Server.UrlEncode(tnefAttach.FileName), tnefAttach.FileName, WebUtil.GetFormattedFileSize(tnefAttach.FileSize));
                                attchSb.Append(item);
                                attachCount++;
                                attachSize += attach.Size;
                            }
                        }
                    }
                }
            }
            AttachListTag.Text = attchSb.ToString();
        }
        _attachCssClass = (attachCount > 0) ? "collapse in" : "collapse";
        AttachSummaryLabel.Text = string.Format(GetLocalResourceObject("AttachSummary").ToString(), attachCount, WebUtil.GetFormattedFileSize((long)attachSize));

        // 본문 출력
        if (message.HtmlBody != "")
        {
            // <body>에 있는 스타일 등을 제거하기 위해 <body></body>를 제거한다.
            HtmlStripper htmlStripper = new HtmlStripper();
            string html = htmlStripper.StripBodyTag(message.HtmlBody);
            // 수신확인 링크 제거
            Regex r = new Regex(@"MailRead\x2eashx\x3fread=[A-Fa-f0-9]{8}(?:-[A-Fa-f0-9]{4}){3}-[A-Fa-f0-9]{12}", RegexOptions.IgnoreCase);
            html = r.Replace(html, "MailRead.ashx?read=00000000-0000-0000-0000-000000000000");

            if (relatedAttach)
            {
                Array.Sort<Attachment>(message.Attachments, new Comparison<Attachment>((i1, i2) => i2.ContentID.CompareTo(i1.ContentID)));
                foreach (Attachment attach in message.Attachments)
                {
                    if (attach.ContentID != "")
                    {
                        string cid = "cid:" + attach.ContentID;
                        string downlink = "../Download.ashx?content=" + attach.FilePath;
                        html = html.Replace(cid, downlink);
                    }
                }
            }
            MsgBodyHolder.Controls.Add(new LiteralControl(html));
        }
        else
        {
            string html = WebUtil.GetFormattedPlainText(message.TextBody, true);
            MsgBodyHolder.Controls.Add(new LiteralControl(html));
        }
    }
}