using System;
using System.Data;
using System.Data.SqlClient;
using System.Collections.Generic;
using System.Configuration;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using TABS.MailCarrier.WebSDK;
using TABS.MailCarrier.WebSDK.Mail;
using TABS.MailCarrier.WebSDK.User;

/// <summary>
/// 메일함 폴더 구조를 반환하는 데이터 소스 클래스입니다.
/// </summary>
public class MailFolderDataSource
{
    public class FolderItem
    {
        private Guid _id;
        private string _folderName;
        private bool _reserved;
        private int _newMsgCount;
        private int _msgCount;
        private long _spaceUsed;
        private int _indent;
        private bool _checked;
        private Dictionary<string, string> _items = new Dictionary<string, string>();

        public FolderItem(Guid id, string folderName, bool reserved, int newMsgCount, int msgCount, long spaceUsed, int indent)
        {
            _id = id;
            _folderName = folderName;
            _reserved = reserved;
            _newMsgCount = newMsgCount;
            _msgCount = msgCount;
            _spaceUsed = spaceUsed;
            _indent = indent;
            _checked = false;
        }

        public FolderItem(Guid id, string folderName, bool reserved, int indent, bool checked_)
        {
            _id = id;
            _folderName = folderName;
            _reserved = reserved;
            _newMsgCount = 0;
            _msgCount = 0;
            _spaceUsed = 0;
            _indent = indent;
            _checked = checked_;
        }

        public Guid ID
        {
            get { return _id; }
        }

        public string FolderName
        {
            get { return _folderName; }
        }

        public bool Reserved
        {
            get { return _reserved; }
        }

        public int NewMsgCount
        {
            get { return _newMsgCount; }
        }

        public int MsgCount
        {
            get { return _msgCount; }
        }

        public long SpaceUsed
        {
            get { return _spaceUsed; }
        }

        public int Indent
        {
            get { return _indent; }
        }

        public bool Checked
        {
            get { return _checked; }
        }

        public Dictionary<string, string> Items
        {
            get { return _items; }
        }
    }

    public MailFolderDataSource()
    {
    }

    public List<FolderItem> GetFolders(bool allMails, bool unreadMails, bool flaggedMails, bool readRecipients, bool sendApproval, bool spamNotification)
    {
        List<FolderItem> folders = new List<FolderItem>();

        if (allMails)
            folders.Add(new FolderItem(MailUtil.AllMails, MailUtil.AllMailsMailboxName, true, 0, 0, 0, 0));
        if (unreadMails)
            folders.Add(new FolderItem(MailUtil.UnreadMails, MailUtil.UnreadMailsMailboxName, true, 0, 0, 0, 0));
        if (flaggedMails)
            folders.Add(new FolderItem(MailUtil.FlaggedMails, MailUtil.FlaggedMailsMailboxName, true, 0, 0, 0, 0));

        if (sendApproval && GlobalConfig.SchemaVersion >= 753)
        {
            PermitSendEx ps = new PermitSendEx(WebUser.CurrentUser.DomainID);
            if (ps.IsApplied())
            {
                PermitSendEx.PsApproverInfoList apvInfoList = ps.GetApproverInfoByDelegate(WebUser.CurrentUser.DomainUserID);
                // 승인할 메일
                if (ps.IsConfirmer(WebUser.CurrentUser.DomainUserID))
                {
                    using (SqlConnection conn = new SqlConnection(GlobalConfig.ConnString))
                    {
                        folders.Add(new FolderItem(MailUtil.MailToApprove, MailUtil.MailToApproveMailboxName, true, 0, ps.PsConfirmListGetWaitCount(conn, WebUser.CurrentUser.DomainUserID), 0, 0));
                    }
                    // 대리자 발송 승인
                    foreach (PermitSendEx.PsApproverInfo apvInfo in apvInfoList)
                    {
                        FolderItem fi = new FolderItem(MailUtil.MailToApprove_Delegate, apvInfo.Name, true, 0, 0, 0, 1);
                        fi.Items.Add("DelegateID", apvInfo.DomainUserID.ToString());
                        folders.Add(fi);
                    }
                }
                else if (apvInfoList.Count > 0)
                {
                    // 본인이 승인자는 아니지만 대리자인 경우
                    FolderItem fi = new FolderItem(MailUtil.MailToApprove, MailUtil.MailToApproveMailboxName, true, 0, 0, 0, 0);
                    fi.Items.Add("EmptyView", "");
                    folders.Add(fi);
                    // 대리자 발송 승인
                    foreach (PermitSendEx.PsApproverInfo apvInfo in apvInfoList)
                    {
                        fi = new FolderItem(MailUtil.MailToApprove_Delegate, apvInfo.Name, true, 0, 0, 0, 1);
                        fi.Items.Add("DelegateID", apvInfo.DomainUserID.ToString());
                        folders.Add(fi);
                    }
                }

                // 승인 대기 메일
                if (ps.IsConfirmed(WebUser.CurrentUser.DomainUserID))
                {
                    folders.Add(new FolderItem(MailUtil.MailWaitForApproval, MailUtil.MailWaitForApprovalMailboxName, true, 0, 0, 0, 0));
                }
            }
        }

        UserMailbox userMbox = new UserMailbox(WebUser.CurrentUser.DomainUserID);
        foreach (Mailbox mailbox in userMbox.Mailboxes)
        {
            MailboxFolder folder = mailbox.RootFolder;
            FolderItem item = new FolderItem(folder.ID, folder.Name, mailbox.Reserved, folder.NewMessageCount, folder.MessageCount, folder.SpaceUsed, 0);
            folders.Add(item);
            TraverseSubFolders(folders, folder, false, 1);
            
            // 수신 확인 추가
            if (folder.Name == "mcSent" && readRecipients)
            {
                folders.Add(new FolderItem(MailUtil.ReadRecipients, MailUtil.ReadRecipientsMailboxName, true, 0, 0, 0, 0));
            }
        }

        DomainUser user = new DomainUser(WebUser.CurrentUser.DomainUserID);
        if (user.SpamOption.UseSpamNotifier && spamNotification)
        {
            folders.Add(new FolderItem(MailUtil.SpamNotification, MailUtil.SpamNotificationMailboxName, true, 0, 0, 0, 0));
        }        
        
        return folders;
    }

