using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Dao;
using Domain;

namespace Service.Implement
{
    public class GroupManager : GenericManagerBase<Group>, IGroupManager
    {
        public ISysUserRepository SysUserRepository { get; set; }
        public IHostRepository HostRepository { get; set; }

        public IList<Group> GetGroupList(Group group)
        {
            return ((IGroupRepository)CurrentRepository).GetGroupList(group);
        }

        public IList<Group> GetGroupList(int hotelID)
        {
            return ((IGroupRepository)CurrentRepository).GetGroupList(hotelID);
        }

        public override void Delete(object id)
        {
            Group group = CurrentRepository.Get(id);
            if (group != null)
            {
                if (SysUserRepository.GetByGroup(group).Count() > 0)
                {
                    throw new ApplicationException("分组【" + group.Name + "】已分配给用户，不能删除！");
                }

                if (HostRepository.GetByGroup(group).Count() > 0)
                {
                    throw new ApplicationException("分组【" + group.Name + "】已分配给主机，不能删除！");
                }
            }
            base.Delete(id);
        }

        public IList<object> CreateGroupTree(Group group, int hotelID)
        {
            return BuildGroupTree(CurrentRepository.LoadAll().Where(r => r.HotelID == hotelID).ToList(), group);
        }

        public object CreateGroupTree2(Group group, int hotelID)
        {
            if (group == null)
            {
                return null;
            }

            var groupMenu = ((IGroupRepository)CurrentRepository).GetGroupMenu(group.ID, hotelID);

            return BuildGroupTree(groupMenu);
        }

        public IList<object> CreateGroupTreeWithRoom(Group group, IList<Host> checkedHosts, int hotelID)
        {
            return BuildGroupTreeWithRoom(CurrentRepository.LoadAll().Where(r => r.HotelID == hotelID).ToList(), group, checkedHosts);
        }

        /// <summary>
        /// 按层级构造分组名称
        /// 例如:
        ///		BLW-1栋-1层
        /// </summary>
        /// <param name="group"></param>
        /// <returns></returns>
        public string BuildGroupName(Group group)
        {
            string name = "";
            while (group != null)
            {
                if (name == "")
                {
                    name = group.Name;
                }
                else
                {
                    name = group.Name + "-" + name;
                }
                group = group.Parent;
            }
            return name;
        }

        #region Private Methods

        /// <summary>
        /// 构造楼层树，用于 easyui-tree, easyui-combotree
        /// </summary>
        /// <param name="groups"></param>
        /// <param name="parent"></param>
        /// <returns></returns>
        private IList<object> BuildGroupTree(IList<Group> groups, Group parent)
        {
            IList<object> groupTree = new List<object>();
            IList<Group> subGroups = groups.Where(r => r.Parent == parent).OrderBy(o => o.Sort).ToList();
            foreach (Group group in subGroups)
            {
                IList<object> children = BuildGroupTree(groups, group);
                if (children.Count != 0)
                {
                    groupTree.Add(new { id = group.ID, text = group.Name, iconCls = "tree-node-no-icon", children = children });
                }
                else
                {
                    groupTree.Add(new { id = group.ID, text = group.Name, iconCls = "tree-node-no-icon" });
                }
            }

            return groupTree;
        }

        private object BuildGroupTree(GroupMenu groupMenu)
        {
            if (groupMenu == null)
            {
                return null;
            }
            if (groupMenu.SubGroupMenus.Count <= 0)
            {
                return new { id = groupMenu.ID, text = groupMenu.Name, iconCls = "tree-node-no-icon" };
            }
            IList<object> children = new List<object>();
            foreach (GroupMenu subGroupMenu in groupMenu.SubGroupMenus)
            {
                var subGroupTree = BuildGroupTree(subGroupMenu);
                if (subGroupTree != null)
                {
                    children.Add(subGroupTree);
                }
            }
            return new { id = groupMenu.ID, text = groupMenu.Name, iconCls = "tree-node-no-icon", children = children };
        }

        /// <summary>
        /// 构造带房号的 easyui-tree 数据格式的分组树，房号附在其所属的结点之下
        /// 如果分支上的房号包含在 checkedHosts 则将其选中
        /// </summary>
        /// <param name="groups"></param>
        /// <param name="parent"></param>
        /// <param name="checkedHosts"></param>
        /// <returns></returns>
        private IList<object> BuildGroupTreeWithRoom(IList<Group> groups, Group parent, IList<Host> checkedHosts)
        {
            IList<object> groupTree = new List<object>();
            IList<Group> subGroups = groups.Where(r => r.Parent == parent).OrderBy(o => o.Sort).ToList();
            foreach (Group group in subGroups)
            {
                IList<object> children = BuildGroupTreeWithRoom(groups, group, checkedHosts);
                if (children.Count != 0)
                {
                    groupTree.Add(new { id = group.ID, text = group.Name, iconCls = "tree-node-no-icon", children = children, attributes = new { isHost = false, roomTypeID = 0 } });
                }
                else
                {
                    groupTree.Add(new { id = group.ID, text = group.Name, iconCls = "tree-node-no-icon", attributes = new { isHost = false, roomTypeID = 0 } });
                }
            }
            var hosts = HostRepository.GetByGroup(parent).OrderBy(r => r.RoomType.ID).ToList();
            foreach (Host host in hosts)
            {
                if (checkedHosts != null && checkedHosts.Contains(host))
                {
                    groupTree.Add(new { id = host.ID, text = host.RoomNumber + "(" + host.RoomType.Name + ")", iconCls = "tree-node-no-icon", @checked = true, attributes = new { isHost = true, roomTypeID = host.RoomType.ID } });
                }
                else
                {
                    groupTree.Add(new { id = host.ID, text = host.RoomNumber + "(" + host.RoomType.Name + ")", iconCls = "tree-node-no-icon", attributes = new { isHost = true, roomTypeID = host.RoomType.ID } });
                }
            }
            return groupTree;
        }

        #endregion
    }
}
