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

namespace Siger.ApiConfig.Controller
{
    public class UserRoleController : BaseController
    {
        private readonly IUnitOfWork _unitOfWork;
        private readonly ISigerUserRoleRepository _roleRepository;
        private readonly ISigerUserPowerRepository _powerRepository;
        private readonly ISigerProjectRepository _projectRepository;
        private readonly ISigerProjectTypeRepository _projectTypeRepository;
        private readonly ISigerUserRolePowerRepository _userRolePowerRepository;
        private readonly ISigerProjectSectionRepository _projectSectionRepository;
        private readonly ISigerProjectUserGroupRepository _projectUserGroupRepository;
        public UserRoleController(IUnitOfWork unitOfWork, ISigerUserRoleRepository userRoleRepository, ISigerUserPowerRepository powerRepository, ISigerProjectRepository projectRepository,
            ISigerProjectTypeRepository typeRepository, ISigerUserRolePowerRepository rolePowerRepository, ISigerProjectSectionRepository projectSectionRepository,
            ISigerProjectUserGroupRepository projectUserGroupRepository)
        {
            _unitOfWork = unitOfWork;
            _roleRepository = userRoleRepository;
            _powerRepository = powerRepository;
            _projectRepository = projectRepository;
            _projectTypeRepository = typeRepository;
            _userRolePowerRepository = rolePowerRepository;
            _projectSectionRepository = projectSectionRepository;
            _projectUserGroupRepository = projectUserGroupRepository;
        }

        [HttpGet]
        public IActionResult GetUserRoleList(int page = 1, int pagesize = PageSize)
        {
            var response = new List<ResponseGetUserRole>();

            var roles = _roleRepository.GetPagedList(page, pagesize, q => q.status == (int)RowState.Valid && q.type == 1);
            foreach (var role in roles.Data)
            {
                response.Add(Mapper<siger_user_roles, ResponseGetUserRole>.Map(role));
            }

            return new PagedObjectResult(response, roles.Total, page, pagesize);
        }

        [HttpGet]
        public IActionResult GetUserRole(int id)
        {
            var role = _roleRepository.Get(id);
            if (role == null || role.status != (int)RowState.Valid)
            {
                throw new BadRequestException(RequestEnum.RoleNotFound);
            }

            var result = Mapper<siger_user_roles, ResponseGetUserRole>.Map(role);
            return new ObjectResult(result);
        }

        [HttpGet]
        public IActionResult GetRoles(int type)
        {
            var roles = _roleRepository.GetList(q => q.type == type && q.status == (int)RowState.Valid);
            var response = new List<ResponseGetUserRole>();
            foreach (var role in roles)
            {
                response.Add(Mapper<siger_user_roles, ResponseGetUserRole>.Map(role));
            }
            
            return new ObjectResult(response);
        }

