using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using Microsoft.EntityFrameworkCore;
using Siger.Middlelayer.Common;
using Siger.Middlelayer.Common.Extensions;
using Siger.Middlelayer.Common.Helpers;
using Siger.Middlelayer.Repository.Data;
using Siger.Middlelayer.Repository.Entities;
using Siger.Middlelayer.Repository.Extensions;
using Siger.Middlelayer.Repository.Paged;
using Siger.Middlelayer.Repository.Repositories.Interface;

namespace Siger.Middlelayer.Repository.Repositories
{
    internal class SigerUserPowerRepository : ApiConfigRepositoryBase<siger_user_power>, ISigerUserPowerRepository
    {
        private readonly ApiConfigDbContext _context;
        public SigerUserPowerRepository(ApiConfigDbContext context) : base(context)
        {
            _context = context;
        }

        public IEnumerable<UserPower> GetUserRolePowers(int roleid)
        {
            var query = _context.siger_user_power.Where(q => q.status == (int)RowState.Valid);

            var powerids = _context.siger_user_role_power.Where(q =>
                q.roleid == roleid && q.status == (int)RowState.Valid).Select(q => q.powerid);

            var queryList = from q in query
                            select new UserPower
                            {
                                id = q.id,
                                description = q.description,
                                name = q.name,
                                parent = q.parent,
                                parentvalue = q.parentvalue,
                                value = q.value,
                                Checked = powerids.Contains(q.id) ? "1" : "0",
                                sorting = q.sorting
                            };

            var entities = queryList.OrderBy(q => q.sorting).ThenBy(q => q.id).AsNoTracking().ToList();

            return new List<UserPower>(entities);
        }

        public IEnumerable<UserPower> GetProjectTypePowers(int projectTypeId)
        {
            var projectType =
                _context.siger_project_type.FirstOrDefault(q => q.id == projectTypeId && q.status == (int)RowState.Valid);
            if (projectType != null)
            {
                var query = _context.siger_user_power.Where(q => q.status == (int)RowState.Valid);

                var powerids = _context.siger_user_role_power.Where(q =>
                    q.roleid == projectType.id && q.status == (int)RowState.Valid).Select(q => q.powerid);

                var queryList = from q in query
                                select new UserPower
                                {
                                    id = q.id,
                                    description = q.description,
                                    name = q.name,
                                    parent = q.parent,
                                    parentvalue = q.parentvalue,
                                    value = q.value,
                                    Checked = powerids.Contains(q.id) ? "1" : "0",
                                    sorting = q.sorting
                                };

                var entities = queryList.OrderBy(q => q.sorting).ThenBy(q => q.id).AsNoTracking().ToList();
                return new List<UserPower>(entities);
            }

            return null;
        }

        public List<ResponseUserPower> GetUserPower(int type)
        {
            var resp = new List<ResponseUserPower>();
            var typeModel = _context.siger_project_type.FirstOrDefault(q => q.id == type && q.status == (int)RowState.Valid);
            var clientType = Enum.GetNames(typeof(PowerType));
            //菜单类型
            foreach (var item in clientType)
            {
                var clientData = new ResponseUserPower
                {
                    title = item,
                    type = (int)Enum.Parse(typeof(PowerType), item),
                    expand = true
                };
                resp.Add(clientData);
            }
            if (typeModel != null)
            {
                var powerModel = _context.siger_user_power.Where(q => q.status == (int)RowState.Valid).ToList();
                var powerids = _context.siger_user_role_power.Where(q => q.roleid == typeModel.id && q.status == (int)RowState.Valid).Select(q => q.powerid).ToList();
                foreach (var item in resp)
                {
                    item.children = GetPowerData(item.id, item.type, powerModel, powerids);
                }
            }
            return resp;
        }

        private List<ResponseUserPower> GetPowerData(int parent, int type, List<siger_user_power> powerModel, List<int> powerids)
        {
            var menus = new List<ResponseUserPower>();
            var powerData = powerModel.Where(f => f.parent.ToInt() == parent && f.status != (int)RowState.Invalid && f.type.Equals(type));
            if (powerData == null)
            {
                return null;
            }
            foreach (var item in powerData)
            {
                var data = Mapper<siger_user_power, ResponseUserPower>.Map(item);
                data.title = item.name;
                data.children = GetPowerData(item.id, type, powerModel, powerids);
                data.@checked = data.children.Count == 0 && powerids.Contains(item.id);
                menus.Add(data);
            }
            return menus;
        }

        public IPagedCollectionResult<UserPower> GetPowers(string name, string type, int page, int pagesize)
        {
            var query = _context.siger_user_power.Where(q => q.status == (int)RowState.Valid);
            var queryList = from q in query
                            join c in _context.siger_user_power on q.parent equals c.id.ToString() into po
                            from c in po.DefaultIfEmpty()
                            select new UserPower
                            {
                                id = q.id,
                                description = q.description,
                                name = q.name,
                                parent = q.parent,
                                parentvalue = c.value,
                                value = q.value,
                                sorting = q.sorting,
                                type = q.type,
                                icon = q.icon,
                                url = q.parentvalue
                            };
            Expression<Func<UserPower, bool>> nameExpression = q => true;
            if (!string.IsNullOrWhiteSpace(name))
            {
                nameExpression = q => q.description.Contains(name);
            }
            Expression<Func<UserPower, bool>> typeExpression = q => true;
            if (!string.IsNullOrWhiteSpace(type))
            {
                typeExpression = q => q.type == type.ToInt();
            }

            var predicate = nameExpression.And(typeExpression);
            var totalCount = queryList.Count(predicate);
            var entities = queryList.Where(predicate).OrderBy(q => q.id).ThenBy(q => q.sorting).Skip((page - 1) * pagesize).Take(pagesize).AsNoTracking().ToList();

            return new PagedCollectionResult<UserPower>(entities, totalCount);
        }

        public IEnumerable<UserPower> GetAllPowers()
        {
            var query = _context.siger_user_power.Where(q => q.status == (int)RowState.Valid);
            var queryList = from q in query
                            join c in _context.siger_user_power on q.parent equals c.id.ToString() into po
                            from c in po.DefaultIfEmpty()
                            select new UserPower
                            {
                                id = q.id,
                                description = q.description,
                                name = q.name,
                                parent = q.parent,
                                parentvalue = c.value,
                                value = q.value,
                                sorting = q.sorting,
                                type = q.type
                            };
            return queryList.OrderBy(q => q.type).ThenBy(q => q.sorting).ThenBy(q => q.id).ToList();
        }
    }
}
