using System;
using System.Collections.Generic;
using System.Linq.Expressions;
using System.Threading;
using System.Threading.Tasks;

using FreeSql;
using XHD.Core.IRepository;
using XHD.Core.Models;
using XHD.Core.Common;

namespace XHD.Core.Repository
{
    public class DBAuthRepository:IDBAuthRepository
    {
        protected IFreeSql _fsql;

        public DBAuthRepository(IFreeSql freeSql)
        {
            _fsql = freeSql;
        }

        /// <summary>
        /// 获取用户所有角色的数据权限最高级别
        /// </summary>
        /// <param name="emp_id"></param>
        /// <returns>0无，1本人，2本部，3本部及下级，4全部</returns>
        public async Task<int> GetAuthType(string emp_id)
        {
            Expression<Func<Sys_role, bool>> exp = a =>
                    _fsql.Select<Sys_role_emp>()
                         .As("b")
                         .Where(b => b.empID == emp_id)
                         .ToList(b => b.RoleID)
                         .Contains(a.id);

            var data = await _fsql.Select<Sys_role>()
                //.WhereIf()
                .Where(exp)
                //.OrderBy(orderby)
                //.Page(Page, Limit)
                .Count(out var total)
                .ToListAsync();

            int authcode = 0;

            foreach (var list in data)
            {
                if (list.DataAuth > authcode)
                {
                    authcode = (int)list.DataAuth;
                }
            }

            return authcode;
        }

        /// <summary>
        /// 根据用户获取目录和按钮权限
        /// </summary>
        /// <param name="emp_id">用户id</param>
        /// <param name="auth_id">目录id</param>
        /// <returns></returns>
        public async Task<bool> GetAuth(string emp_id, string auth_id)
        {
            //系统管理员，绝对的权限
            if (emp_id.ToLower().Equals("admin"))
            {
                return true;
            }

            //查出此用户角色集合
            var roleidlist = await _fsql.Select<Sys_role_emp>().Where(a => a.empID == emp_id).ToListAsync(b => b.RoleID);

            //从权限表查出是否有此目录id权限
            var rolelist = await _fsql.Select<Sys_authority>().Where(a => a.Auth_id == auth_id && roleidlist.Contains(a.Role_id)).ToListAsync();

            //如果有数据，则有权限授权
            if (rolelist.Count > 0)
                return true;

            return false;
        }

        /// <summary>
        /// 根据用户获取数据权限，返回用户id列表
        /// 此处都返回emp_id，不返回dep_id，是因为防止查询过深
        /// 比如order，如果返回的是dep_id，则需要这样查询：Customr.employee.department.id==dep_id
        /// 如果返回的是emplist，则Customer.employee.id in (emplist),可以少查询一层
        /// </summary>
        /// <param name="emp_id">用户id</param>
        /// <returns></returns>
        public async Task<XHDRoleData> GetDataAuth(string emp_id)
        {
            //系统管理员，绝对的权限
            if (emp_id.ToLower().Equals("admin"))
            {
                //全部,返回一个标记即可，前端无需处理
                return new XHDRoleData { authtype = 4, empList = new List<string> { } };
            }

            var authtype = await GetAuthType(emp_id);

            if (authtype == 0)
            {
                //无权限，直接返回一个空数组
                return new XHDRoleData { authtype = 0, empList = new List<string> { } };
            }

            if (authtype == 1)
            {
                //本人，返回用户id
                return new XHDRoleData { authtype = 1, empList = new List<string> { emp_id } };
            }

            if (authtype == 2)
            {
                //本部门，返回部门id，交前端处理
                var depidlist = await _fsql.Select<hr_employee>().Where(a => a.id == emp_id).ToListAsync();

                var depid = "";

                if (depidlist.Count > 0)
                {
                    depid = depidlist[0].dep_id;
                }

                var deppartmentidlist = await _fsql.Select<hr_employee>().Where(a => a.dep_id == depid).ToListAsync(b => b.id);

                return new XHDRoleData { authtype = 2, empList = deppartmentidlist };
            }

            if (authtype == 3)
            {
                //本部及下级，需要递归获取部门下全部员工
                var employeelist = await _fsql.Select<hr_employee>().Where(a => a.id == emp_id).ToListAsync();

                var depid = "";

                if (employeelist.Count > 0)
                {
                    depid = employeelist[0].dep_id;
                }

                var departmentlist = await _fsql.Select<hr_department>().Where(a => 1==1).ToListAsync();
                var deplist = getDepList(departmentlist, depid);
                deplist.Add(depid);


                var emplist = await _fsql.Select<hr_employee>().Where(a => deplist.Contains(a.dep_id)).ToListAsync(b => b.id);

                return new XHDRoleData { authtype = 3, empList = emplist };
            }

            if (authtype == 4)
            {
                //全部,返回一个标记即可，前端无需处理
                return new XHDRoleData { authtype = 4, empList = new List<string> { } };
            }

            //默认无权限
            return new XHDRoleData { authtype = 0, empList = new List<string> { } };
        }

        //获取部门id列表
        private List<string> getDepList(List<hr_department> list, string id)
        {
            var selectList = list.FindAll(c => c.parentid == id);

            List<string> arr = new List<string>();

            foreach (var a in selectList)
            {
                arr.Add(a.id);

                if (getDepList(list, a.id).Count > 0)
                {
                    getDepList(list, a.id);
                }
            }

            return arr;
        }
    }
}