    private void TraverseSubFolders(List<FolderItem> folders, MailboxFolder folder, bool reserved, int indent)
    {
        foreach (MailboxFolder subfolder in folder.SubFolders)
        {
            FolderItem item = new FolderItem(subfolder.ID, subfolder.Name, reserved, subfolder.NewMessageCount, subfolder.MessageCount, subfolder.SpaceUsed, indent);
            folders.Add(item);
            TraverseSubFolders(folders, subfolder, reserved, indent + 1);
        }
    }

    public List<FolderItem> GetFolders4WebPush()
    {
        List<FolderItem> folders = new List<FolderItem>();

        UserMailbox userMbox = new UserMailbox(WebUser.CurrentUser.DomainUserID);
        foreach (Mailbox mailbox in userMbox.Mailboxes)
        {
            if (mailbox.Reserved && mailbox.Name == Mailbox.INBOX)
            {
                MailboxFolder folder = mailbox.RootFolder;
                FolderItem item = new FolderItem(folder.ID, folder.Name, mailbox.Reserved, 0, true);
                folders.Add(item);
                TraverseSubFolders4WebPush(folders, folder, false, 1);
            }
            else if (!mailbox.Reserved)
            {
                MailboxFolder folder = mailbox.RootFolder;
                FolderItem item = new FolderItem(folder.ID, folder.Name, mailbox.Reserved, 0, (folder.Flag & MailboxFolder.FolderFlag.WebPushSubscribed) > 0);
                folders.Add(item);
                TraverseSubFolders4WebPush(folders, folder, false, 1);
            }
        }

        return folders; ;
    }

    private void TraverseSubFolders4WebPush(List<FolderItem> folders, MailboxFolder folder, bool reserved, int indent)
    {
        foreach (MailboxFolder subfolder in folder.SubFolders)
        {
            FolderItem item = new FolderItem(subfolder.ID, subfolder.Name, reserved, indent, (subfolder.Flag & MailboxFolder.FolderFlag.WebPushSubscribed) > 0);
            folders.Add(item);
            TraverseSubFolders(folders, subfolder, reserved, indent + 1);
        }
    }
}
