using System;
using System.Collections.Generic;
using System.Globalization;
using System.Threading;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using TABS.MailCarrier.WebSDK;
using TABS.MailCarrier.WebSDK.Mail;
using TABS.MailCarrier.WebSDK.User;

/// <summary>
/// List.aspx 파라미터 
///   folder (필수, GUID) - 폴더 ID
///   page (선택, int) - 페이지 번호(0에서 시작)
///   searchCategoty (선택) - 검색 카테고리(subject, body, sender, receiver, all)
///   searchKeyword (선택) - 검색 키워드
/// </summary>
public partial class Mail_List : System.Web.UI.Page
{
    protected Guid _folderId;                  // 메시지 ID
    protected string _folderType;              // 메일박스 타입 (ex. mcInbox, mcSent ...)
    protected string _folderName;              // 메일박스 폴더 이름 (ex. mcInbox, mcSent, mcAllMails, 사용자정의 ...)
    protected string _sortExp;                 // 정렬 필드
    protected bool _newField;                  // 새 메시지 확인
    protected SortDirection _sortDirection;    // 정렬 순서 (ASC, DESC)
    protected string _complexPwdWarning = "";
    private int _newMailCount = 0;

    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.SetMcCommonCss(Page.Header);
    }

    protected void Page_Load(object sender, EventArgs e)
    {
        Page.Title = AppSetting.GetTitleInfo(Request).Title;
        if (!IsPostBack)
        {
            _folderId = WebParam.GetGuidParamValue("folder");
            if (_folderId == Guid.Empty) _folderId = GetDefaultFolderID();
            if (_folderId == MailUtil.AllMails)
            {
                _folderType = Mailbox.INBOX;
                _folderName = MailUtil.AllMailsMailboxName;
                MsgDataSource.SelectParameters[0].DefaultValue = _folderId.ToString();
            }
            else if (_folderId == MailUtil.UnreadMails)
            {
                _folderType = Mailbox.INBOX;
                _folderName = MailUtil.UnreadMailsMailboxName;
                MsgDataSource.SelectParameters[0].DefaultValue = _folderId.ToString();
                MsgDataSource.SelectParameters[1].DefaultValue = "true";
            }
            else if (_folderId == MailUtil.FlaggedMails)
            {
                _folderType = Mailbox.INBOX;
                _folderName = MailUtil.FlaggedMailsMailboxName;
                MsgDataSource.SelectParameters[0].DefaultValue = _folderId.ToString();
            }
            else
            {
                // folderId의 유효성 검사
                MailboxFolder folder = new MailboxFolder(_folderId);
                if (!folder.IsMine(WebUser.CurrentUser.DomainUserID))
                {
                    Response.Redirect("../Error.aspx", true);
                }
                _folderType = GetMailboxFolderType(_folderId, out _folderName);                
                _newMailCount = folder.NewMessageCount;
                MsgDataSource.SelectParameters[0].DefaultValue = _folderId.ToString();
            }

            CategoryList.SelectedValue = AppSetting.MailSearchCategory;
            ProcessGetParameters();
            SetMsgGridViewMethods(_folderType);

            ViewState["folderId"] = _folderId;
            ViewState["folderType"] = _folderType;
            ViewState["folderName"] = _folderName;
        }
        else
        {
            _folderId = (Guid)ViewState["folderId"];
            _folderType = (string)ViewState["folderType"];
            _folderName = (string)ViewState["folderName"];
            SetMsgGridViewMethods(_folderType);
        }
    }

    /// <summary>
    /// GET 파라미터에 따라 리스트, 검색 리스트를 선택해 출력한다.
    /// </summary>
    private void ProcessGetParameters()
    {
        int pageIndex = WebParam.GetIntParamValue("page");
        MsgGridView.PageIndex = pageIndex;
        CategoryList.SelectedValue = WebParam.GetStrParamValue("searchCategoty");
        KeywordTextBox.Text = WebParam.GetStrParamValue("searchKeyword");
        if (KeywordTextBox.Text.Trim().Length > 0)
        {
            SelectDataSoutce(true);
            searchPanel.Attributes.Add("class", "collapse in");
        }
    }
    /// <summary>
    /// 데이터 소스(일반, 검색)를 선택한다.
    /// </summary>
    /// <param name="search"></param>
    private void SelectDataSoutce(bool search)
    {
        if (search)
        {
            MsgGridView.DataSourceID = "SearchedMsgDataSource";            
            SearchedMsgDataSource.SelectParameters[0].DefaultValue = _folderId.ToString();
            SearchedMsgDataSource.SelectParameters[1].DefaultValue = KeywordTextBox.Text.Trim();
            SearchedMsgDataSource.SelectParameters[2].DefaultValue = CategoryList.SelectedValue;
            SearchedMsgDataSource.SelectParameters[3].DefaultValue = (_folderId == MailUtil.UnreadMails) ? "true" : "false";
        }
        else
        {
            MsgGridView.DataSourceID = "MsgDataSource";            
            MsgDataSource.SelectParameters[0].DefaultValue = _folderId.ToString();
            MsgDataSource.SelectParameters[1].DefaultValue = (_folderId == MailUtil.UnreadMails) ? "true" : "false";
        }
    }

    #region Page Event Methods

    protected void MsgGridView_PreRender(object sender, EventArgs e)
    {
        GridView gv = (GridView)sender;
        if ((gv.ShowHeader == true && gv.Rows.Count > 0) || (gv.ShowHeaderWhenEmpty == true))
        {
            gv.HeaderRow.TableSection = TableRowSection.TableHeader;
        }
        if (gv.ShowFooter == true && gv.Rows.Count > 0)
        {
            gv.FooterRow.TableSection = TableRowSection.TableFooter;
        }
    }
    
    protected void MsgDataSource_Selected(object sender, ObjectDataSourceStatusEventArgs e)
    {
        if (e.ReturnValue != null && e.ReturnValue.GetType() == typeof(System.Int32))
        {
            MsgGridView.Columns[1].HeaderText = (_newMailCount > 0) ?
                string.Format("{0} <span class='badge mc-badge'>{1}</span>", MailUtil.GetMailboxDisplayName(_folderName), _newMailCount) :
                string.Format("{0}", MailUtil.GetMailboxDisplayName(_folderName));
        }
    }

    protected void SearchedMsgDataSource_Selected(object sender, ObjectDataSourceStatusEventArgs e)
    {
        if (e.ReturnValue != null && e.ReturnValue.GetType() == typeof(System.Int32))
        {
            MsgGridView.Columns[1].HeaderText = string.Format("{0}", MailUtil.GetMailboxDisplayName(_folderName));
        }
    }

    protected void RefreshButton_Click(object sender, EventArgs e)
    {
        // 메일 삭제 ajax 호출 후 화면 갱신
        //  - 마지막 페이지인데 삭제로 인해 출력 레코드가 없을 경우 그 전 페이지로 강제 이동
        MsgGridView.DataBind();
        if (MsgGridView.Rows.Count == 0 && MsgGridView.PageIndex > 0)
        {
            MsgGridView.PageIndex--;
            MsgGridView.DataBind();
        }
    }

    // Ajax 호출 방식으로 변경되어 사용되지 않는다.
    protected void DeleteButton_Click(object sender, EventArgs e)
    {
        foreach (GridViewRow row in MsgGridView.Rows)
        {
            CheckBox check = (CheckBox)row.FindControl("SelectCheckBox");
            if (check.Checked)
            {
                Guid msgid = new Guid(MsgGridView.DataKeys[row.DataItemIndex - (MsgGridView.PageSize * MsgGridView.PageIndex)].Value.ToString());
                Message message = new Message(msgid);

                if (_folderType == Mailbox.TRASHBOX || _folderType == Mailbox.SPAMBOX)
                {
                    // 현재 메일박스가 휴지통이나 스팸편지함이라면 삭제처리한다.
                    message.Remove();
                    WebOperationLog.Write(WebUser.CurrentUser.MailAddress, Request.UserHostAddress, "M/Mail/List.aspx", "RemoveMessage", string.Format("{0}(msg:{1})", _folderType, message.ID));
                }
                else
                {
                    // 휴지통으로 이동
                    message.MoveToTrash(WebUser.CurrentUser.DomainUserID);
                    WebOperationLog.Write(WebUser.CurrentUser.MailAddress, Request.UserHostAddress, "M/Mail/List.aspx", "MsgMoveToTrash", string.Format("{0}(msg:{1})", _folderType, message.ID));
                }
            }
        }
        MsgGridView.DataBind();
    }

    protected void SearchButton_Click(object sender, EventArgs e)
    {
        string keyword = KeywordTextBox.Text.Trim();
        if (keyword.Length > 0)
        {
            SelectDataSoutce(true);
            MsgGridView.PageIndex = 0;
            MsgGridView.DataBind();
            searchPanel.Attributes.Add("class", "collapse in");
        }
        else
        {
            SelectDataSoutce(false);
            MsgGridView.PageIndex = 0;
            MsgGridView.DataBind();
        }
    }

    protected void SearchCancelButton_Click(object sender, EventArgs e)
    {
        KeywordTextBox.Text = "";       // <- DataBind() 전 호출 필수
        SelectDataSoutce(false);
        MsgGridView.PageIndex = 0;
        MsgGridView.DataBind();
        searchPanel.Attributes.Add("class", "collapse");
    }

    protected void MoveToButton_Click(object sender, EventArgs e)
    {
        List<string> msgIds = GetSelectedItems();
        int count = msgIds.Count;

        string messages = "";
        for (int i = 0; i < count; i++)
        {
            if (messages != "") messages += string.Format("|{0}", msgIds[i]);
            else messages = msgIds[i];
        }

        Response.Redirect("MoveTo.aspx?msg=" + messages + "&folder=" + _folderId + "&page=" + MsgGridView.PageIndex, true);
    }

    #endregion

    /// <summary>
    /// folderId를 가지고 메일박스 이름을 가져온다.
    /// </summary>
    /// <param name="folderId"></param>
    /// <returns></returns>
    private string GetMailboxFolderType(Guid folderId, out string folderName)
    {
        MailboxFolder folder = new MailboxFolder(folderId);
        folderName = folder.Name;
        Mailbox mailbox = new Mailbox(folder.MailboxID);
        string folderType = mailbox.Name;
        if (!mailbox.Reserved && (folder.Flag & MailboxFolder.FolderFlag.ViewAsSentbox) > 0) folderType = Mailbox.SENTBOX;
        return folderType;
    }

    protected string GetImageUrl()
    {
        return MailUtil.GetMailboxImageName(_folderName);
    }

    /// <summary>
    /// 체크 박스가 선택된 ID 리스트를 반환한다.
    /// </summary>
    /// <returns></returns>
    private List<string> GetSelectedItems()
    {
        List<string> list = new List<string>();
        foreach (GridViewRow row in MsgGridView.Rows)
        {
            CheckBox check = (CheckBox)row.FindControl("SelectCheckBox");
            if (check.Checked)
            {
                list.Add(MsgGridView.DataKeys[row.DataItemIndex - (MsgGridView.PageSize * MsgGridView.PageIndex)].Value.ToString());
            }
        }
        return list;
    }

    /// <summary>
    /// mcInbox의 folderId를 반환한다.
    /// </summary>
    /// <returns></returns>
    private Guid GetDefaultFolderID()
    {
        Guid inboxFolderId = MailboxFolder.GetRootFolderID(WebUser.CurrentUser.DomainUserID, Mailbox.INBOX);
        return inboxFolderId;
    }

    #region MsgGridView Methods

    protected delegate string getFromOrTo(string fromName, string fromAddr, string sentTo, bool newMsg);
    protected delegate string getSubject(string subject, bool newMsg, string folderName, int actionFlag);

    protected getFromOrTo GetFromOrTo = null;
    protected getSubject GetSubject = null;

    private void SetMsgGridViewMethods(string folderType)
    {
        if (folderType == Mailbox.SENTBOX || folderType == Mailbox.TEMPBOX)
        {
            GetFromOrTo = GetTo;
            GetSubject = GetGeneralSubject;
        }
        else
        {
            GetFromOrTo = GetFrom;
            if (_folderId == MailUtil.AllMails || _folderId == MailUtil.UnreadMails || _folderId == MailUtil.FlaggedMails) 
                GetSubject = GetGeneralSubjectWithFolderName;
            else GetSubject = GetGeneralSubject;
        }
    }

    protected string GetTo(string fromName, string fromAddr, string sentTo, bool newMsg)
    {
        string item = Server.HtmlEncode(sentTo);
        return (newMsg) ? "<span class='mc-new-mail'>" + item + "</span>" : item;
    }

    protected string GetFrom(string fromName, string fromAddr, string sentTo, bool newMsg)
    {
        string item = (fromName != "") ? fromName : fromAddr;
        item = Server.HtmlEncode(item);
        return (newMsg) ? "<span class='mc-new-mail'>" + item + "</span>" : item;
    }

    protected string GetGeneralSubject(string subject, bool newMsg, string folderName, int actionFlag)
    {
        subject = (subject != "") ? subject : "[제목 없음]";
        return string.Format("<span class='{0}' style='{1}'>{2}</span>", GetNewMailClass(newMsg), GetImapDeletedStyle(actionFlag), Server.HtmlEncode(subject));
    }

    protected string GetGeneralSubjectWithFolderName(string subject, bool newMsg, string folderName, int actionFlag)
    {
        subject = (subject != "") ? subject : "[제목 없음]";
        string fname = MailUtil.GetMailboxDisplayName(folderName);
        return string.Format("<small class=\"text-muted\">[{0}]</small> <span class='{1}' style='{2}'>{3}</span>", 
            Server.HtmlEncode(fname), GetNewMailClass(newMsg), GetImapDeletedStyle(actionFlag), Server.HtmlEncode(subject));
    }

    protected string GetActionFlagImage(bool newMsg, int actionFlag)
    {
        //return string.Format("<img src='../Images/Mail/{0}' />", MailUtil.GetActionFlagImageName(newMsg, (Message.MsgActionFlag)actionFlag));
        return MailUtil.GetActionFlagFontIcon(newMsg, (Message.MsgActionFlag)actionFlag);
    }

    protected string GetFormattedRecvTime(DateTime recvTime)
    {
        DateTime receive = WebUser.CurrentUser.ToLocalTime(recvTime);

        return (receive.ToShortDateString() == WebUser.CurrentUser.GetLocalToday().ToShortDateString()) ? receive.ToString("t") : receive.ToString("MM-dd");
    }

    protected string GetAttachmentImage(int attachNum)
    {
        return MailUtil.GetAttachFontIcon(attachNum);
    }

    protected string GetClickEventFunction(Guid msgId)
    {
        return (_folderType == Mailbox.TEMPBOX) ? 
            string.Format("EditMessage('{0}', '{1}', {2})", msgId, _folderId, MsgGridView.PageIndex) :
            string.Format("ViewMessage('{0}', '{1}', {2}, '{3}', '{4}')", msgId, _folderId, MsgGridView.PageIndex, CategoryList.SelectedValue, WebUtil.EncodeJsString2(KeywordTextBox.Text.Trim()));
    }

    private static string[] FlagColors = { "#CECEC6", "#D3401B", "#638CD6", "#F4DE84", "#94C673", "#F78431", "#B563D6" };

    protected string GetFlag(int flag, Guid msgId)
    {
        //return string.Format("<img src=\"../Images/Mail/msgflag{0}.gif\" data-flag-id=\"{1}\" data-flag-value=\"{0}\" />", flag, msgId.ToString());
        if (flag >= 0 && flag <=6)
            return string.Format("<span class=\"fa-solid fa-flag mc-likeLink\" style=\"color:{0}\" data-flag-id=\"{2}\" data-flag-value=\"{1}\" />", FlagColors[flag], flag, msgId.ToString());
        else
            return string.Format("<span class=\"fa-solid fa-check mc-likeLink\" style=\"color:#524A52\" data-flag-id=\"{1}\" data-flag-value=\"{0}\" />", flag, msgId.ToString());
    }

    private string GetNewMailClass(bool newMail)
    {
        return (newMail) ? "mc-new-mail" : "";
    }

    private string GetImapDeletedStyle(int actionFlag)
    {
        string style = "";
        if (((Message.MsgActionFlag)actionFlag & Message.MsgActionFlag.ImapDeleted) > 0)
        {
            style = "text-decoration:line-through;";
        }
        return style;
    }

    #endregion
}