using DeviceRepair.Models;
using DeviceRepair.Models.History;
using SqlSugar;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace DeviceRepair.DataAccess
{
    public class RoleAccess : DbContext<RoleModel>
    {
        private static RoleAccess manager;
        public static RoleAccess Instance
        {
            get
            {
                if (manager == null)
                    manager = new RoleAccess();
                return manager;
            }
        }

        /// <summary>
        /// 获取所有角色
        /// </summary>
        /// <returns></returns>
        public APIResponseData GetAllRole()
        {
            APIResponseData apiResponseData = new APIResponseData { Code = -1, Message = "没有查询到数据！" };
            try
            {
                db.ChangeDatabase("main");

                var Datas = base.GetList();
                apiResponseData.Code = 1;
                apiResponseData.Data = Datas;
                apiResponseData.Message = "";
            }
            catch (SqlSugarException ex)
            {
                apiResponseData.Code = -1;
                apiResponseData.Message = ex.Message;
            }
            catch (Exception ex)
            {
                apiResponseData.Code = -1;
                apiResponseData.Message = ex.Message;
            }
            return apiResponseData;
        }

        /// <summary>
        /// 获取全部权限数据
        /// </summary>
        /// <returns></returns>
        public APIResponseData GetAuthList()
        {
            APIResponseData apiResponseData = new APIResponseData { Code = -1, Message = "没有查询到数据！" };
            try
            {
                db.ChangeDatabase("main");

                var Datas = db.Queryable<AuthModel>().ToList();
                apiResponseData.Code = 1;
                apiResponseData.Data = Datas;
                apiResponseData.Message = "";
            }
            catch (SqlSugarException ex)
            {
                apiResponseData.Code = -1;
                apiResponseData.Message = ex.Message;
            }
            catch (Exception ex)
            {
                apiResponseData.Code = -1;
                apiResponseData.Message = ex.Message;
            }
            return apiResponseData;
        }

        /// <summary>
        /// 获取角色下的用户
        /// </summary>
        /// <param name="RoleID"></param>
        /// <returns></returns>
        public APIResponseData GetRoleUsers(int RoleID)
        {
            APIResponseData apiResponseData = new APIResponseData { Code = -1, Message = "没有查询到数据！" };
            try
            {
                db.ChangeDatabase("main");

                var Datas = db.Queryable<UserInfoModel>().Where(x => x.RoleGroup == RoleID).ToList();
                apiResponseData.Code = 1;
                apiResponseData.Data = Datas;
                apiResponseData.Message = "";
            }
            catch (SqlSugarException ex)
            {
                apiResponseData.Code = -1;
                apiResponseData.Message = ex.Message;
            }
            catch (Exception ex)
            {
                apiResponseData.Code = -1;
                apiResponseData.Message = ex.Message;
            }
            return apiResponseData;
        }

        /// <summary>
        /// 清空角色下的用户
        /// </summary>
        /// <param name="RoleAutoID"></param>
        /// <returns></returns>
        public APIResponseData ClearRoleUsers(int RoleID, HeaderModel Operation)
        {
            APIResponseData apiResponseData = new APIResponseData { Code = -1, Message = "没有查询到数据！" };
            try
            {
                db.ChangeDatabase("main");

                DateTime CurrentDate = DateTime.Now;
                if (RoleID == 0)
                {
                    apiResponseData.Message = "角色编码不能为0！";
                    return apiResponseData;
                }

                int Count = db.Updateable<UserInfoModel>()
                                .SetColumns(x => new UserInfoModel() { RoleGroup = 0, ModifyBy = Operation.Operator, ModifyDate = CurrentDate })
                                .Where(x => x.RoleGroup == RoleID).ExecuteCommand();

                if (Count <= 0)
                {
                    throw new Exception("操作出错,用户角色修改失败！");
                }

                apiResponseData.Code = 1;
                apiResponseData.Message = "操作成功！";
            }
            catch (SqlSugarException ex)
            {
                apiResponseData.Code = -1;
                apiResponseData.Message = ex.Message;
            }
            catch (Exception ex)
            {
                apiResponseData.Code = -1;
                apiResponseData.Message = ex.Message;
            }
            return apiResponseData;
        }

        /// <summary>
        /// 清空角色下的权限
        /// </summary>
        /// <param name="RoleID"></param>
        /// <param name="Operation"></param>
        /// <returns></returns>
        public APIResponseData ClearRoleAuths(int RoleID, HeaderModel Operation)
        {
            APIResponseData apiResponseData = new APIResponseData { Code = -1, Message = "没有查询到数据！" };
            try
            {
                db.ChangeDatabase("main");

                DateTime CurrentDate = DateTime.Now;
                if (RoleID == 0)
                {
                    apiResponseData.Message = "角色编码不能为0！";
                    return apiResponseData;
                }

                int Count = db.Deleteable<RoleAuthModel>().Where(x => x.RoleID == RoleID).ExecuteCommand();

                if (Count <= 0)
                {
                    throw new Exception("操作出错,用户角色修改失败！");
                }

                apiResponseData.Code = 1;
                apiResponseData.Message = "操作成功！";
            }
            catch (SqlSugarException ex)
            {
                apiResponseData.Code = -1;
                apiResponseData.Message = ex.Message;
            }
            catch (Exception ex)
            {
                apiResponseData.Code = -1;
                apiResponseData.Message = ex.Message;
            }
            return apiResponseData;
        }

        /// <summary>
        /// 判断当前角色编码是否存在
        /// </summary>
        /// <param name="RoleCode"></param>
        /// <returns></returns>
        public APIResponseData CheckRoleCodeExists(string RoleCode)
        {
            APIResponseData apiResponseData = new APIResponseData { Code = -1, Message = "没有查询到数据！" };
            try
            {
                db.ChangeDatabase("main");

                var Datas = db.Queryable<RoleModel>().Any(x => x.RoleCode.Equals(RoleCode, StringComparison.CurrentCultureIgnoreCase));
                apiResponseData.Code = 1;
                apiResponseData.Data = Datas;
                apiResponseData.Message = "";
            }
            catch (SqlSugarException ex)
            {
                apiResponseData.Code = -1;
                apiResponseData.Message = ex.Message;
            }
            catch (Exception ex)
            {
                apiResponseData.Code = -1;
                apiResponseData.Message = ex.Message;
            }
            return apiResponseData;
        }

        /// <summary>
        /// 根据角色ID,权限状态 获取权限列表
        /// </summary>
        /// <param name="RoleID"></param>
        /// <param name="Status"></param>
        /// <returns></returns>
        public APIResponseData GetRoleAuths(int RoleID, bool Status)
        {
            APIResponseData apiResponseData = new APIResponseData { Code = -1, Message = "没有查询到数据！" };
            try
            {
                db.ChangeDatabase("main");

                var Datas = db.Queryable<AuthModel, RoleAuthModel>((au, ra) => new object[] {
                        JoinType.Inner,au.AutoID == ra.AuthID
                    }).Where((au, ra) => ra.RoleID == RoleID && ra.Status == Status)
                    .Select<AuthModel>().ToList();

                apiResponseData.Code = 1;
                apiResponseData.Data = Datas;
                apiResponseData.Message = "";
            }
            catch (SqlSugarException ex)
            {
                apiResponseData.Code = -1;
                apiResponseData.Message = ex.Message;
            }
            catch (Exception ex)
            {
                apiResponseData.Code = -1;
                apiResponseData.Message = ex.Message;
            }
            return apiResponseData;
        }

        /// <summary>
        /// 修改
        /// </summary>
        /// <param name="item"></param>
        /// <returns></returns>
        public APIResponseData Update(RoleModel item, HeaderModel Operation)
        {
            APIResponseData apiResponseData = new APIResponseData { Code = -1, Message = "没有查询到数据！" };
            try
            {
                db.ChangeDatabase("main");

                RoleModel Datas = db.Queryable<RoleModel>().First(x => x.AutoID == item.AutoID && x.RoleStatus == x.RoleStatus);
                if (Datas == null)
                {
                    throw new Exception($"找不到ID为{item.AutoID}的角色！");
                }

                DateTime CurrentDate = DateTime.Now;
                string OperationType = Datas.RoleStatus != item.RoleStatus ? (item.RoleStatus ? "解锁" : "锁定") : "修改";

                Datas.ModifyBy = Operation.Operator;
                Datas.ModifyOn = CurrentDate;
                Datas.RoleCode = item.RoleCode;
                Datas.RoleDescription = item.RoleDescription;
                Datas.RoleName = item.RoleName;
                Datas.RoleNote = item.RoleNote;
                Datas.RoleStatus = item.RoleStatus;

                if (db.Updateable(Datas).ExecuteCommand() > 0)
                {
                    apiResponseData.Code = 1;
                    apiResponseData.Data = Datas;
                    apiResponseData.Message = "";

                    db.ChangeDatabase("log");
                    db.Insertable(new RoleInfoChangeLogInfo
                    {
                        RoleAutoID = Datas.AutoID,
                        Description = Datas.RoleDescription,
                        OperationComputer = Operation.ClientName,
                        OperationContent = "",
                        OperationDate = CurrentDate,
                        OperationIP = Operation.IPAddress,
                        OperationType = OperationType,
                        OperationUser = Operation.Operator,
                        OperationUserName = Operation.OperatorName,
                        RoleCode = Datas.RoleCode,
                        RoleName = Datas.RoleName
                    }).ExecuteCommand();
                }
            }
            catch (SqlSugarException ex)
            {
                apiResponseData.Code = -1;
                apiResponseData.Message = ex.Message;
            }
            catch (Exception ex)
            {
                apiResponseData.Code = -1;
                apiResponseData.Message = ex.Message;
            }
            return apiResponseData;
        }

        /// <summary>
        /// 根据主键编号是插入/更新
        /// </summary>
        /// <param name="entity"></param>
        /// <returns></returns>
        public APIResponseData InsertOrEdit(RoleEditSubmitModel entity, HeaderModel Operation)
        {
            APIResponseData apiResponseData = new APIResponseData { Code = -1 };
            try
            {

                DateTime CurrentDate = DateTime.Now;
                if (entity.Role.AutoID == 0)
                {
                    if (db.Queryable<RoleModel>().Any(x => x.RoleCode == entity.Role.RoleCode))
                    {
                        apiResponseData.Message = "角色编码已存在！";
                        return apiResponseData;
                    }
                    entity.Role.CreateOn = CurrentDate;
                    entity.Role.CreateBy = Operation.Operator;
                }
                entity.Role.ModifyOn = CurrentDate;
                entity.Role.ModifyBy = Operation.Operator;

                db.ChangeDatabase("main");
                db.BeginTran();

                // 更新或新增 角色数据
                RoleModel model = db.Saveable(entity.Role).ExecuteReturnEntity();

                #region 角色权限处理

                // 角色权限处理
                List<RoleAuthLogInfo> logs = new List<RoleAuthLogInfo>();
                if (entity.RoleAuths != null && entity.RoleAuths.Count > 0)
                {
                    foreach (RoleAuthModel item in entity.RoleAuths)
                    {
                        item.RoleID = model.AutoID;
                        item.CreateOn = CurrentDate;
                        item.CreateBy = Operation.Operator;
                    }

                    // 当前选中权限Ids
                    int[] ids = entity.RoleAuths.Select(x => x.AuthID).ToArray();

                    //修改数据,删除后插入
                    if (entity.Role.AutoID != 0)
                    {
                        // 待删除的ids
                        var Dels = db.Queryable<RoleAuthModel>().Where(x => x.RoleID == entity.Role.AutoID && !SqlFunc.ContainsArray(ids, x.AuthID)).ToList();

                        foreach (RoleAuthModel item in Dels)
                        {
                            logs.Add(new RoleAuthLogInfo
                            {
                                RoleAutoID = item.RoleID,
                                AuthAutoID = item.AuthID,
                                OperationContent = "",
                                OperationUser = Operation.Operator,
                                OperationUserName = Operation.OperatorName,
                                OperationComputer = Operation.ClientName,
                                OperationIP = Operation.IPAddress,
                                OperationType = "删除"
                            });
                        }

                        // 删除权限
                        db.Deleteable(Dels).ExecuteCommand();
                    }

                    // 排除已存在项目
                    int[] none = db.Queryable<RoleAuthModel>().Where(x => x.RoleID == entity.Role.AutoID && SqlFunc.ContainsArray(ids, x.AuthID)).Select(x => x.AuthID).ToArray();
                    entity.RoleAuths.RemoveAll(x => none.Contains(x.AuthID));

                    //直接插入
                    if (entity.RoleAuths.Count > 0)
                    {
                        int Count = db.Insertable(entity.RoleAuths).ExecuteCommand();
                        if (Count <= 0)
                        {
                            throw new Exception("操作出错,角色权限插入失败！");
                        }
                    }

                    foreach (RoleAuthModel item in entity.RoleAuths)
                    {
                        logs.Add(new RoleAuthLogInfo
                        {
                            RoleAutoID = item.RoleID,
                            AuthAutoID = item.AuthID,
                            OperationContent = "",
                            OperationUser = Operation.Operator,
                            OperationUserName = Operation.OperatorName,
                            OperationComputer = Operation.ClientName,
                            OperationIP = Operation.IPAddress,
                            OperationType = "新增"
                        });
                    }
                }

                #endregion

                #region 角色用户处理

                List<UserRoleLogInfo> ulogs = new List<UserRoleLogInfo>();
                if (entity.Users != null && entity.Users.Count > 0)
                {
                    foreach (UserInfoModel item in entity.Users)
                    {
                        item.RoleGroup = model.AutoID;
                        item.ModifyDate = CurrentDate;
                        item.ModifyBy = Operation.Operator;
                    }

                    int[] uids = entity.Users.Select(x => x.AutoID).ToArray();

                    //修改数据,删除后插入
                    if (entity.Role.AutoID != 0)
                    {
                        // 待删除的ids
                        var Dels = db.Queryable<UserInfoModel>().Where(x => x.RoleGroup == model.AutoID && !SqlFunc.ContainsArray(uids, x.AutoID)).ToList();


                        foreach (var item in Dels)
                        {
                            ulogs.Add(new UserRoleLogInfo
                            {
                                UserAutoID = item.AutoID,
                                RoleAutoID = item.RoleGroup,
                                RoleCode = entity.Role.RoleCode,
                                RoleName = entity.Role.RoleName,
                                UserCode = item.LoginCode,
                                UserName = item.RealName,
                                Description = item.Description,
                                OperationContent = "权限删除",
                                OperationUser = Operation.Operator,
                                OperationUserName = Operation.OperatorName,
                                OperationComputer = Operation.ClientName,
                                OperationIP = Operation.IPAddress,
                                OperationType = "删除"
                            });
                        }


                        // 删除权限
                        //db.Deleteable(Dels).ExecuteCommand();

                        int[] ids = Dels.Select(x => x.AutoID).ToArray();
                        db.Updateable<UserInfoModel>()
                           .SetColumns(x => new UserInfoModel() { RoleGroup = 0, ModifyBy = entity.Users[0].ModifyBy, ModifyDate = CurrentDate })
                           .Where(x => SqlFunc.ContainsArray(ids, x.AutoID)).ExecuteCommand();
                    }

                    // 排除已存在项目
                    int[] none = db.Queryable<UserInfoModel>().Where(x => x.RoleGroup == model.AutoID && SqlFunc.ContainsArray(uids, x.AutoID)).Select(x => x.AutoID).ToArray();
                    entity.Users.RemoveAll(x => none.Contains(x.AutoID));

                    if (entity.Users.Count > 0)
                    {
                        //直接插入
                        int Count = db.Updateable(entity.Users).UpdateColumns(s => new { s.RoleGroup, s.ModifyBy, s.ModifyDate }).WhereColumns(it => new { it.AutoID }).ExecuteCommand();
                        if (Count <= 0)
                        {
                            throw new Exception("操作出错,用户角色修改失败！");
                        }

                        int[] addIds = entity.Users.Select(x => x.AutoID).ToArray();

                       var Users =  db.Queryable<UserInfoModel>().Where(x => SqlFunc.ContainsArray(addIds, x.AutoID)).ToList();

                        foreach (UserInfoModel item in Users)
                        {
                            item.ModifyBy = Operation.Operator;

                            ulogs.Add(new UserRoleLogInfo
                            {
                                UserAutoID = item.AutoID,
                                RoleAutoID = item.RoleGroup,
                                RoleCode = entity.Role.RoleCode,
                                RoleName = entity.Role.RoleName,
                                UserCode = item.LoginCode,
                                UserName = item.RealName,
                                Description = item.Description,
                                OperationContent = "权限删除",
                                OperationUser = Operation.Operator,
                                OperationUserName = Operation.OperatorName,
                                OperationComputer = Operation.ClientName,
                                OperationIP = Operation.IPAddress,
                                OperationType = "删除"
                            });
                        }
                    }

                    #endregion
                }

                db.CommitTran();
                apiResponseData.Code = 1;
                apiResponseData.Message = "操作成功！";

                db.ChangeDatabase("log");
                db.Insertable(logs).ExecuteCommand();
                db.Insertable(ulogs).ExecuteCommand();
            }
            catch (SqlSugarException ex)
            {
                db.RollbackTran();
                apiResponseData.Code = -1;
                apiResponseData.Message = ex.Message;
            }
            catch (Exception ex)
            {
                db.RollbackTran();
                apiResponseData.Code = -1;
                apiResponseData.Message = ex.Message;
            }
            return apiResponseData;
        }
    }
}
