using System.Collections.Generic;
using System.Linq;
using Infrastructure;
using Microsoft.AspNetCore.Mvc;
using Microsoft.VisualStudio.TestPlatform.ObjectModel.Utilities;
using OpenAuth.App.Base;
using OpenAuth.App.Interface;
using OpenAuth.App.ModuleManager;
using OpenAuth.App.ModuleManager.Response;
using OpenAuth.App.Request;
using OpenAuth.Repository;
using OpenAuth.Repository.Core;
using OpenAuth.Repository.Domain;
using SqlSugar;

namespace OpenAuth.App
{
    public class ModuleManagerApp : StringTreeApp<SysModule, SugarDbContext>
    {
        private ISqlSugarClient client;

        public ModuleManagerApp(
            ISugarUnitOfWork<SugarDbContext> unitWork,
            ISimpleClient<SysModule> repository
            , IAuth auth) : base(unitWork, repository, auth)
        {
            client = base.Repository.AsSugarClient();
        }

        #region 菜单

        #region 查询

        #region 菜单树

        /// <summary>
        /// 菜单树【全部数据】
        /// </summary>
        /// <param name="name"></param>
        /// <returns></returns>
        public Response<List<TreeItemString>> ModulesTree(string name)
        {
            var result = new Response<List<TreeItemString>>();

            if (!string.IsNullOrEmpty(name))
            {
                object[] orgIds = base.Repository.AsQueryable()
                    .Where(a => a.Name.Contains(name))
                    .Select(it => it.Id).ToList().Cast<object>().ToArray();

                result.Result = base.Repository.AsQueryable()
                    .OrderBy(a => a.SortNo)
                    .Select<TreeItemString>()
                    .ToTree(a => a.Children, a => a.ParentId, 0, orgIds);
            }
            else
            {
                result.Result = base.Repository.AsQueryable()
                    .OrderBy(a => a.SortNo)
                    .Select<TreeItemString>()
                    .ToTree(a => a.Children, a => a.ParentId, 0, a => a.Id);
            }

            return result;
        }

        #endregion

        #region 单个菜单

        public async Task<Response<SysModule>> ModuleById(string id)
        {
            var model = await base.Repository.GetByIdAsync(id);
            return new Response<SysModule> { Result = model };
        }

        #endregion

        #endregion

        #region 增加

        public Response<bool> Add(SysModule model)
        {
            var loginContext = _auth.GetCurrentUser();
            if (loginContext == null)
            {
                throw new CommonException("登录已过期", Define.INVALID_TOKEN);
            }

            //后面再看
            //CalculateCascade(model);
            model.Id = Guid.NewGuid().ToString();
            var flag = Repository.Insert(model);
            return new Response<bool>
            {
                Result = flag,
                Message = flag == true ? "success" : "error"
            };
        }

        #endregion

        #region 修改

        public Response<bool> Update(SysModule obj)
        {
            try
            {
                //var flag = base.Repository.Update(obj);
                //if (flag)
                //{
                //    return new Response<bool> { Result = true, Message = "success" };
                //}
                //else
                //{
                //    return new Response<bool> { Result = false, Message = "error" };
                //}
                UpdateTreeObj(obj);
                return new Response<bool> { Result = true, Message = "success" };
            }
            catch (Exception ex)
            {
                return new Response<bool> { Result = false, Message = "error:" + ex.Message.ToString() };
            }
        }

        #endregion

        #region 删除

        /// <summary>
        /// 删除指定的菜单
        /// </summary>
        /// <param name="ids"></param>
        public async Task<Response<bool>> Delete(string[] ids)
        {
            using (var uow = base.UnitWork.CreateContext())
            {
                await uow.Module.DeleteByIdAsync(ids.Cast<object>().ToArray());
                await uow.ModuleElement.DeleteAsync(a => ids.Contains(a.ModuleId));
                var flag = uow.Commit();

                return new Response<bool>
                {
                    Result = flag,
                    Message = flag == true ? "success" : "error"
                };
            }
        }

        #endregion

        #endregion

        #region 按钮

        #region 查询

        #region 根据 ModuleId 获取 Elements

        /// <summary>
        /// 根据 ModuleId 获取 Elements
        /// </summary>
        /// <param name="req"></param>
        /// <returns></returns>
        public async Task<Response<PageInfo<List<SysModuleElement>>>> ElementsByModule(
            [FromQuery] QueryElementListReq req)
        {
            RefAsync<int> totalCount = 0;

            var elements = await base.Repository.ChangeRepository<SugarRepositiry<SysModuleElement>>().AsQueryable()
                .WhereIF(!string.IsNullOrEmpty(req.key), el => el.Name.Contains(req.key))
                .WhereIF(!string.IsNullOrEmpty(req.ModuleId), el => el.ModuleId == req.ModuleId)
                .ToPageListAsync(req.page, req.limit, totalCount);

            return new Response<PageInfo<List<SysModuleElement>>>
            {
                Result = new PageInfo<List<SysModuleElement>>
                {
                    Items = elements,
                    Total = totalCount
                }
            };
        }

        #endregion

        #endregion

        #region 添加

        public Response<bool> AddMenu(SysModuleElement model)
        {
            var loginContext = _auth.GetCurrentUser();
            if (loginContext == null)
            {
                throw new CommonException("登录已过期", Define.INVALID_TOKEN);
            }

            using (var uow = base.UnitWork.CreateContext())
            {
                model.Id = Guid.NewGuid().ToString();
                uow.ModuleElement.Insert(model);
                var flag = uow.Commit();

                return new Response<bool>
                {
                    Result = flag,
                    Message = flag == true ? "success" : "error"
                };
            }
        }

        #endregion

        #region 修改

        public Response<bool> UpdateMenu(SysModuleElement model)
        {
            var flag = base.Repository.ChangeRepository<SugarRepositiry<SysModuleElement>>().Update(model);
            return new Response<bool>
            {
                Result = flag,
                Message = flag == true ? "success" : "error"
            };
        }

        #endregion

        #region 删除

        public async Task<Response<bool>> DelMenu(string[] ids)
        {
            var flag = await base.Repository.ChangeRepository<SugarRepositiry<SysModuleElement>>()
                .DeleteByIdAsync(ids.Cast<object>().ToArray());
            return new Response<bool>
            {
                Result = flag,
                Message = flag == true ? "success" : "error"
            };
        }

        #endregion

        #endregion

        #region 用户/角色分配模块

        /// <summary>
        /// 加载特定角色的模块
        /// </summary>
        /// <param name="roleId">The role unique identifier.</param>
        public async Task<Response<ModulesWithElements>> LoadForRole(long roleId)
        {
            var respone = new Response<ModulesWithElements>();

            using (var uwo = UnitWork.CreateContext())
            {
                respone.Result = new ModulesWithElements
                {
                    ElementIds = (await uwo.SysRoleElement.GetListAsync(a => a.RoleId == roleId))
                        .Select(a => a.ElementId).ToList(),
                    ModuleIds = (await uwo.SysRoleModule.GetListAsync(a => a.RoleId == roleId))
                        .Select(a => a.ModuleId).ToList()
                };
            }

            return respone;
        }

        #endregion 用户/角色分配模块

        public async Task<Response<List<SysModule>>> AllModule()
        {
            var modules =
                await Repository.AsQueryable().Select<SysModule>(a => new SysModule
                    {
                        Id = a.Id,
                        ModuleTypeId = a.ModuleTypeId
                    }).Where(a => a.Status == 1).OrderBy(a => a.SortNo)
                    .ToListAsync();
            return new Response<List<SysModule>> { Result = modules };
        }
    }
}