package com.hfkj.service.impl;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.hfkj.common.exception.ErrorCode;
import com.hfkj.common.exception.ErrorHelp;
import com.hfkj.common.exception.SysCode;
import com.hfkj.dao.SecMenuMapper;
import com.hfkj.dao.SecPermissionMapper;
import com.hfkj.dao.SecRolePermissionRelMapper;
import com.hfkj.entity.*;
import com.hfkj.model.CommonTreeModel;
import com.hfkj.model.MenuTreeModel;
import com.hfkj.model.TreeStateModel;
import com.hfkj.service.SecPermissionService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service("secPermissionService")
public class SecPermissionServiceImpl implements SecPermissionService {

	@Resource
	private SecRolePermissionRelMapper secRolePermissionRelMapper;

	@Resource
	private SecPermissionMapper secPermissionMapper;

	@Resource
	private SecMenuMapper secMenuMapper;


	@Override
	public List<MenuTreeModel> findMenuByUserId(Long userId) {
		// 根据用户id查询用户角色
		if(userId != null){
			// 查询用户的权限集合
			List<SecPermission> permissionList = secRolePermissionRelMapper.getPermissionListByUserId(userId);
			// 通过权限获取菜单
			if(permissionList != null && permissionList.size() != 0){
				List<Long> menuIds = new ArrayList<>();
				for(SecPermission pms : permissionList){
					if (pms.getPermissionCode().contains("MENU_")) {
						menuIds.add(pms.getMenuId());
					}
				}
				if (menuIds == null || menuIds.size() == 0) {
					return null;
				}
				// 查询顶级菜单
				SecMenuExample menuExample = new SecMenuExample();
				menuExample.createCriteria().andIdIn(menuIds).andMenuPSidIsNull();
				menuExample.setOrderByClause("menu_sort");
				List<SecMenu> topMenuList = secMenuMapper.selectByExample(menuExample);
				// 查询所有子级菜单
				SecMenuExample menuExample1 = new SecMenuExample();
				menuExample1.createCriteria().andIdIn(menuIds).andMenuPSidIsNotNull();
				menuExample1.setOrderByClause("menu_sort");
				List<SecMenu> sonMenuList = secMenuMapper.selectByExample(menuExample1);
				List<MenuTreeModel> menuTreeModelList = new ArrayList<>();
				if (topMenuList != null && topMenuList.size() != 0) {
					for (SecMenu menu : topMenuList) {
						MenuTreeModel menuTreeModel = new MenuTreeModel();
						menuTreeModel.setSid(menu.getId());
						menuTreeModel.setMenuName(menu.getMenuName());
						menuTreeModel.setMenuUrl(menu.getMenuUrl());
						menuTreeModel.setMenuUrlImg(menu.getMenuUrlImg());
						menuTreeModel.setMenuSort(menu.getMenuSort());
						menuTreeModel.setMenuDesc(menu.getMenuDesc());
						menuTreeModel.setMenuMobileUrl(menu.getMenuMobileUrl());
						menuTreeModel.setShowOnMobile(menu.getShowOnMobile());
						//构建树
						buildMenuTree(menuTreeModel,sonMenuList);
						menuTreeModelList.add(menuTreeModel);
					}
				}
				return menuTreeModelList;
			}
		}
		return new ArrayList<>();
	}

	@Override
	public List<SecPermission> findBtnByUserId(Long userId) {
		// 根据用户id查询用户角色
		if(userId != null) {
			// 查询用户的权限集合
			List<SecPermission> permissionList = secRolePermissionRelMapper.getPermissionListByUserId(userId);
			// 筛选按钮权限
			if(permissionList != null && permissionList.size() != 0){
				List<SecPermission> permissions = new ArrayList<>();
				for(SecPermission pms : permissionList){
					if (pms.getPermissionCode().contains("BTN_")) {
						permissions.add(pms);
					}
				}
				return permissions;
			}
		}
		return new ArrayList<>();
	}