        [HttpPost]
        public IActionResult AddUserRole([FromBody]RequestAddRole request)
        {
            var isExist = _roleRepository.IsExist(q => q.name == request.name && q.status == (int)RowState.Valid);
            if (isExist)
            {
                throw new BadRequestException(RequestEnum.NameHasExist);
            }
            var role = new siger_user_roles();
            role.name = request.name;
            role.description = request.description;

            _roleRepository.Insert(role);

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

        [HttpPost]
        public IActionResult EditUserRole([FromBody]RequestUpdateRole request)
        {
            var role = _roleRepository.Get(request.id);
            if (role == null || role.status != (int)RowState.Valid)
            {
                throw new BadRequestException(RequestEnum.RoleNotFound);
            }
            var isExist = _roleRepository.IsExist(q => q.name == request.name && q.id != role.id && q.status == (int)RowState.Valid);
            if (isExist)
            {
                throw new BadRequestException(RequestEnum.NameHasExist);
            }
            role.name = request.name;
            role.description = request.description;

            _roleRepository.Update(role);

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

        [HttpPost]
        public IActionResult DeleteUserRole(int id)
        {
            var role = _roleRepository.Get(id);
            if (role == null || role.status != (int)RowState.Valid)
            {
                throw new BadRequestException(RequestEnum.RoleNotFound);
            }

            role.status = (int)RowState.Invalid;
            _roleRepository.Update(role);

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

        [HttpGet]
        public IActionResult GetProjectTypeRoleMaintenanceList(int roleid)
        {
            var list = _powerRepository.GetProjectTypePowers(roleid);

            return new ObjectResult(list);
        }

        [HttpGet]
        public IActionResult GetProjectTypeRoleMaintenanceListEx(int roleid)
        {
            var list = _powerRepository.GetUserPower(roleid);
            return new ObjectResult(list);
        }

        [HttpPost]
        public IActionResult SetProjectTypeRoleMaintenance([FromBody]RequestSetProjectTypeRoleMaintenance request)
        {
            var projectType = _projectTypeRepository.Get(request.roleid);
            if (projectType == null)
            {
                throw new BadRequestException(RequestEnum.ProjectTypeNotFound);
            }
            //先删除
            var powers = _userRolePowerRepository.GetList(q => q.roleid == projectType.id);
            foreach (var sigerUserRolePower in powers)
            {
                _userRolePowerRepository.Delete(sigerUserRolePower);
            }

            //删除已经分配出去的权限
            if (request.permissions != null)
            {
                var ids = (from permission in request.permissions where permission.HasValue select permission.Value).ToList();
                var excepts = powers.Select(m => m.powerid).Except(ids).ToList();
                if (excepts.Any())
                {
                    var projectSections = _projectSectionRepository.GetList(q => q.projectid == ProjectId && q.status == (int)RowState.Valid);
                    if (projectSections.Any())
                    {
                        foreach (var projectSection in projectSections.ToList())
                        {
                            //先删除部门，再删除岗位
                            var sectionpowers = _userRolePowerRepository.GetList(q => q.roleid == projectSection.role_id && excepts.Contains(q.powerid));
                            foreach (var sigerUserRolePower in sectionpowers)
                            {
                                _userRolePowerRepository.Delete(sigerUserRolePower);
                            }

                            var groups = _projectUserGroupRepository.GetList(q => q.sectionid == projectSection.id).ToList();
                            foreach (var usergroup in groups)
                            {
                                var usergrouppowers = _userRolePowerRepository.GetList(q => q.roleid == usergroup.role_id && excepts.Contains(q.powerid));
                                foreach (var sigerUserRolePower in usergrouppowers)
                                {
                                    _userRolePowerRepository.Delete(sigerUserRolePower);
                                }
                            }
                        }
                    }
                }
            }

            //再添加
            foreach (var permission in request.permissions)
            {
                var per = new siger_user_role_power
                {
                    roleid = request.roleid,
                    powerid = permission ?? 0
                };
                _userRolePowerRepository.Insert(per);
            }
            if (_unitOfWork.Commit() > 0)
            {
                return new ObjectResult(CommonEnum.Succefull);
            }
            throw new BadRequestException(CommonEnum.SystemExcetion);
        }

        [HttpGet]
        public IActionResult GetUserRoleMaintenanceList(int roleid)
        {
            var list = _powerRepository.GetUserRolePowers(roleid);

            return new ObjectResult(list);
        }

        [HttpPost]
        public IActionResult SetUserRoleMaintenance([FromBody]RequestSetProjectTypeRoleMaintenance request)
        {
            //先删除
            var powers = _userRolePowerRepository.GetList(q => q.roleid == request.roleid);
            foreach (var sigerUserRolePower in powers)
            {
                _userRolePowerRepository.Delete(sigerUserRolePower);
            }

            //再添加
            if (request.permissions != null)
            {
                foreach (var permission in request.permissions)
                {
                    var per = new siger_user_role_power
                    {
                        roleid = request.roleid,
                        powerid = permission ?? 0
                    };
                    _userRolePowerRepository.Insert(per);
                }
                if (_unitOfWork.Commit() > 0)
                {
                    return new ObjectResult(CommonEnum.Succefull);
                }
            }

            return new ObjectResult(CommonEnum.Succefull);
        }

        [HttpGet]
        public IActionResult GetNormalUserRoleMaintenanceList(int roleid)
        {
            var projectSection = _projectSectionRepository.Get(roleid);
            if (projectSection == null || projectSection.status != (int)RowState.Valid)
            {
                throw new BadRequestException(RequestEnum.SectionNotFound);
            }

            if (projectSection.role_id == 0)
            {
                throw new BadRequestException(RequestEnum.SectionRoleIdIsEmpty);
            }

            var project = _projectRepository.Get(ProjectId);
            if (project == null || project.status != (int)RowState.Valid)
            {
                throw new BadRequestException(RequestEnum.ProjectNotFound);
            }

            var projectType = _projectTypeRepository.Get(project.typeid);
            if (projectType == null || projectType.status != (int)RowState.Valid)
            {
                throw new BadRequestException(RequestEnum.ProjectTypeNotFound);
            }

            var list = _userRolePowerRepository.GetNormalUserRoleMaintenance(projectSection.role_id, projectType.id);

            return new ObjectResult(list);
        }

        [HttpPost]
        public IActionResult SetNormalUserRoleMaintenance([FromBody]RequestSetProjectTypeRoleMaintenance request)
        {
            var projectSection = _projectSectionRepository.Get(request.roleid);
            if (projectSection == null || projectSection.status != (int)RowState.Valid)
            {
                throw new BadRequestException(RequestEnum.SectionNotFound);
            }

            //先删除部门，再删除岗位
            var powers = _userRolePowerRepository.GetList(q => q.roleid == projectSection.role_id);
            foreach (var sigerUserRolePower in powers)
            {
                _userRolePowerRepository.Delete(sigerUserRolePower);
            }

            if (request.permissions != null)
            {
                var ids = (from permission in request.permissions where permission.HasValue select permission.Value).ToList();
                var excepts = powers.Select(m => m.powerid).Except(ids).ToList();

                var groups = _projectUserGroupRepository.GetList(q => q.sectionid == projectSection.id).ToList();
                foreach (var usergroup in groups)
                {
                    var usergrouppowers = _userRolePowerRepository.GetList(q => q.roleid == usergroup.role_id && excepts.Contains(q.powerid));
                    foreach (var sigerUserRolePower in usergrouppowers)
                    {
                        _userRolePowerRepository.Delete(sigerUserRolePower);
                    }
                }
            }

            //再添加
            if (request.permissions != null)
            {
                foreach (var permission in request.permissions)
                {
                    var per = new siger_user_role_power
                    {
                        roleid = projectSection.role_id,
                        powerid = permission ?? 0
                    };
                    _userRolePowerRepository.Insert(per);
                }

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

            return new ObjectResult(CommonEnum.Succefull);
        }

        [HttpPost]
        public IActionResult SetNormalUserGroupRoleMaintenance([FromBody]RequestSetProjectTypeRoleMaintenance request)
        {
            var projectGroup = _projectUserGroupRepository.Get(request.roleid);
            if (projectGroup == null || projectGroup.status != (int)RowState.Valid)
            {
                throw new BadRequestException(RequestEnum.UserGroupNotFound);
            }

            //先删除
            var powers = _userRolePowerRepository.GetList(q => q.roleid == projectGroup.role_id);
            foreach (var sigerUserRolePower in powers)
            {
                _userRolePowerRepository.Delete(sigerUserRolePower);
            }
            //再添加
            if (request.permissions != null)
            {
                foreach (var permission in request.permissions)
                {
                    var per = new siger_user_role_power
                    {
                        roleid = projectGroup.role_id ?? 0,
                        powerid = permission ?? 0
                    };
                    _userRolePowerRepository.Insert(per);
                }
                if (_unitOfWork.Commit() > 0)
                {
                    return new ObjectResult(CommonEnum.Succefull);
                }
            }

            return new ObjectResult(CommonEnum.Succefull);
        }

        [HttpGet]
        public IActionResult GetNormalSectionUserRoleMaintenanceList(int roleid)
        {
            var userGroup = _projectUserGroupRepository.Get(roleid);
            if (userGroup == null || userGroup.status != (int)RowState.Valid)
            {
                throw new BadRequestException(RequestEnum.UserGroupNotFound);
            }
            if (!userGroup.role_id.HasValue)
            {
                throw new BadRequestException(RequestEnum.SectionRoleIdIsEmpty);
            }
            var projectSection = _projectSectionRepository.Get(userGroup.sectionid);
            if (projectSection == null || projectSection.status != (int)RowState.Valid)
            {
                throw new BadRequestException(RequestEnum.SectionNotFound);
            }
            if (projectSection.role_id == 0)
            {
                throw new BadRequestException(RequestEnum.SectionRoleIdIsEmpty);
            }

            var list = _userRolePowerRepository.GetNormalUserRoleMaintenance(userGroup.role_id.Value, projectSection.role_id);

            return new ObjectResult(list);
        }

        [HttpPost]
        public IActionResult SetNormalSectionUserRoleMaintenance([FromBody]RequestSetProjectTypeRoleMaintenance request)
        {
            var userGroup = _projectUserGroupRepository.Get(request.roleid);
            if (userGroup == null || userGroup.status != (int)RowState.Valid)
            {
                throw new BadRequestException(RequestEnum.UserGroupNotFound);
            }
            //先删除
            var powers = _userRolePowerRepository.GetList(q => q.roleid == userGroup.role_id.Value);
            foreach (var sigerUserRolePower in powers)
            {
                _userRolePowerRepository.Delete(sigerUserRolePower);
            }
            //再添加
            if (request.permissions != null)
            {
                foreach (var permission in request.permissions)
                {
                    if (userGroup.role_id != null)
                    {
                        var per = new siger_user_role_power
                        {
                            roleid = userGroup.role_id.Value,
                            powerid = permission ?? 0
                        };
                        _userRolePowerRepository.Insert(per);
                    }
                }
                if (_unitOfWork.Commit() > 0)
                {
                    return new ObjectResult(CommonEnum.Succefull);
                }
            }

            return new ObjectResult(CommonEnum.Succefull);
        }


        [HttpGet]
        public IActionResult GetNormalUserRoleMaintenanceListEx(int roleid)
        {
            var projectSection = _projectSectionRepository.Get(roleid);
            if (projectSection == null || projectSection.status != (int)RowState.Valid)
            {
                throw new BadRequestException(RequestEnum.SectionNotFound);
            }

            if (projectSection.role_id == 0)
            {
                throw new BadRequestException(RequestEnum.SectionRoleIdIsEmpty);
            }

            var project = _projectRepository.Get(ProjectId);
            if (project == null || project.status != (int)RowState.Valid)
            {
                throw new BadRequestException(RequestEnum.ProjectNotFound);
            }

            var projectType = _projectTypeRepository.Get(project.typeid);
            if (projectType == null || projectType.status != (int)RowState.Valid)
            {
                throw new BadRequestException(RequestEnum.ProjectTypeNotFound);
            }

            var list = _userRolePowerRepository.GetNormalUserRoleMaintenanceTree(projectSection.role_id, projectType.id);

            return new ObjectResult(list);
        }

        [HttpGet]
        public IActionResult GetNormalSectionUserRoleMaintenanceListEx(int roleid)
        {
            var userGroup = _projectUserGroupRepository.Get(roleid);
            if (userGroup == null || userGroup.status != (int)RowState.Valid)
            {
                throw new BadRequestException(RequestEnum.UserGroupNotFound);
            }
            if (!userGroup.role_id.HasValue)
            {
                throw new BadRequestException(RequestEnum.SectionRoleIdIsEmpty);
            }
            var projectSection = _projectSectionRepository.Get(userGroup.sectionid);
            if (projectSection == null || projectSection.status != (int)RowState.Valid)
            {
                throw new BadRequestException(RequestEnum.SectionNotFound);
            }
            if (projectSection.role_id == 0)
            {
                throw new BadRequestException(RequestEnum.SectionRoleIdIsEmpty);
            }
            var project = _projectRepository.Get(ProjectId);
            if (project == null || project.status != (int)RowState.Valid)
            {
                throw new BadRequestException(RequestEnum.ProjectNotFound);
            }

            var projectType = _projectTypeRepository.Get(project.typeid);
            if (projectType == null || projectType.status != (int)RowState.Valid)
            {
                throw new BadRequestException(RequestEnum.ProjectTypeNotFound);
            }

            var list = _userRolePowerRepository.GetNormalUserGroupRoleMaintenanceTree(userGroup.role_id.Value, projectType.id, projectSection.role_id);

            return new ObjectResult(list);
        }

    }
}