using Infrastructure.Extensions;
using OpenAuth.App.Interface;
using OpenAuth.Repository.Domain;
using SqlSugar;
using StackExchange.Redis;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Runtime.CompilerServices;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;

namespace OpenAuth.App.BasicQueryService
{
    public class UserManager
    {
        ISqlSugarClient client;

        public UserManager(ISqlSugarClient sqlSugarClient)
        {
            client = sqlSugarClient;
        }

        /// <summary>
        /// x用户的部门集合
        /// </summary>
        /// <param name="userId"></param>
        /// <returns></returns>
        public ISugarQueryable<SysUserOrg, SysOrg> UserOrgs(long userId)
        {
            var query = client.Queryable<SysUserOrg>()
                 .LeftJoin<SysOrg>((u, o) => u.OrgId == o.Id)
                 .Where((u, o) => u.UserId == userId && o.Id != null);

            return query;
        }

        /// <summary>
        /// x用户的角色集合
        /// </summary>
        /// <param name="userId"></param>
        /// <returns></returns>
        public ISugarQueryable<SysUserRole, SysRole> UserRoles(long userId)
        {
            var query = client.Queryable<SysUserRole>()
                    .LeftJoin<SysRole>((u, r) => u.RoleId == r.Id)
                    .Where((u, r) => u.UserId == userId && r.Id != null);

            return query;
        }


        /// <summary>
        /// x角色集合的菜单集合
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="roleIds"></param>
        /// <param name="whereExpression"></param>
        /// <param name="selectExpression"></param>
        /// <returns></returns>
        public ISugarQueryable<SysRoleModule, SysModule> RoleModules(List<long> roleIds)
        {
            var query = client.Queryable<SysRoleModule>()
                    .LeftJoin<SysModule>((r, m) => r.ModuleId == m.Id)
                    .Where((r, m) => roleIds.Contains(r.RoleId) && m.Id != null);

            return query;
        }

        /// <summary>
        /// x角色集合的按钮集合
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="roleIds"></param>
        /// <param name="whereExpression"></param>
        /// <param name="selectExpression"></param>
        /// <returns></returns>
        public ISugarQueryable<SysRoleElement, SysModuleElement> RoleModuleElements(List<long> roleIds)
        {
            var query = client.Queryable<SysRoleElement>()
                    .LeftJoin<SysModuleElement>((r, m) => r.ElementId == m.Id)
                    .Where((r, m) => roleIds.Contains(r.RoleId) && m.Id != null);

            return query;
        }

        public ISugarQueryable<SysUserOrg, SysPosition> UserPositons(long userId)
        {
            var query = client.Queryable<SysUserOrg>()
                        .LeftJoin<SysPosition>((u, p) => u.PositionId == p.Id)
                        .Where((u, p) => u.PositionId != null && u.UserId == userId && p.Id != null);

            return query;
        }

        public async Task<List<string>> UserIdsByPosition(string orgId, string positionId)
        {
            var list = await client.Queryable<SysUserOrg>()
                  .Where(a => a.PositionId.ToString() == positionId)
                  .WhereIF(!string.IsNullOrEmpty(orgId), a => a.OrgId.ToString() == orgId)
                  .Select(a => a.UserId.ToString()).ToListAsync();
            return list;
        }

        public async Task<List<string>> UserIdsByPositions(List<string> positionIds)
        {
            var list = await client.Queryable<SysUserOrg>()
                      .Where(a => positionIds.Contains(a.PositionId.ToString()))
                      .Select(a => a.UserId.ToString()).ToListAsync();
            return list;
        }

        public async Task<List<string>> UserIdsByRole(string roleId)
        {
            var list = await client.Queryable<SysUserRole>()
                    .Where(a => a.RoleId.ToString() == roleId)
                    .Select(a => a.UserId.ToString())
                    .ToListAsync();
            return list;
        }

        public async Task<Dictionary<string, object>> UserOrgsByUserIds(List<string> userIds)
        {
            var list1 = await client.Queryable<SysUserOrg>()
                .Where(a => userIds.Contains(a.UserId.ToString()))
                .GroupBy(a => a.UserId)
                .Select(it => new
                {
                    UserId = it.UserId.ToString(),
                    OrgIds = SqlFunc.Subqueryable<SysUserOrg>().Where(s => s.UserId == it.UserId).ToList(s => s.OrgId.ToString())
                }).ToListAsync();
            //.ToDictionaryAsync(x => x.UserId, x => x.OrgIds);

            //var result = list.GroupBy(a => a.UserId.ToString())
            //    .Select(g => new
            //    {
            //        UserId = g.Key,
            //        OrgIds = g.Select(a => a.OrgId.ToString()).ToList()
            //    }).ToDictionary(x => x.UserId, x => x.OrgIds);
            Dictionary<string, object> list = new Dictionary<string, object>();
            foreach(var item in list1)
            {
                list.Add(item.UserId, item.OrgIds);
            }
            return list;
        }

        public async Task<List<string>> PositonsByUser(string userId)
        {
            var list = await client.Queryable<SysUserOrg>()
                    .Where(a => a.UserId.ToString() == userId)
                    .Select(a => a.PositionId.ToString())
                    .ToListAsync();
            return list;
        }


    }
}