	@Override
	public List<SecPermission> findPermissionByUserId(Long userId) {
		// 根据用户id查询用户角色
		if(userId != null) {
			// 查询用户的权限集合
			List<SecPermission> permissionList = secRolePermissionRelMapper.getPermissionListByUserId(userId);
			return permissionList;
		}
		return new ArrayList<>();
	}

	@Override
	public SecPermission findByMenuId(Long menuId) {
		SecPermissionExample example = new SecPermissionExample();
		example.createCriteria().andMenuIdEqualTo(menuId);
		List<SecPermission> list = secPermissionMapper.selectByExample(example);
		if (list == null || list.size() == 0) {
			return null;
		}else {
			return list.get(0);
		}
	}

	@Override
	public  List<CommonTreeModel> findAllMenuTree(Long allotRoleId) {
		//查询被分配角色已拥有的菜单
		SecRolePermissionRelExample example = new SecRolePermissionRelExample();
		example.createCriteria().andRoleIdEqualTo(allotRoleId);

		List<SecRolePermissionRel> rolePermissionRels = secRolePermissionRelMapper.selectByExample(example);
		List<Long> permissionIds = new ArrayList<>();
		List<SecPermission> permissionList;
		List<Long> menuIds = new ArrayList<>();
		if (rolePermissionRels != null && rolePermissionRels.size() != 0) {
			for (SecRolePermissionRel rel : rolePermissionRels) {
				permissionIds.add(rel.getPermissionId());
			}
			//查询被分配角色拥有的权限信息
			SecPermissionExample permissionExample = new SecPermissionExample();
			permissionExample.createCriteria().andIdIn(permissionIds);
			permissionList = secPermissionMapper.selectByExample(permissionExample);
			//查询拥有的菜单
			for (SecPermission permission: permissionList) {
				menuIds.add(permission.getMenuId());
			}
		}

		// 查询所有一级菜单
		SecMenuExample example1 = new SecMenuExample();
		example1.createCriteria().andMenuPSidIsNull().andMenuTypeEqualTo(0);
		example1.setOrderByClause("show_on_mobile, menu_sort");
		List<SecMenu> parentList = secMenuMapper.selectByExample(example1);
		//查询所有子级
		SecMenuExample example2 = new SecMenuExample();
		example2.createCriteria().andMenuPSidIsNotNull();
		example2.setOrderByClause("menu_sort");
		List<SecMenu> sonList = secMenuMapper.selectByExample(example2);
		List<CommonTreeModel> treeModelList = new ArrayList<>();
		if (parentList != null && parentList.size()!= 0) {
			for (SecMenu parentMenu : parentList) {
				CommonTreeModel commonTreeModel = new CommonTreeModel();
				if (menuIds.contains(parentMenu.getId())){
					commonTreeModel.setState(new TreeStateModel(true,false,false,false));
				}
				commonTreeModel.setId(parentMenu.getId());
				commonTreeModel.setText(parentMenu.getMenuDesc());
				commonTreeModel.setShowOnMobile(parentMenu.getShowOnMobile());
				buildTree(commonTreeModel,sonList,menuIds);
				treeModelList.add(commonTreeModel);
			}
			return treeModelList;
		}else{
			throw ErrorHelp.genException(SysCode.System, ErrorCode.UNKNOW_ERROR, "");
		}
	}

