using BPA.SAAS.Manage.Application.System.Dtos;
using BPA.SAAS.Manage.Application.System.Interface;
using BPA.SAAS.Manage.Comm.Const;
using BPA.SAAS.Manage.Comm.Enum;
using BPA.SAAS.Manage.Core.Org;
using BPA.SAAS.Manage.Core.System;
using Furion.LinqBuilder;
using Mapster.Utils;
using NPOI.SS.Formula.Functions;
using NPOI.XSSF.UserModel;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;

namespace BPA.SAAS.Manage.Application.System.Services
{
    public class MenuService : IMenuService, ITransient
    {
        private readonly ISqlSugarClient _db;
        public MenuService(ISqlSugarClient db)
        {
            _db = db;
        }
        /// <summary>
        /// 分页查询
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public async Task<List<MenuTreeDtoOutput>> GetMenuTreePage(MenuTreeSearchDtoInput input)
        {
            if (App.User.FindFirst(ClaimConst.CLAINM_USERID)?.Value == null)
                return null;

            var AllMenus =await _db.Queryable<BPA_Menu>().OrderBy(t => t.Sort).ToListAsync();

            var query = AllMenus.Where(t => t.Pid == "" || t.Pid == null);

            if (!input.Name.IsNullOrEmpty())
                query = query.Where(t => t.Name.Contains(input.Name));
            if (!input.Code.IsNullOrEmpty())
                query = query.Where(t => t.Code.Contains(input.Code));

            var data = query.Select(t => new MenuTreeDtoOutput
            {
                Id = t.Id,
                Name = t.Name,
                CreateAt = t.CreateAt,
                Code = t.Code,
                Icon = t.Icon,
                Router = t.Router,
                Pid = t.Pid,
                Sort = t.Sort,
                Component = t.Component,
                Status = t.Status,
                IsAdmin=t.IsAdmin,
                Type= t.Type,
               // TypeName= GetTypeName(t.Type),
                Children = AllMenus.Where(x => x.Pid == t.Id).Select(x => new MenuTreeDtoOutput
                {
                    Id = x.Id,
                    Name = x.Name,
                    CreateAt = x.CreateAt,
                    Code = x.Code,
                    Pid = x.Pid,
                    Icon = x.Icon,
                    Router = x.Router,
                    Sort = x.Sort,
                    Component = x.Component,
                    Status = x.Status,
                    IsAdmin=x.IsAdmin,
                    Type = x.Type,
                    //TypeName = GetTypeName(x.Type),
                    Children = AllMenus.Where(y => y.Pid == x.Id).Select(y => new MenuTreeDtoOutput
                    {
                        Id = y.Id.ToString(),
                        Name = y.Name,
                        CreateAt = y.CreateAt,
                        Code = y.Code,
                        Icon = y.Icon,
                        Pid = y.Pid.ToString(),
                        Router = y.Router,
                        Sort = y.Sort,
                        Component = y.Component,
                        Status = y.Status,
                        IsAdmin=y.IsAdmin,
                        Type = y.Type,
                        //TypeName = GetTypeName(y.Type),
                    }).ToList()
                }).ToList()
            }).ToList();

            return data;
        }
        /// <summary>
        /// 新增菜单
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public async Task<bool> Add(MenuDtoInput input)
        {
            var dicttypes = _db.Queryable<BPA_Menu>().Where(a => a.Code == input.Code).ToList();
            if (dicttypes.Count() > 0)
            {
                throw Oops.Oh("编码已存在");
            }
            if (input.Name.Length > 20)
            {
                throw Oops.Oh("菜单名称过长");
            }
            var menu = input.Adapt<BPA_Menu>();
            return  await _db.Insertable(menu).CallEntityMethod(t => t.Create()).ExecuteCommandAsync()> 0;
        }

        /// <summary>
        /// 编辑菜单
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public async Task<bool> Update(MenuDtoInput input)
        {
            var menu = await _db.Queryable< BPA_Menu >().Where(x=>x.Id== input.Id).FirstAsync();
            //menu = input.Adapt<BPA_Menu>();
            menu.Code = input.Code;
            menu.Component = input.Component;
            menu.Name= input.Name;
            menu.Pid= input.Pid;
            menu.Router = input.Router;
            menu.Remark= input.Remark;
            menu.Sort = input.Sort;
            menu.Icon = input.Icon;
            menu.IsAdmin= input.IsAdmin;
            menu.Type   = input.Type;
            return await _db.Updateable(menu).ExecuteCommandAsync()>0;
        }

