namespace Tiobon.Core.Services;

/// <summary>
/// 岗位 (服务)
/// </summary>
public class Ghra_TitleServices : BaseServices<Ghra_Title, Ghra_TitleDto, InsertGhra_TitleInput, EditGhra_TitleInput>, IGhra_TitleServices
{
    private readonly IBaseRepository<Ghra_Title> _dal;
    private readonly ICommonServices _commonServices;
    public Ghra_TitleServices(ICaching caching, IBaseRepository<Ghra_Title> dal, ICommonServices commonServices)
    {
        this._dal = dal;
        base.BaseDal = dal;
        base._caching = caching;
        _commonServices = commonServices;
    }

    public override async Task<Ghra_TitleDto> QueryById(object objId)
    {
        var entity = await base.QueryById(objId);

        return entity;
    }


    public async Task<dynamic> QuerySkillMatrix(QueryBody filter)
    {

        dynamic obj = new ExpandoObject();
        dynamic result = new ExpandoObject();
        var ruleSrc = Db.Queryable<Ghre_StudyRule>().Where($"dbo.FUserDataBelongPriv ({App.User.ID}, DataBelongID, NULL) = 1");
        if (string.IsNullOrWhiteSpace(filter.orderBy))
            filter.orderBy = "Type ASC";
        string sql = $"SELECT *\r\nFROM Ghre_CourseScene_V\r\nWHERE IsEnable = 1 AND dbo.FUserDataBelongPriv ({App.User.ID}, DataBelongID, NULL) = 1 ";
        var rules1 = await ruleSrc.Where(x => x.RuleType == "Required" && x.TrainType == "Title").ToListAsync();
        var rules = Mapper.Map(rules1).ToANew<List<Ghre_StudyRuleDto>>();

        rules.ForEach(x =>
        {
            if (x.ZoneId.IsNotEmptyOrNull())
                x.ZoneIds = JsonHelper.JsonToObj<List<int?>>(x.ZoneId);
            if (x.DeptId.IsNotEmptyOrNull())
                x.DeptIds = JsonHelper.JsonToObj<List<int?>>(x.DeptId);

            if (x.TitleId.IsNotEmptyOrNull())
                x.TitleIds = JsonHelper.JsonToObj<List<int?>>(x.TitleId);

            if (x.JobId.IsNotEmptyOrNull())
                x.JobIds = JsonHelper.JsonToObj<List<int?>>(x.JobId);

            if (x.GradeId.IsNotEmptyOrNull())
                x.GradeIds = JsonHelper.JsonToObj<List<int?>>(x.GradeId);
        });
        var titles = await Db.Queryable<Ghra_Title>().Where($"dbo.FUserDataBelongPriv ({App.User.ID}, DataBelongID, NULL) = 1").OrderBy(x => x.SortNo).ToListAsync();

        #region 处理查询条件
        //Expression<Func<Ghrh_Resume, bool>> whereExpression = new Expression<Func<Ghrh_Resume, bool>>();
        var whereExpression = Expressionable.Create<Ghrh_Resume>();
        foreach (JProperty jProperty in filter.jsonParam.Properties())
        {
            var name = jProperty.Name;
            var value = jProperty.Value.ToString();
            if (name == "page" || name == "pageSize")
                continue;
            if (value.IsNotEmptyOrNull())
            {
                var jsonParam = JsonHelper.JsonToObj<JsonParam>(value);

                switch (name)
                {

                    case "ZoneId":
                        switch (jsonParam.operationKey)
                        {
                            case "Include":
                                if (jsonParam.columnValue != null)
                                    rules = rules.Where(x => x.ZoneIds.Contains(jsonParam.columnValue.ObjToInt())).ToList();
                                break;
                            case "NotInclude":
                                if (jsonParam.columnValue != null)
                                    rules = rules.Where(x => !x.ZoneIds.Contains(jsonParam.columnValue.ObjToInt())).ToList();
                                break;
                            case "IsNull":
                                rules = rules.Where(x => x.ZoneIds.Count == 0).ToList();
                                break;
                            case "NotNull":
                                rules = rules.Where(x => x.ZoneIds.Count > 0).ToList();
                                break;
                            default:
                                break;
                        }
                        break;
                    case "DeptId":
                        switch (jsonParam.operationKey)
                        {
                            case "Include":
                                if (jsonParam.columnValue != null)
                                    rules = rules.Where(x => x.DeptIds.Contains(jsonParam.columnValue.ObjToInt())).ToList();
                                break;
                            case "NotInclude":
                                if (jsonParam.columnValue != null)
                                    rules = rules.Where(x => !x.DeptIds.Contains(jsonParam.columnValue.ObjToInt())).ToList();
                                break;
                            case "IsNull":
                                rules = rules.Where(x => x.DeptIds.Count == 0).ToList();
                                break;
                            case "NotNull":
                                rules = rules.Where(x => x.DeptIds.Count > 0).ToList();
                                break;
                            default:
                                break;
                        }
                        break;
                    case "TitleId":
                        switch (jsonParam.operationKey)
                        {
                            case "Include":
                                if (jsonParam.columnValue != null)
                                    rules = rules.Where(x => x.TitleIds.Contains(jsonParam.columnValue.ObjToInt())).ToList();
                                titles = titles.Where(x => x.TitleID == jsonParam.columnValue.ObjToInt()).ToList();
                                break;
                            case "NotInclude":
                                if (jsonParam.columnValue != null)
                                    rules = rules.Where(x => !x.TitleIds.Contains(jsonParam.columnValue.ObjToInt())).ToList();
                                titles = titles.Where(x => x.TitleID != jsonParam.columnValue.ObjToInt()).ToList();
                                break;
                            case "IsNull":
                                rules = rules.Where(x => x.TitleIds.Count == 0).ToList();
                                break;
                            case "NotNull":
                                rules = rules.Where(x => x.TitleIds.Count > 0).ToList();
                                break;
                            default:
                                break;
                        }
                        break;
                    case "JobId":
                        switch (jsonParam.operationKey)
                        {
                            case "Include":
                                if (jsonParam.columnValue != null)
                                    rules = rules.Where(x => x.JobIds.Contains(jsonParam.columnValue.ObjToInt())).ToList();
                                break;
                            case "NotInclude":
                                if (jsonParam.columnValue != null)
                                    rules = rules.Where(x => !x.JobIds.Contains(jsonParam.columnValue.ObjToInt())).ToList();
                                break;
                            case "IsNull":
                                rules = rules.Where(x => x.JobIds.Count == 0).ToList();
                                break;
                            case "NotNull":
                                rules = rules.Where(x => x.JobIds.Count > 0).ToList();
                                break;
                            default:
                                break;
                        }
                        break;
                    case "GradeId":
                        switch (jsonParam.operationKey)
                        {
                            case "Include":
                                if (jsonParam.columnValue != null)
                                    rules = rules.Where(x => x.GradeIds.Contains(jsonParam.columnValue.ObjToInt())).ToList();
                                break;
                            case "NotInclude":
                                if (jsonParam.columnValue != null)
                                    rules = rules.Where(x => !x.GradeIds.Contains(jsonParam.columnValue.ObjToInt())).ToList();
                                break;
                            case "IsNull":
                                rules = rules.Where(x => x.GradeIds.Count == 0).ToList();
                                break;
                            case "NotNull":
                                rules = rules.Where(x => x.GradeIds.Count > 0).ToList();
                                break;
                            default:
                                break;
                        }
                        break;
                    case "CourseId":
                        switch (jsonParam.operationKey)
                        {
                            case "Equal":
                                if (jsonParam.columnValue != null)
                                    rules = rules.Where(x => x.CourseId == jsonParam.columnValue.ObjToLong()).ToList();
                                sql += $" AND Id={jsonParam.columnValue}";
                                break;
                            case "NotEqual":
                                if (jsonParam.columnValue != null)
                                    rules = rules.Where(x => x.CourseId != jsonParam.columnValue.ObjToLong()).ToList();
                                sql += $" AND Id !={jsonParam.columnValue}";

                                break;
                            case "EqualAny":// 
                                if (jsonParam.columnValue != null)
                                {
                                    var ids1 = JsonHelper.JsonToObj<List<string>>(jsonParam.columnValue.ToString());

                                    sql += $" AND  Id IN ({string.Join(",", ids1.Select(id => "'" + id + "'"))})";
                                }
                                break;
                            case "NotEqualAny":// 
                                if (jsonParam.columnValue != null)
                                {
                                    var ids1 = JsonHelper.JsonToObj<List<string>>(jsonParam.columnValue.ToString());

                                    sql += $" AND ( Id NOT IN ({string.Join(",", ids1.Select(id => "'" + id + "'"))}) OR {name} IS NULL)";
                                }
                                break;
                            default:
                                break;
                        }
                        break;

                    default:
                        break;
                }
            }
        }
        #endregion 


        if (filter.pageSize == 0)
            filter.pageSize = 10000;

        var sql1 = GetQueryString(sql, filter.pageNum, filter.pageSize, filter.orderBy);

        var totalCount = await Db.Ado.GetIntAsync("select count(0) from ( " + sql + ") A");
        var list = DbAccess.QueryList<TitleSkillMatrix>(sql);

        ModuleParam param = new ModuleParam()
        {
            langId = filter.langId,
            menuName = filter.menuName,
            jsonParam1 = filter.jsonParam
        };
        var module = await _commonServices.GetModuleInfoAsync(param);
        var result1 = new ServicePageResult<TitleSkillMatrix>(filter.pageNum, totalCount, filter.pageSize, list);
        result1.result.JM_TableColumnT1 = module.Data.JM_TableColumnT1;

        var columns = new JArray();


        var dict = new Dictionary<string, List<int>>();

        rules.ForEach(x =>
        {
            if (x.TitleId.IsNotEmptyOrNull())
            {

                var key = (x.CourseId ?? x.CourseSceneId).ObjToString();
                if (dict.ContainsKey(key))
                {
                    var ids = dict[key];

                    ids.AddRange(JsonHelper.JsonToObj<List<int>>(x.TitleId));
                    ids = ids.Distinct().ToList();
                    dict[key] = ids;
                }
                else
                {
                    dict.Add(key, JsonHelper.JsonToObj<List<int>>(x.TitleId));
                }
            }

        });

        for (int i = 0; i < list.Count; i++)
        {
            var column = list[i];

            var CourseName = column.CourseName;
            var CourseSceneName = column.CourseName;
            if (column.Type == "Course")
            {
                if (column.CourseSceneIds.IsNotEmptyOrNull())
                {
                    var courseSceneIds = JsonHelper.JsonToObj<List<long>>(column.CourseSceneIds);
                    var courseScene = await Db.Queryable<Ghre_CourseScene>().Where(x => courseSceneIds.Contains(x.Id)).ToListAsync();
                    CourseSceneName = string.Join(",", courseScene.Select(a => a.SceneName));
                }
                else
                    CourseSceneName = null;
            }
            else
            {
                CourseName = CourseSceneName;
                CourseSceneName = null;
            }

            var item = new JObject
            {
                new JProperty("Id", column.Id),
                new JProperty("CourseSceneName", CourseSceneName),
                new JProperty("CourseName", CourseName),
                new JProperty("Type", column.Type),
            };

            titles.ForEach(x =>
            {
                if (dict.ContainsKey(column.Id.ObjToString()))
                {
                    var ids = dict[column.Id.ObjToString()];
                    if (ids.Where(id => id == x.TitleID).Any())
                        item.Add(new JProperty("Title_" + x.TitleNo, "✔"));
                    else
                        item.Add(new JProperty("Title_" + x.TitleNo, ""));
                }
                else
                    item.Add(new JProperty("Title_" + x.TitleNo, ""));
            });

            columns.Add(item);
        }

        result.JM_TableColumnT1 = module.Data.JM_TableColumnT1;
        result.DT_TablePageInfoT1 = result1.result.DT_TablePageInfoT1;
        result.DT_TableDataT1 = columns;
        obj.result = result;
        obj.Success = true;
        obj.code = "0";
        obj.type = "success";
        obj.message = "查询成功！";
        return obj;
    }
}