using System.Collections.Generic;
using Microsoft.AspNetCore.Mvc;
using Siger.ApiCommon.Result;
using Siger.Middlelayer.Common;
using Siger.Middlelayer.Common.Extensions;
using Siger.Middlelayer.Common.Helpers;
using Siger.Middlelayer.Repository;
using Siger.Middlelayer.Repository.Data;
using Siger.Middlelayer.Repository.Entities;
using Siger.Middlelayer.Repository.Repositories.Interface;
using Siger.Middlelayer.Repository.Request;
using Siger.Middlelayer.Repository.Response;
using System.Linq;

namespace Siger.ApiConfig.Controller
{
    public class UserPowerController : BaseController
    {
        private readonly IUnitOfWork _unitOfWork;
        private readonly ISigerUserPowerRepository _powerRepository;
        private readonly ISigerUserRepository _userRepository;
        public UserPowerController(IUnitOfWork unitOfWork, ISigerUserPowerRepository powerRepository, ISigerUserRepository userRepository)
        {
            _unitOfWork = unitOfWork;
            _powerRepository = powerRepository;
            _userRepository = userRepository;
        }

        [HttpGet]
        public IActionResult GetPowerList(string name, string type, int page = 1, int pagesize = PageSize)
        {
            var list = _powerRepository.GetPowers(name, type, page, pagesize);

            return new PagedObjectResult(list.Data, list.Total, page, pagesize);
        }

        [HttpGet]
        public IActionResult GetUserPowerTree()
        {
            var list = _powerRepository.GetAllPowers();

            var powers = new List<LevelSectionTree>();
            foreach (var power in list)
            {
                powers.Add(new LevelSectionTree
                {
                    id = power.id,
                    name = power.name,
                    title = power.description,
                    pid = power.parent.ToInt(),
                    disabled = false,
                    open = true,
                });
            }
            var response = new ResponseLevelSectionChildren(ConvertToTree(powers));

            return new ObjectResult(response);
        }

        private IList<LevelSectionTree> ConvertToTree(IEnumerable<LevelSectionTree> models)
        {
            var section = new Dictionary<int, LevelSectionTree>();
            foreach (var item in models)
            {
                section.Add(item.id, item);
            }
            var result = new List<LevelSectionTree>();
            foreach (var item in section.Values)
            {
                if (item.pid == 0)
                {
                    result.Add(item);
                }
                else
                {
                    if (section.ContainsKey(item.pid))
                    {
                        section[item.pid].AddChilrden(item);
                    }
                }
            }
            return result;
        }

        [HttpGet]
        public IActionResult GetAllPowers()
        {
            var response = new List<ResponseGetUserPower>();

            var list = _powerRepository.GetAllPowers();
            foreach (var power in list)
            {
                response.Add(Mapper<UserPower, ResponseGetUserPower>.Map(power));
            }

            return new ObjectResult(list);
        }

        [HttpPost]
        public IActionResult AddPower([FromBody] RequestAddUserPower request)
        {
            var power = new siger_user_power
            {
                value = request.value,
                description = request.description,
                name = request.name,
                parent = request.parent,
                icon = request.icon.ToStr(),
                sorting = request.sorting.ToInt(),
                type = request.type.ToInt(),
                parentvalue = request.url.ToStr()
            };

            _powerRepository.Insert(power);

            if (_unitOfWork.Commit() > 0)
            {
                return new ObjectResult(CommonEnum.Succefull);
            }
            throw new BadRequestException(CommonEnum.SystemExcetion);
        }

        [HttpGet]
        public IActionResult GetPower(int id)
        {
            var power = _powerRepository.Get(id);
            if (power == null || power.status != (int)RowState.Valid)
            {
                throw new BadRequestException(RequestEnum.UserPowerIsNotFound);
            }

            return new ObjectResult(new List<siger_user_power> { power });
        }

        [HttpPost]
        public IActionResult EditPower([FromBody] RequestUpdateUserPower request)
        {
            var power = _powerRepository.Get(request.id);
            if (power == null || power.status != (int)RowState.Valid)
            {
                throw new BadRequestException(RequestEnum.UserPowerIsNotFound);
            }
            power.value = request.value;
            power.description = request.description;
            power.name = request.name;
            power.parent = request.parent;
            power.icon = request.icon.ToStr();
            power.type = request.type.ToInt();
            power.sorting = request.sorting.ToInt();
            power.parentvalue = request.url.ToStr();
            _powerRepository.Update(power);

            if (_unitOfWork.Commit() > 0)
            {
                return new ObjectResult(CommonEnum.Succefull);
            }
            throw new BadRequestException(CommonEnum.SystemExcetion);
        }

        [HttpPost]
        public IActionResult DeletePower(int id)
        {
            var power = _powerRepository.Get(id);
            if (power == null || power.status != (int)RowState.Valid)
            {
                throw new BadRequestException(RequestEnum.UserPowerIsNotFound);
            }

            power.status = (int)RowState.Invalid;
            _powerRepository.Update(power);

            if (_unitOfWork.Commit() > 0)
            {
                return new ObjectResult(CommonEnum.Succefull);
            }
            throw new BadRequestException(CommonEnum.SystemExcetion);
        }