        /// <summary>
        /// 删除菜单
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public async Task<bool> Delete(List<string> input)
        {
            try
            {
                _db.Ado.BeginTran();
                // 查询数据库中是否存在未删除的活动信息
                var resEntitites = _db.Queryable<BPA_Menu>().In(input).ToList();
                for (int i = 0; i < resEntitites.Count; i++)
                {
                    var childlist = _db.Queryable<BPA_Menu>().Where(x => x.Pid == resEntitites[i].Id).ToList();
                    if(childlist.Count>0) resEntitites.AddRange(childlist);
                }
                var res =await _db.Deleteable(resEntitites).ExecuteCommandAsync();
                _db.Ado.CommitTran();
                return res>0;
            }
            catch (Exception)
            {
                _db.Ado.RollbackTran();
                return false;
            }
        }
       /// <summary>
       /// 查询菜单树
       /// </summary>
       /// <param name="GetType"></param>
       /// <returns></returns>
        public async Task<List<MenuTreeOutput>> MenuTree(string GetType)
        {
            if (!string.IsNullOrWhiteSpace(GetType) && GetType.ToLower() == "user")
            {

                var userId = App.User.FindFirst(ClaimConst.CLAINM_USERID)?.Value;
               // var GroupId = App.User.FindFirst(ClaimConst.GroupId)?.Value;
                if ( string.IsNullOrWhiteSpace(userId))
                {
                    return null;
                }
                List<BPA_Roles> dataRoles =await _db.Queryable<BPA_Roles>().ToListAsync();
                if (dataRoles.Count() <= 0)
                {
                    return null;
                }
                var sysRoleId = dataRoles.Select(a => a.Id).ToArray();
                var menus = _db.Queryable<BPA_RoleMenu>().Where(t => sysRoleId.Contains(t.SysRoleId))
                 .Select(x => x.SysMenuId).ToArray();

                var AllMenus = _db.Queryable<BPA_Menu>().Where(t => menus.Contains(t.Id)).OrderBy(t => t.Sort).ToList();

                var data = AllMenus.Where(t => t.Pid == null || t.Pid == "").Select(t => new MenuTreeOutput
                {
                    Key = t.Id,
                    Title = t.Name,
                    value = t.Id,
                    Children = AllMenus.Where(x => x.Pid == t.Id).Select(x => new MenuTreeOutput
                    {
                        Key = x.Id,
                        Title = x.Name,
                        value = x.Id,
                        Children = AllMenus.Where(y => y.Pid == x.Id).Select(y => new MenuTreeOutput
                        {
                            Key = y.Id,
                            Title = y.Name,
                            value = y.Id,
                        }).ToList()
                    }).ToList()
                }).ToList();

                return data;

            }
            else
            {
                var AllMenus = _db.Queryable<BPA_Menu>().OrderBy(t => t.Sort).ToList();
                var data = AllMenus.Where((t => t.Pid == null || t.Pid == "")).Select(t => new MenuTreeOutput
                {
                    Key = t.Id,
                    Title = t.Name,
                    value = t.Id,
                    Children = AllMenus.Where(x => x.Pid == t.Id).Select(x => new MenuTreeOutput
                    {
                        Key = x.Id,
                        Title = x.Name,
                        value = x.Id,
                        Children = AllMenus.Where(y => y.Pid == x.Id).Select(y => new MenuTreeOutput
                        {
                            Key = y.Id,
                            Title = y.Name,
                            value = y.Name,
                        }).ToList()
                    }).ToList()
                }).ToList();
                var da = new List<MenuTreeOutput>();
                data.ForEach(x =>
                {
                    if (x.Children.Count() > 0)
                    {
                        da.Add(x);
                    }

                });
              
                
                return da;

            }

        }
        public async Task<List<MenuTreeOutput>> MenuParmyTree(string GetType, string type)
        {
            if (!string.IsNullOrWhiteSpace(GetType) && GetType.ToLower() == "user")
            {

                var userId = App.User.FindFirst(ClaimConst.CLAINM_USERID)?.Value;
                // var GroupId = App.User.FindFirst(ClaimConst.GroupId)?.Value;
                if (string.IsNullOrWhiteSpace(userId))
                {
                    return null;
                }
                List<BPA_Roles> dataRoles = await _db.Queryable<BPA_Roles>().ToListAsync();
                if (dataRoles.Count() <= 0)
                {
                    return null;
                }
                var sysRoleId = dataRoles.Select(a => a.Id).ToArray();
                var menus = _db.Queryable<BPA_RoleMenu>().Where(t => sysRoleId.Contains(t.SysRoleId))
                 .Select(x => x.SysMenuId).ToArray();

                var AllMenus = _db.Queryable<BPA_Menu>().Where(t => menus.Contains(t.Id)).OrderBy(t => t.Sort).ToList();

                var data = AllMenus.Where(t => t.Pid == null || t.Pid == "").Select(t => new MenuTreeOutput
                {
                    Key = t.Id,
                    Title = t.Name,
                    value = t.Id,
                    Children = AllMenus.Where(x => x.Pid == t.Id).Select(x => new MenuTreeOutput
                    {
                        Key = x.Id,
                        Title = x.Name,
                        value = x.Id,
                        Children = AllMenus.Where(y => y.Pid == x.Id).Select(y => new MenuTreeOutput
                        {
                            Key = y.Id,
                            Title = y.Name,
                            value = y.Id,
                        }).ToList()
                    }).ToList()
                }).ToList();

                return data;

            }
            else
            {
                var AllMenus = _db.Queryable<BPA_Menu>().Where(t =>  t.IsAdmin == 0).OrderBy(t => t.Sort).ToList();
                var data = AllMenus.Where((t => t.Pid == null || t.Pid == "")).Select(t => new MenuTreeOutput
                {
                    Key = t.Id,
                    Title = t.Name,
                    value = t.Id,
                    type=t.Type,
                    Children = AllMenus.Where(x => x.Pid == t.Id).Select(x => new MenuTreeOutput
                    {
                        Key = x.Id,
                        Title = x.Name,
                        value = x.Id,
                        type = x.Type,
                        Children = AllMenus.Where(y => y.Pid == x.Id).Select(y => new MenuTreeOutput
                        {
                            Key = y.Id,
                            Title = y.Name,
                            value = y.Name,
                            type = y.Type,
                        }).ToList()
                    }).ToList()
                }).ToList();
                var da = new List<MenuTreeOutput>();
                //data.ForEach(x =>
                //{
                //    if (x.Children.Count() > 0 || x.type== type)
                //    {
                //        da.Add(x);
                //    }

                //});
                return data;
            }

        }
        public async Task<List<MenuTreeOutput>> MenuTree()
        {
                var AllMenus = _db.Queryable<BPA_Menu>().OrderBy(t => t.Sort).ToList();
                var data = AllMenus.Where(t => t.Pid == null || t.Pid == "").Select(t => new MenuTreeOutput
                {
                    Key = t.Id,
                    Title = t.Name,
                    value = t.Id,
                    Children = AllMenus.Where(x => x.Pid == t.Id).Select(x => new MenuTreeOutput
                    {
                        Key = x.Id,
                        Title = x.Name,
                        value = x.Id,
                        Children = AllMenus.Where(y => y.Pid == x.Id).Select(y => new MenuTreeOutput
                        {
                            Key = y.Id,
                            Title = y.Name,
                            value = y.Id,
                        }).ToList()
                    }).ToList()
                }).ToList();
                return data;
        }
        /// <summary>
        /// 动态菜单(菜单树)
        /// </summary>
        /// <returns></returns>
        public async Task<List<MenuRouteDtoOutput>> DymicMenuTree(int type)
        {
            var UserId = App.User.FindFirst(ClaimConst.CLAINM_USERID)?.Value;
            var IsAdmin = App.User.FindFirst(ClaimConst.CLAINM_SUPERADMIN)?.Value;
            var account = App.User.FindFirst(ClaimConst.CLAINM_ACCOUNT)?.Value;

            if (UserId == null)
                return null;
            List<BPA_Menu> AllMenus = await _db.Queryable<BPA_Menu>().OrderBy(t => t.Sort).ToListAsync();
            List<BPA_Menu> ParnMenus = new();
            if (IsAdmin == "1" && account == "admin")
            {
                var adminmenu = await _db.Queryable<BPA_Menu>().Where(t =>t.IsAdmin==1).OrderBy(t => t.Sort).ToListAsync();
                var pids= adminmenu.Select(t => t.Pid).ToList();
                var pidmenu=await _db.Queryable<BPA_Menu>().Where(t => pids.Contains(t.Id)).ToListAsync();
                adminmenu.AddRange(pidmenu);
                //去重
                adminmenu = adminmenu.Where((x, i) => adminmenu.FindIndex(z => z.Id == x.Id) == i).ToList();
                var data = adminmenu.Where(t => t.Pid == null || t.Pid == "").OrderBy(t => t.Sort).Select(t => new MenuRouteDtoOutput
                {
                    Id = t.Id,
                    Component = t.Component,
                    Icon = t.Icon,
                    Name = t.Name,
                    Path = t.Router,
                    Routes = adminmenu.Where(y => y.Pid == t.Id).Select(x => new MenuRouteChildDtoOutput
                    {
                        Id = t.Id,
                        Component = x.Component,
                        Name = x.Name,
                        Path = x.Router,
                        Routes = adminmenu.Where(y => y.Pid == x.Id).Select(y => new MenuRouteChildDtoOutput
                        {
                            Id = t.Id,
                            Component = y.Component,
                            Name = y.Name,
                            Path = y.Router
                        }).ToList()
                    }).ToList()
                }).ToList();
                return data;
            }
            else
            {
                AllMenus= AllMenus.Where(t=>  t.IsAdmin == 0).ToList();
                ParnMenus = await _db.Queryable<BPA_Menu>().LeftJoin<BPA_RoleMenu>((t, x) => t.Id == x.SysMenuId).LeftJoin<BPA_UserRole>((t, x, y) => x.SysRoleId == y.SysRoleId)
                   .Where((t, x, y) => y.SysUserId == UserId && t.Status == 0  && t.IsAdmin==0).Select(t => t).ToListAsync();
                var data = ParnMenus.Where(t => t.Pid == null || t.Pid == "").OrderBy(t => t.Sort).Select(t => new MenuRouteDtoOutput
                {
                    Id = t.Id,
                    Component = t.Component,
                    Icon = t.Icon,
                    Name = t.Name,
                    Path = t.Router,
                    Routes = AllMenus.Where(y => y.Pid == t.Id).Select(x => new MenuRouteChildDtoOutput
                    {
                        Id = t.Id,
                        Component = x.Component,
                        Name = x.Name,
                        Path = x.Router,
                        Routes = AllMenus.Where(y => y.Pid == x.Id).Select(y => new MenuRouteChildDtoOutput
                        {
                            Id = t.Id,
                            Component = y.Component,
                            Name = y.Name,
                            Path = y.Router
                        }).ToList()
                    }).ToList()
                }).ToList();
                return data;
            }

            //    ParnMenus = await _db.Queryable<BPA_Menu>().Where(t => (t.Name == "系统管理" || t.Name == "加盟商管理" || t.Name == "设备管理")).OrderBy(t => t.Sort).ToListAsync();
            //else
            //    ParnMenus = await _db.Queryable<BPA_Menu>().LeftJoin<BPA_RoleMenu>((t, x) => t.Id == x.SysMenuId).LeftJoin<BPA_UserRole>((t, x, y) => x.SysRoleId == y.SysRoleId)
            //        .Where((t, x, y) => y.SysUserId == UserId && t.Status == 0 && (t.Type== type || t.Type==3) && (t.Name!= "产品管理" || t.Name != "版本管理")).Select(t => t).ToListAsync();
            //菜单去重
           // ParnMenus = AllMenus.Where((x, i) => AllMenus.FindIndex(z => z.Id == x.Id) == i).ToList();
            //var data = ParnMenus.Where(t => t.Pid == null || t.Pid == "").OrderBy(t => t.Sort).Select(t => new MenuRouteDtoOutput
            //{
            //    Id = t.Id,
            //    Component = t.Component,
            //    Icon = t.Icon,
            //    Name = t.Name,
            //    Path = t.Router,
            //    Routes = AllMenus.Where(x => x.Pid == t.Id) .WhereIF(IsAdmin == "1" && account == "admin", x =>x.Name!="设备信息" && x.Name != "设备数据同步").Select(x => new MenuRouteChildDtoOutput
            //    {
            //        Id = t.Id,
            //        Component = x.Component,
            //        Name = x.Name,
            //        Path = x.Router,
            //        Routes = AllMenus.Where(y => y.Pid == x.Id).Select(y => new MenuRouteChildDtoOutput
            //        {
            //            Id = t.Id,
            //            Component = y.Component,
            //            Name = y.Name,
            //            Path = y.Router
            //        }).ToList()
            //    }).ToList()
            //}).ToList();
           // return data;
        }
        /// <summary>
        /// 启用
        /// </summary>
        /// <param name="Id"></param>
        /// <returns></returns>
        public async Task<bool> Enable(string Id)
        {
            var resEntitites = _db.Queryable<BPA_Menu>().In(Id).ToList();
            resEntitites.ForEach(x =>
            {
                x.Status = CommonStatus.ENABLE;
            });
            var res =await _db.Updateable(resEntitites).ExecuteCommandAsync();
            return res>0;
        }

        /// <summary>
        /// 禁用
        /// </summary>
        /// <param name="Id"></param>
        /// <returns></returns>
        public async Task<bool> Disable(string Id)
        {
            var resEntitites = _db.Queryable<BPA_Menu>().In(Id).ToList();
            resEntitites.ForEach(x =>
            {
                x.Status = CommonStatus.DISABLE;
            });
            var res =await _db.Updateable(resEntitites).ExecuteCommandAsync();
            return res>0;
        }

    }
}