	@Override
	public List<CommonTreeModel> findMenuTreeByRoleId(Long roleId,Long allotRoleId) {
		//查询被分配角色已拥有的菜单
		SecRolePermissionRelExample relExample = new SecRolePermissionRelExample();
		SecRolePermissionRelExample.Criteria secRolePermissionRelCriteria = relExample.createCriteria();
		if(allotRoleId != null){
			secRolePermissionRelCriteria.andRoleIdEqualTo(allotRoleId);
		}

		List<SecRolePermissionRel> rolePermissionRelList = secRolePermissionRelMapper.selectByExample(relExample);
		List<Long> perIds = new ArrayList<>();
		List<SecPermission> permissions;
		List<Long> allotMenuIds = new ArrayList<>();
		if (rolePermissionRelList != null && rolePermissionRelList.size() != 0) {
			for (SecRolePermissionRel rel : rolePermissionRelList) {
				perIds.add(rel.getPermissionId());
			}
			//查询被分配角色拥有的权限信息
			SecPermissionExample perExample = new SecPermissionExample();
			perExample.createCriteria().andIdIn(perIds);
			permissions = secPermissionMapper.selectByExample(perExample);
			//查询拥有的菜单
			for (SecPermission permission: permissions) {
				allotMenuIds.add(permission.getMenuId());
			}
		}

		//查询主角色和权限关系
		SecRolePermissionRelExample example = new SecRolePermissionRelExample();
		SecRolePermissionRelExample.Criteria criteria = example.createCriteria();
		if(roleId != null){
			criteria.andRoleIdEqualTo(roleId);
		}

		List<SecRolePermissionRel> rolePermissionRels = secRolePermissionRelMapper.selectByExample(example);
		List<Long> permissionIds = new ArrayList<>();
		if (rolePermissionRels != null && rolePermissionRels.size() != 0) {
			for (SecRolePermissionRel rel : rolePermissionRels) {
				permissionIds.add(rel.getPermissionId());
			}
		}else {
			throw ErrorHelp.genException(SysCode.System, ErrorCode.MENU_TREE_HAS_NOT_ERROR, "");
		}
		//查询主角色拥有的权限信息
		SecPermissionExample permissionExample = new SecPermissionExample();
		permissionExample.createCriteria().andIdIn(permissionIds);
		List<SecPermission> permissionList = secPermissionMapper.selectByExample(permissionExample);
		//查询拥有的菜单
		List<Long> menuIds = new ArrayList<>();
		for (SecPermission permission: permissionList) {
			menuIds.add(permission.getMenuId());
		}

		// 查询所有一级菜单
		SecMenuExample menuExample = new SecMenuExample();
		menuExample.createCriteria().andMenuPSidIsNull().andMenuTypeEqualTo(0).andIdIn(menuIds);
		List<SecMenu> parentList = secMenuMapper.selectByExample(menuExample);
		//查询所有子级
		SecMenuExample example1 = new SecMenuExample();
		example1.createCriteria().andMenuPSidIsNotNull().andIdIn(menuIds);
		List<SecMenu> sonList = secMenuMapper.selectByExample(example1);
		List<CommonTreeModel> treeModelList = new ArrayList<>();
		if (parentList != null && parentList.size()!= 0) {
			for (SecMenu parentMenu : parentList) {
				CommonTreeModel commonTreeModel = new CommonTreeModel();
				if (allotMenuIds.contains(parentMenu.getId())){
					commonTreeModel.setState(new TreeStateModel(true,false,false,false));
				}
				commonTreeModel.setText(parentMenu.getMenuDesc());
				commonTreeModel.setId(parentMenu.getId());
				commonTreeModel.setShowOnMobile(parentMenu.getShowOnMobile());
				buildTree(commonTreeModel,sonList,allotMenuIds);
				treeModelList.add(commonTreeModel);
			}
			return treeModelList;
		}else{
			throw ErrorHelp.genException(SysCode.System, ErrorCode.UNKNOW_ERROR, "");
		}
	}

