using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Windows.Forms;
using DevExpress.XtraBars.ToolbarForm;
using DevExpress.XtraTreeList.Nodes;
using DeviceRepair.Models;
using DeviceRepairAndOptimization.Common;
using DeviceRepairAndOptimization.Biz;

namespace DeviceRepairAndOptimization.Pages.Users
{
    public partial class frmRoleAuths : ToolbarForm
    {
        private RoleModel CurrentRole = null;

        public frmRoleAuths(RoleModel currentRole)
        {
            InitializeComponent();
            CurrentRole = currentRole;
            this.Load += FrmRoleAuths_Load;
        }

        private void FrmRoleAuths_Load(object sender, EventArgs e)
        {
            tvAuths.BeforeCheckNode += TvAuths_BeforeCheckNode;
            tvAuths.AfterCheckNode += TvAuths_AfterCheckNode;
            splashScreenManager1.ShowWaitForm();

            APIResponseData apiResponseData = RoleManger.Instance.GetAuthList();
            if (!apiResponseData.IsSuccess)
            {
                splashScreenManager1.CloseWaitForm();
                XtraMessageBoxHelper.Error(apiResponseData.Message);
                return;
            }
            var lst = apiResponseData.ToDeserializeObject<List<AuthModel>>();

            tvAuths.DataSource = lst;
            tvAuths.KeyFieldName = "AuthCode";
            tvAuths.ParentFieldName = "FatherAuthCode";
            tvAuths.ExpandAll();

            if (CurrentRole != null)
            {
                txtRoleCode.Tag = CurrentRole.AutoID;
                txtRoleCode.Text = CurrentRole.RoleCode;
                txtRoleName.Text = CurrentRole.RoleName;
                txtRoleDesc.Text = CurrentRole.RoleDescription;
                txtNote.Text = CurrentRole.RoleNote;
                SelectCurrentRoleAuths();
            }

            splashScreenManager1.TryCloseWait();
        }

        private void SelectCurrentRoleAuths()
        {
            APIResponseData apiResponseData = RoleManger.Instance.GetRoleAuths(CurrentRole.AutoID, CurrentRole.RoleStatus);
            if (apiResponseData.Code == 1)
            {
                List<AuthModel> lst = apiResponseData.ToDeserializeObject<List<AuthModel>>();

                if (lst.Count > 0)
                {
                    SelectTreeviewAuths(tvAuths.Nodes, lst);
                }
            }
        }

        private void SelectTreeviewAuths(TreeListNodes tvds, List<AuthModel> auths)
        {
            foreach (TreeListNode item in tvds)
            {
                var drv = tvAuths.GetDataRecordByNode(item) as AuthModel;
                if (drv != null)
                {
                    int authID = drv.AutoID;
                    if (auths.Exists((A) => { return A.AutoID == authID; }))
                    {
                        item.Checked = true;
                    }
                    else
                    {
                        item.Checked = false;
                    }
                }
                else
                {
                    item.Checked = false;
                }
                if (item.HasChildren)
                {
                    item.CheckState = CheckState.Indeterminate;
                    SelectTreeviewAuths(item.Nodes, auths);

                    var vFindUnChecked = item.Nodes.Where(A =>
                    {
                        return A.CheckState == CheckState.Unchecked;
                    });
                    if (vFindUnChecked != null)
                    {
                        if (vFindUnChecked.Count() == 0)
                        {
                            item.CheckState = CheckState.Checked;
                        }
                        else
                        {
                            if (vFindUnChecked.Count() == item.Nodes.Count)
                            {
                                item.CheckState = CheckState.Unchecked;
                            }
                            else
                            {
                                item.CheckState = CheckState.Indeterminate;
                            }
                        }
                    }
                    else
                    {
                        item.CheckState = CheckState.Checked;
                    }
                }
            }
        }

        private void TvAuths_BeforeCheckNode(object sender, DevExpress.XtraTreeList.CheckNodeEventArgs e)
        {
            e.State = (e.PrevState == CheckState.Checked ? CheckState.Unchecked : CheckState.Checked);
        }