        /// <summary>
        /// Vue菜单显示
        /// </summary>
        /// <param name="name"></param>
        /// <returns></returns>
        [HttpGet]
        public IActionResult GetMenu(string name = "configs")
        {
            var parentPower = _powerRepository.Get(q => q.value == name && q.status == (int)RowState.Valid && q.type == (int)PowerType.Web);
            if (parentPower == null)
            {
                return new ObjectResult(new List<ResponseMenu>());
            }

            var powerModel = _userRepository.GetModulePowers(UserId, ProjectId, parentPower.id.ToString()).Where(q => q.type == (int)PowerType.Web).ToList();
            //顶级模块
            var toppest = powerModel.FirstOrDefault(f => f.status == (int)RowState.Valid && f.value.Equals(name) && f.parent == "0");
            if (toppest == null)    
            {
                return new ObjectResult(new List<ResponseMenu>());
            }
            var ret = GetChildren(powerModel, toppest.id.ToStr());
            return new ObjectResult(ret);
        }

        /// <summary>
        /// 根据三级菜单获取父级下的全部菜单
        /// </summary>
        /// <param name="name"></param>
        /// <param name="path"></param>
        /// <returns></returns>
        [HttpGet]
        public IActionResult GetMenuByChild(string name, string path)
        {
            var power = _powerRepository.Get(q => q.name == name && q.parentvalue == path && q.status == (int)RowState.Valid && q.type == (int)PowerType.Web);
            if (power == null)
            {
                return new ObjectResult(new List<ResponseMenu>());
            }
            var parentonePower = _powerRepository.Get(q => q.id == power.parent.ToInt() && q.status == (int)RowState.Valid);
            if (parentonePower == null)
            {
                return new ObjectResult(new List<ResponseMenu>());
            }
            var parenttwoPower = _powerRepository.Get(q => q.id == parentonePower.parent.ToInt() && q.status == (int)RowState.Valid);
            if (parenttwoPower == null)
            {
                return new ObjectResult(new List<ResponseMenu>());
            }
            return new ObjectResult(parenttwoPower.value);
        }

        /// <summary>
        /// App菜单显示
        /// </summary>
        /// <returns></returns>
        [HttpGet]
        public IActionResult GetAppMenu()
        {
            var parentPower = _powerRepository.Get(q => q.status == (int)RowState.Valid && q.type == (int)PowerType.App);
            if (parentPower == null)
            {
                return new ObjectResult(new List<ResponseMenu>());
            }

            var powerModel = _userRepository.GetModulePowers(UserId, ProjectId, parentPower.id.ToString()).Where(q => q.type == (int)PowerType.App).ToList();
            //顶级模块
            var toppest = powerModel.FirstOrDefault(f => f.status == (int)RowState.Valid && f.parent == "0");
            if (toppest == null)
            {
                return new ObjectResult(new List<ResponseMenu>());
            }

            var responses = new List<ResponseMenu>();
            foreach (var power in powerModel.Where(q => q.parent == "0"))
            {
                var response = new ResponseMenu
                {
                    parentvalue = power.parentvalue,
                    component = power.parentvalue,
                    name = power.name,
                    path = power.value,
                    meta = new Meta
                    {
                        icon = power.icon,
                        title = power.name
                    },
                    children = GetChildren(powerModel, power.id.ToStr())
                };

                responses.Add(response);
            }
           
            return new ObjectResult(responses);
        }

        private List<ResponseMenu> GetChildren(List<siger_user_power> powerModel, string parent)
        {
            var data = powerModel.Where(f => f.parent.Equals(parent)).OrderBy(q => q.sorting).ToList();
            var ret = new List<ResponseMenu>();
            if (data.Any())
            {
                foreach (var item in data)
                {
                    var child = new ResponseMenu
                    {
                        parentvalue=item.parentvalue,
                        component = item.parentvalue,
                        name = item.name,
                        path = item.value,
                        meta = new Meta
                        {
                            hideInMenu=item.hidden==1?true:false,
                            icon = item.icon,
                            title = item.name
                        }
                    };
                    child.children = GetChildren(powerModel, item.id.ToStr());
                    ret.Add(child);
                }
                return ret;
            }
            return null;
        }
        /// <summary>
        /// 获取模块信息
        /// </summary>
        /// <returns></returns>
        [HttpGet]
        public IActionResult GetModular()
        {
            var data = _powerRepository.GetList(f => f.status == (int)RowState.Valid && f.parent == "0");
            return new ObjectResult(data);
        }

        [HttpPost]
        public IActionResult Deletes([FromBody]RequestDeleteEntities request)
        {
            if (request.ids == null || !request.ids.Any())
            {
                throw new BadRequestException(RequestEnum.ParameterError);
            }
            foreach (var id in request.ids)
            {
                var power = _powerRepository.Get(id);
                if (power != null)
                {
                    power.status = (int)RowState.Invalid;
                    _powerRepository.Update(power);
                }
            }

            _unitOfWork.Commit();
            return new ObjectResult(CommonEnum.Succefull);
        }
    }
}