	@Override
	public List<CommonTreeModel> getAllMenuTree(Integer showOnMobile) {

		List<CommonTreeModel> treeModelList = new ArrayList<>();
		// 查询所有一级菜单
		SecMenuExample example1 = new SecMenuExample();
		example1.createCriteria().andMenuPSidIsNull().andMenuTypeEqualTo(0).andShowOnMobileEqualTo(showOnMobile);
		example1.setOrderByClause("show_on_mobile, menu_sort");
		List<SecMenu> parentList = secMenuMapper.selectByExample(example1);

		//查询所有子级
		SecMenuExample example2 = new SecMenuExample();
		example2.createCriteria().andMenuPSidIsNotNull();
		example2.setOrderByClause("menu_sort");
		List<SecMenu> sonList = secMenuMapper.selectByExample(example2);

		CommonTreeModel commonTreeModel = null;
		if (parentList != null && parentList.size()!= 0) {
			for (SecMenu parentMenu : parentList) {
				commonTreeModel = new CommonTreeModel();
				commonTreeModel.setId(parentMenu.getId());
				commonTreeModel.setText(parentMenu.getMenuName());
				commonTreeModel.setShowOnMobile(parentMenu.getShowOnMobile());
				buildTree(commonTreeModel,sonList,null);
				treeModelList.add(commonTreeModel);
			}
			return treeModelList;
		}
		return null;
	}

	@Override
	public PageInfo<SecPermission> findPage(String permissionName, Integer type, Integer pageNum, Integer pageSize) {
		SecPermissionExample example = new SecPermissionExample();
		SecPermissionExample.Criteria criteria = example.createCriteria();
		if (StringUtils.isNotBlank(permissionName)) {
			criteria.andPermissionNameLike("%" + permissionName + "%");
		}
		if(type != null && type == 1){
			criteria.andPermissionCodeLike("%MENU_%");
		}
		if(type != null && type == 2){
			criteria.andPermissionCodeLike("%BTN_%");
		}
		example.setOrderByClause("menu_id ASC, sort ASC");
		PageHelper.startPage(pageNum, pageSize);
		return new PageInfo<SecPermission>(secPermissionMapper.selectByExample(example));
	}

	@Override
	public List<SecPermission> getPermissions() {
		SecPermissionExample example = new SecPermissionExample();
		example.setOrderByClause("menu_id ASC, sort ASC");
		return secPermissionMapper.selectByExample(example);
	}


	@Override
	public List<SecPermission> getNoPermissionsByRoleId(Long roleId) {
		/**----获取permissionIds start-----**/
		SecRolePermissionRelExample relExample = new SecRolePermissionRelExample();
		relExample.createCriteria().andRoleIdEqualTo(roleId);
		List<SecRolePermissionRel> rprs = secRolePermissionRelMapper.selectByExample(relExample);
		List<Long> permissionIds = new ArrayList<Long>();
		if(rprs != null && rprs.size() != 0){
			for(SecRolePermissionRel rel:rprs){
				permissionIds.add(rel.getPermissionId());
			}
		}
		/**----获取permissionIds end-----**/
		if(permissionIds.size() != 0){
			SecPermissionExample permissionExample = new SecPermissionExample();
			permissionExample.createCriteria().andIdNotIn(permissionIds);
			permissionExample.setOrderByClause("sort");
			return secPermissionMapper.selectByExample(permissionExample);
		}else{
			SecPermissionExample permissionExample = new SecPermissionExample();
			permissionExample.createCriteria().andIdIsNotNull();
			permissionExample.setOrderByClause("sort");
			return secPermissionMapper.selectByExample(permissionExample);
		}
	}

	@Override
	public List<SecPermission> getPermissionsByRoleId(Long roleId) {
		/**----获取permissionIds start-----**/
		SecRolePermissionRelExample relExample = new SecRolePermissionRelExample();
		relExample.createCriteria().andRoleIdEqualTo(roleId);
		List<SecRolePermissionRel> rprs = secRolePermissionRelMapper.selectByExample(relExample);
		List<Long> permissionIds = new ArrayList<Long>();
		if(rprs != null && rprs.size() != 0){
			for(SecRolePermissionRel rel:rprs){
				permissionIds.add(rel.getPermissionId());
			}
		}
		/**----获取permissionIds end-----**/
		if(permissionIds.size() != 0){
			SecPermissionExample permissionExample = new SecPermissionExample();
			permissionExample.createCriteria().andIdIn(permissionIds);
			permissionExample.setOrderByClause("sort");
			return secPermissionMapper.selectByExample(permissionExample);
		}
		return null;
	}