        private void TvAuths_AfterCheckNode(object sender, DevExpress.XtraTreeList.NodeEventArgs e)
        {
            SetCheckedChildNodes(e.Node, e.Node.CheckState);
            SetCheckedParentNodes(e.Node, e.Node.CheckState);
        }


        /// <summary>
        /// 保存
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void bBtnSave_ItemClick(object sender, DevExpress.XtraBars.ItemClickEventArgs e)
        {
            splashScreenManager1.ShowWaitForm();
            try
            {
                RoleEditSubmitModel submitModel = new RoleEditSubmitModel();
                submitModel.Role = CurrentRole;

                // 权限列表选中项
                authLst.Clear();
                if (tvAuths.Nodes.Count > 0)
                {
                    foreach (TreeListNode root in tvAuths.Nodes)
                    {
                        GetCheckedAuthorizatioId(root);
                    }
                }
                if (authLst.Count > 0)
                {
                    foreach (int item in authLst)
                    {
                        submitModel.RoleAuths.Add(new RoleAuthModel
                        {
                            AuthID = item,
                            CreateBy = GlobalInfo.CurrentUser.AutoID,
                            RoleID = CurrentRole.AutoID,
                            Status = true,
                        });
                    }

                    APIResponseData apiResponseData = RoleManger.Instance.InsertOrEdit(submitModel);
                    if (apiResponseData.Code != 1)
                    {
                        throw new Exception(apiResponseData.Message);
                    }
                }
                else
                {
                    splashScreenManager1.TryCloseWait();

                    DialogResult AskResult = XtraMessageBoxHelper.Ask($"没有选择任何权限，是否清空角色 {CurrentRole.RoleName} 下的所有权限？");

                    if (AskResult == DialogResult.OK)
                    {
                        splashScreenManager1.ShowWaitForm();
                        //清空角色下的所有权限
                        APIResponseData apiResponseData = RoleManger.Instance.ClearRoleAuths(CurrentRole.AutoID);
                        if (!apiResponseData.IsSuccess)
                            throw new Exception(apiResponseData.Message);
                    }
                    else
                    {
                        splashScreenManager1.TryCloseWait();
                        return;
                    }
                }

                splashScreenManager1.TryCloseWait();
                this.DialogResult = DialogResult.OK;
            }
            catch (Exception ex)
            {
                splashScreenManager1.TryCloseWait();
                XtraMessageBoxHelper.Error(ex.Message);
            }
        }

        /// <summary>
        /// 设置子节点的状态
        /// </summary>
        /// <param name="node"></param>
        /// <param name="check"></param>
        private void SetCheckedChildNodes(TreeListNode node, CheckState check)
        {
            for (int i = 0; i < node.Nodes.Count; i++)
            {
                node.Nodes[i].CheckState = check;
                SetCheckedChildNodes(node.Nodes[i], check);
            }
        }

        /// <summary>
        /// 设置父节点的状态
        /// </summary>
        /// <param name="node"></param>
        /// <param name="check"></param>
        private void SetCheckedParentNodes(TreeListNode node, CheckState check)
        {
            if (node.ParentNode != null)
            {
                bool bCheck = false;
                CheckState state;
                for (int i = 0; i < node.ParentNode.Nodes.Count; i++)
                {
                    state = node.ParentNode.Nodes[i].CheckState;
                    if (!check.Equals(state))
                    {
                        bCheck = !bCheck;
                        break;
                    }
                }
                node.ParentNode.CheckState = bCheck ? CheckState.Indeterminate : check;
                SetCheckedParentNodes(node.ParentNode, check);
            }
        }

        private List<int> authLst = new List<int>();//所选择的权限的ID集合
        private void GetCheckedAuthorizatioId(TreeListNode parentNode)
        {
            if (parentNode.Nodes.Count == 0)
            {
                return;//递归终止
            }
            foreach (TreeListNode node in parentNode.Nodes)
            {
                if (node.CheckState == CheckState.Checked || node.CheckState == CheckState.Indeterminate)
                {
                    var drv = tvAuths.GetDataRecordByNode(node) as AuthModel;
                    if (drv != null)
                    {
                        authLst.Add(drv.AutoID);
                    }
                }
                GetCheckedAuthorizatioId(node);
            }
        }
    }
}
