using Sugar.Enties;
using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Linq.Expressions;

namespace WebAPIBase.NetCore.BusinessCore
{
    public sealed class AccessRanggeQuery : DbContext<SystemUser>
    {
        private static NLog.Logger logger = NLog.LogManager.GetCurrentClassLogger();
        public string BuildAccessRangeString(string usercode, string operationCode, string classname)
        {
            SystemClassItem systemClassItem = SystemClassDescription.GetSystemClassItem(classname);
            return BuildAccessRangeString(usercode, operationCode, systemClassItem.TableName, systemClassItem.KeyColumnName, systemClassItem.TypeColumnName, systemClassItem.CreateUserColumnName, systemClassItem.UnitColumnName, systemClassItem.ProjectColumnName);
        }

        public string BuildAccessRangeString(string usercode, string operationCode, string tableName, string keyColumnName, string typeColumnName, string createUserColumnName, string UnitColumnName, string ProjectColumnName)
        {
            return BuildAccessTypeString(usercode, operationCode, tableName, keyColumnName, typeColumnName, createUserColumnName, UnitColumnName, ProjectColumnName);
        }

        private string BuildAccessTypeString(string usercode, string operationCode, string tableName, string keyColumnName, string typeColumnName, string createUserColumnName, string UnitColumnName, string ProjectColumnName)
        {
            string text = "";
            FdcUser fdcUser = new FdcUser(usercode);
            bool flag = false;
            if (typeColumnName != "")
            {
                List<FdcGroupUnitRight> groupUnitRight = fdcUser.GetGroupUnitRight(operationCode);
                if (groupUnitRight.Count > 0)
                {
                    flag = true;
                }
                foreach (FdcGroupUnitRight item in groupUnitRight)
                {
                    if (item.IsPerson == 1)
                    {
                        if (createUserColumnName != "")
                        {
                            if (UnitColumnName != "")
                            {
                                text += string.Format(" or (dbo.GetSystemGroupFullID({0}.{1}) like '{2}%' and dbo.GetUnitFullCode({0}.{3}) like ('{4}%') and {0}.{5}='{6}')", tableName, typeColumnName, item.group.FullId, UnitColumnName, item.unit.FullCode, createUserColumnName, usercode);
                            }
                            else if (ProjectColumnName != "")
                            {
                                string projectCodesByParentUnit = GetProjectCodesByParentUnit(item.unit.UnitCode);
                                if (projectCodesByParentUnit != string.Empty)
                                {
                                    text += string.Format(" or (dbo.GetSystemGroupFullID({0}.{1}) like '{2}%' and {0}.{3} in ({4}) and {0}.{5}='{6}')", tableName, typeColumnName, item.group.FullId, ProjectColumnName, projectCodesByParentUnit, createUserColumnName, usercode);
                                }
                            }
                            else
                            {
                                text += string.Format(" or (dbo.GetSystemGroupFullID({0}.{1}) like '{2}%' and {0}.{3}='{4}')", tableName, typeColumnName, item.group.FullId, createUserColumnName, usercode);
                            }
                        }
                        else
                        {
                            text += string.Format(" or dbo.GetSystemGroupFullID({0}.{1}) like '{2}%'", tableName, typeColumnName, item.group.FullId, createUserColumnName, usercode);
                        }
                    }
                    else if (UnitColumnName != "")
                    {
                        text += string.Format(" or (dbo.GetSystemGroupFullID({0}.{1}) like '{2}%' and dbo.GetUnitFullCode({0}.{3}) like ('{4}%'))", tableName, typeColumnName, item.group.FullId, UnitColumnName, item.unit.FullCode);
                    }
                    else if (ProjectColumnName != "")
                    {
                        string projectCodesByParentUnit2 = GetProjectCodesByParentUnit(item.unit.UnitCode);
                        if (projectCodesByParentUnit2 != string.Empty)
                        {
                            text += string.Format(" or (dbo.GetSystemGroupFullID({0}.{1}) like '{2}%' and {0}.{3} in ({4}))", tableName, typeColumnName, item.group.FullId, ProjectColumnName, projectCodesByParentUnit2);
                        }
                    }
                    else
                    {
                        text += string.Format(" or dbo.GetSystemGroupFullID({0}.{1}) like '{2}%'", tableName, typeColumnName, item.group.FullId, UnitColumnName, item.unit.FullCode);
                    }
                }
            }
            else if (UnitColumnName != "" || ProjectColumnName != "")
            {
                List<FdcUnitRight> unitRight = fdcUser.GetUnitRight(operationCode);
                if (unitRight.Count > 0)
                {
                    flag = true;
                }
                foreach (FdcUnitRight item2 in unitRight)
                {
                    if (item2.IsPerson == 1)
                    {
                        if (!(createUserColumnName != ""))
                        {
                            continue;
                        }
                        if (UnitColumnName != "")
                        {
                            text += string.Format(" or dbo.GetUnitFullCode({0}.{1}) like ('{2}%') and {0}.{3}='{4}'", tableName, UnitColumnName, item2.unit.FullCode, createUserColumnName, usercode);
                        }
                        else if (ProjectColumnName != "")
                        {
                            string projectCodesByParentUnit3 = GetProjectCodesByParentUnit(item2.unit.UnitCode);
                            if (projectCodesByParentUnit3 != string.Empty)
                            {
                                text += string.Format(" or {0}.{1} in ({2}) and {0}.{3}='{4}'", tableName, ProjectColumnName, projectCodesByParentUnit3, createUserColumnName, usercode);
                            }
                        }
                        else
                        {
                            text += $" or {tableName}.{createUserColumnName}='{usercode}'";
                        }
                    }
                    else if (UnitColumnName != "")
                    {
                        text += $" or dbo.GetUnitFullCode({tableName}.{UnitColumnName}) like ('{item2.unit.FullCode}%')";
                    }
                    else
                    {
                        string projectCodesByParentUnit4 = GetProjectCodesByParentUnit(item2.unit.UnitCode);
                        if (projectCodesByParentUnit4 != string.Empty)
                        {
                            text += $" or {tableName}.{ProjectColumnName} in ({projectCodesByParentUnit4})";
                        }
                    }
                }
            }
            else if (createUserColumnName != "")
            {
                flag = true;
                text += $" or {tableName}.{createUserColumnName}='{usercode}'";
            }
            if (text != "")
            {
                text = text.Substring(4, text.Length - 4);
            }
            if (flag && text != "")
            {
                return $"({text})";
            }
            return "(1=2)";
        }