	@Override
	public List<Long> findPmsIds(List<Long> menus) {
		SecPermissionExample example = new SecPermissionExample();
		example.createCriteria().andMenuIdIn(menus);
		List<SecPermission> permissionList = secPermissionMapper.selectByExample(example);

		if (permissionList != null && permissionList.size() != 0) {
			List<Long> pmsIds = new ArrayList<>();
			for (SecPermission permission : permissionList) {
				pmsIds.add(permission.getId());
			}
			return pmsIds;
		}else {
			return null;
		}
	}

	@Override
	@Transactional(propagation = Propagation.REQUIRED,isolation = Isolation.DEFAULT,timeout=36000,rollbackFor=Exception.class)
	public void assignPmsToRole(Long roleId, List<Long> pmsIds) {
		if(roleId == null || pmsIds == null) {
			return;
		}
		//删除原来的关系
		SecRolePermissionRelExample relExample = new SecRolePermissionRelExample();
		relExample.createCriteria().andRoleIdEqualTo(roleId);
		List<SecRolePermissionRel> dbRels = secRolePermissionRelMapper.selectByExample(relExample);
		if (dbRels != null && dbRels.size() != 0) {
			for (SecRolePermissionRel rel : dbRels) {
				secRolePermissionRelMapper.deleteByPrimaryKey(rel.getId());
			}
		}
		//增加新增的权限
		for(Long pmsId : pmsIds){
			SecRolePermissionRel rel = new SecRolePermissionRel();
			rel.setRoleId(roleId);
			rel.setPermissionId(pmsId);
			secRolePermissionRelMapper.insert(rel);
		}
	}

	@Override
	public void deleteRolePms(Long roleId) {
		SecRolePermissionRelExample relExample = new SecRolePermissionRelExample();
		relExample.createCriteria().andRoleIdEqualTo(roleId);
		List<SecRolePermissionRel> dbRels = secRolePermissionRelMapper.selectByExample(relExample);
		if (dbRels != null && dbRels.size() != 0) {
			for (SecRolePermissionRel rel : dbRels) {
				secRolePermissionRelMapper.deleteByPrimaryKey(rel.getId());
			}
		}
	}

	@Override
	@Transactional(propagation = Propagation.REQUIRED,isolation = Isolation.DEFAULT,timeout=36000,rollbackFor=Exception.class)
	public void assignTemplatePmsToRole(Long roleId, List<Long> newRolePermissionRelIds) {
		//原角色模板权限
		SecRolePermissionRelExample secRolePermissionRelExample = new SecRolePermissionRelExample();
		secRolePermissionRelExample.createCriteria().andRoleIdEqualTo(roleId);
		List<SecRolePermissionRel> initialRolePermissionRels = secRolePermissionRelMapper.selectByExample(secRolePermissionRelExample);
		List<Long> initialRolePermissionRelIds = new ArrayList<>();
		// 原来模板有无权限
		if(initialRolePermissionRels != null && initialRolePermissionRels.size() > 0){

			Map<String,String> map = null;
			for (SecRolePermissionRel secRolePermissionRel : initialRolePermissionRels){
				initialRolePermissionRelIds.add(secRolePermissionRel.getPermissionId());
			}

			//从新的权限中筛选出删除的权限
			for (Long initialRolePermissionRelId : initialRolePermissionRelIds){
				if(newRolePermissionRelIds.contains(initialRolePermissionRelId) == false){
					Integer status = this.deleteRolePmsByRoleAndPms(roleId,initialRolePermissionRelId);
					if(status != 1){
						throw ErrorHelp.genException(SysCode.System, ErrorCode.DELETE_DATA_ERROR, "");
					}
					map = new HashMap<>();
					map.put("roleId",roleId.toString());
					map.put("permissionId",initialRolePermissionRelId.toString());
					//删除已分配出去的权限
					this.deleteTemplatePermission(map);
				}
			}

			//从新的权限中筛选出新的权限
			for (Long newRolePermissionRelId : newRolePermissionRelIds){
				if(initialRolePermissionRelIds.contains(newRolePermissionRelId) == false){
					SecRolePermissionRel rel = new SecRolePermissionRel();
					rel.setRoleId(roleId);
					rel.setPermissionId(newRolePermissionRelId);
					secRolePermissionRelMapper.insert(rel);
				}
			}

		}else{
			//从新的权限中筛选出新的权限
			for (Long newRolePermissionRelId : newRolePermissionRelIds){
				SecRolePermissionRel rel = new SecRolePermissionRel();
				rel.setRoleId(roleId);
				rel.setPermissionId(newRolePermissionRelId);
				secRolePermissionRelMapper.insert(rel);
			}
		}
	}


	@Override
	public Integer deleteRolePmsByRoleAndPms(Long roleId, Long pmsId) {
		SecRolePermissionRelExample relExample = new SecRolePermissionRelExample();
		relExample.createCriteria().andRoleIdEqualTo(roleId).andPermissionIdEqualTo(pmsId);
		List<SecRolePermissionRel> secRolePermissionRels = secRolePermissionRelMapper.selectByExample(relExample);

		if(secRolePermissionRels != null && secRolePermissionRels.size() > 0){
			secRolePermissionRelMapper.deleteByPrimaryKey(secRolePermissionRels.get(0).getId());
			return 1;
		}
		return 0;
	}

	@Override
	public void deleteTemplatePermission(Map<String, String> map) {
		secPermissionMapper.deleteTemplatePermission(map);
	}

	public void buildTree(CommonTreeModel parent, List<SecMenu> secMenuList, List<Long> menuIds) {
		secMenuList.forEach(secMenu -> {
			if (secMenu.getMenuPSid().equals(parent.getId())) {
				CommonTreeModel child = new CommonTreeModel();
				if (menuIds != null && menuIds.contains(secMenu.getId())){
					child.setState(new TreeStateModel(true,false,false,false));
				}
				child.setId(secMenu.getId());
				child.setText(secMenu.getMenuName());
				child.setpId(parent.getId());
				child.setShowOnMobile(secMenu.getShowOnMobile());
				parent.add(child);
				buildTree(child,secMenuList,menuIds);
			}
		});
	}

	/**
	 *
	 * @Title: BuildMenuTree
	 * @Description: TODO(构建菜单树)
	 * @author: 杜江
	 * @param: [menuTreeModel, sonMenuList]
	 * @return: void
	 * @throws
	 */
	public void buildMenuTree(MenuTreeModel menuTreeModel , List<SecMenu> sonMenuList) {
		sonMenuList.forEach(menu -> {
			if (menu.getMenuPSid().equals(menuTreeModel.getSid())) {
				MenuTreeModel child = new MenuTreeModel();
				child.setSid(menu.getId());
				child.setMenuName(menu.getMenuName());
				child.setMenuUrl(menu.getMenuUrl());
				child.setMenuUrlImg(menu.getMenuUrlImg());
				child.setMenuSort(menu.getMenuSort());
				child.setMenuDesc(menu.getMenuDesc());
				child.setMenuPSid(menu.getMenuPSid());
				child.setParentName(menuTreeModel.getMenuName());
				child.setMenuMobileUrl(menu.getMenuMobileUrl());
				child.setShowOnMobile(menu.getShowOnMobile());
				menuTreeModel.add(child);
				buildMenuTree(child,sonMenuList);
			}
		});
	}
}