        private string GetProjectCodesByParentUnit(string unitCode)
        {
            string text = string.Empty;
            try
            {
                string format = "select unitcode from Unit u where exists(select * from project where projectcode=u.unitcode) or exists(select * from saproject where pid=u.unitcode) and FullCode like '%{0}%' and UnitType='项目'";
                format = string.Format(format, unitCode);
                var dt = Db.Ado.GetDataTable(format);

                foreach (DataRow row in dt.Rows)
                {
                    text += string.Format("'{0}',", row["unitcode"].ToString().Replace("'", "''"));
                }

                if (text != string.Empty)
                {
                    text = text.Remove(text.Length - 1);
                    text = "'All',''," + text;
                }

            }
            catch (Exception exp)
            {
                text = string.Empty;
                logger.Error(exp);
                throw;
            }
            return text;
        }

        private string GetUnitCodesByUser(string UserCode)
        {
            string text = "";
            DataTable dataTable = new DataTable();
            dataTable.Columns.Add("UnitCode");

            string queryString = string.Format("select s.UnitCode from userrole ur, station s where ur.StationCode = s.StationCode and ur.UserCode = '{0}'", UserCode.Replace("'", "''"));
            var dt = Db.Ado.GetDataTable(queryString);
            foreach (DataRow row in dt.Rows)
            {
                EntityData unitAllChildAndSelf = GetUnitAllChildAndSelf(row["UnitCode"].ToString());
                foreach (DataRow row2 in unitAllChildAndSelf.CurrentTable.Rows)
                {
                    if (dataTable.Select("UnitCode = '" + row2["UnitCode"].ToString() + "'").Length == 0)
                    {
                        DataRow dataRow3 = dataTable.NewRow();
                        dataRow3["UnitCode"] = row2["UnitCode"].ToString();
                        dataTable.Rows.Add(dataRow3);
                    }
                }

            }

            foreach (DataRow row3 in dataTable.Rows)
            {
                if (text != "")
                {
                    text += ",";
                }
                text = text + "'" + row3["UnitCode"].ToString() + "'";
            }
            return text;
        }


        public EntityData GetUnitAllChildAndSelf(string parentCode)
        {
            try
            {
                string text = "";
                EntityData unitByCode = GetUnitByCode(parentCode);
                text = ((!unitByCode.HasRecord()) ? "null" : unitByCode.GetString("FullCode"));
                unitByCode.Dispose();
                UnitStrategyBuilder unitStrategyBuilder = new UnitStrategyBuilder();
                unitStrategyBuilder.AddStrategy(new Strategy(UnitStrategyName.UnderUnitCode, text));
                string str = unitStrategyBuilder.BuildQueryChildCountString();
                str += unitStrategyBuilder.GetDefaultOrder();
                logger.Info($"【GetUnitAllChildAndSelf】sql:{str}");
                var result = Db.Ado.GetDataSetAll(str);


                return (EntityData)result;
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

        public EntityData GetUnitByCode(string code)
        {
            try
            {

                return SelectbyPrimaryKey(code, "Unit");

            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

        public EntityData SelectbyPrimaryKey(object keyvalues, string entityName)
        {
            try
            {
                EntityData entitydata = null;

                SqlStruct sqlStruct = SqlManager.GetSqlStruct(entityName, "Select");
                if (sqlStruct.SqlString.Length != 0)
                {
                    if (1 != sqlStruct.ParamsList.Length)
                        throw new ApplicationException("参数列表不匹配");
                    entitydata = (EntityData)Db.Ado.GetDataSetAll(sqlStruct.SqlString, sqlStruct.ParamsList);


                }
                return entitydata;
            }
            catch (Exception ex)
            {

                throw ex;
            }
        }

        public static string BuildStationCodeString(string stationCodes)
        {
            string text = "";
            string[] array = stationCodes.Split(',');
            foreach (string str in array)
            {
                if (text != "")
                {
                    text += ",";
                }
                text = text + "'" + str + "'";
            }
            return text;
        }

        public string BuildContractAccessRangeString(string userCode, string systemgroupcodes)
        {
            return BuildAccessRangeString(userCode, systemgroupcodes, "Contract");
        }
    }

}
