package cn.service.system.impl;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
import cn.constant.CommonConst;
import cn.orm.abs.ISqlToyDao;
import cn.orm.abs.ICommonAPI;
import cn.orm.sqltoy.plus.Wrappers;
import cn.orm.sqltoy.plus.query.LambdaQueryWrapper;
import cn.orm.sqltoy.plus.query.QueryWrapper;
import cn.orm.sqltoy.plus.update.LambdaUpdateWrapper;
import cn.pojo.entity.TSysDept;
import cn.pojo.vo.TreeSelectVo;
import cn.pojo.vo.LoginUser;
import cn.service.system.IDeptService;
import cn.util.core.IsKit;
import cn.util.core.TypeKit;

@Repository("IDeptService")
public class DeptServiceImpl implements IDeptService
{	
	@Autowired
	private ISqlToyDao daoService;
	@Autowired
	private ICommonAPI sysBaseService;

	/**修改保存部门信息*/
	@Override
	public Boolean updateDept(TSysDept dept) 
	{
		//获取所选节点的父节点(父部门)的信息 ,最多一条记录
		LambdaQueryWrapper<TSysDept> queryWrapper = Wrappers.lambdaWrapper(TSysDept.class)
				.select(TSysDept::getDeptId)
				.select(TSysDept::getAncestors)
				.eq(TSysDept::getDeptId, dept.getParentId());
		TSysDept newParentDept = daoService.findOne(queryWrapper);

		//获取所选节点(当前部门),最多一条记录
		LambdaQueryWrapper<TSysDept> queryWrapper2 = Wrappers.lambdaWrapper(TSysDept.class)
				.select(TSysDept::getAncestors)
				.eq(TSysDept::getDeptId, dept.getDeptId());
		TSysDept oldDept = daoService.findOne(queryWrapper2);
		if (IsKit.isNotNullOrEmpty(newParentDept) && IsKit.isNotNullOrEmpty(oldDept)) {
			//祖级列表
			String newAncestors = newParentDept.getAncestors() + "," + newParentDept.getDeptId();
			String oldAncestors = oldDept.getAncestors();
			dept.setAncestors(newAncestors);
			//修改子元素关系(即修改祖级列表字段)
			_updateDeptChildren(dept.getDeptId(), newAncestors, oldAncestors);
		}
		//执行更新
		Long result1 = daoService.update(dept);
		Long result2 = 1l;
		//如果该部门是启用状态，则启用该部门的所有上级部门
		if (CommonConst.CHAR_NUM_0.equals(dept.getStatus())){
			/**修改该部门的父级部门状态*/
			LambdaUpdateWrapper<TSysDept> updateWrapper = Wrappers.lambdaUpdateWrapper(TSysDept.class)
					.set(TSysDept::getStatus, dept.getStatus())
					.in(TSysDept::getDeptId,TypeKit.strToList(dept.getAncestors()));
			result2 = daoService.update(updateWrapper);
		}
		return (result1 > 0 && result2 > 0);
	}

	/**新增部门节点需要插入到dept所在节点的下面*/
	@Override
	public Boolean insertDept(TSysDept dept)
	{
		/**获取父节点即dept所在节点。至多存在一个:原parent_id错误*/
		LambdaQueryWrapper<TSysDept> queryWrapper = Wrappers.lambdaWrapper(TSysDept.class)
				.select(TSysDept::getStatus)
				.select(TSysDept::getAncestors)
				.eq(TSysDept::getDeptId, dept.getParentId());
		TSysDept entity = daoService.findOne(queryWrapper);

		/** 如果父节点dept不为正常状态,则不允许新增子节点*/
		if (!CommonConst.CHAR_NUM_0.equals(entity.getStatus())) {
			//throw new BaseException("部门停用，不允许新增");
			return false;
		}
		//设置祖级列表id路径
		dept.setAncestors(entity.getAncestors() + "," + dept.getParentId());
        //设置默认正常状态  
		dept.setDelFlag("0");
		//save单个对象保存
		Object result = daoService.save(dept);
		return TypeKit.objToInt(result) > 0;
	}

	/**构建前端所需要部门列表下拉树结构*/
	@Override
	public List<TreeSelectVo> buildDeptTreeSelect(String roleId) 
	{
		//获取满足条件的部门信息表
		List<TSysDept> depts = getDeptListByRole(roleId);
		//转换为树形级联目录
		if(IsKit.isNullOrEmpty(depts)) {
			return null;
		}
		List<TSysDept> deptTrees = _buildDeptTree(depts);
		return deptTrees.stream().map(TreeSelectVo::new).collect(Collectors.toList());
	}

	/**获取满足条件的所有部门信息*/
	@Override
	public List<TSysDept> getDeptListByRole(String roleId) 
	{
		String deptId = "";
		//用户是否管理员
		if (!sysBaseService.isAdminByRoleId(roleId)) {
			//非管理员，获取登录者所在部门
			deptId = _getLoginUserDeptId();
		}
		//限制返回的部门状态为正常：注意.eq("del_flag",0).eq("status",0);
		QueryWrapper<TSysDept> queryWrapper = Wrappers.wrapper(TSysDept.class)
				.eq("delFlag",0).eq("status",0);
		//非管理员
		if(IsKit.isNotNullOrEmpty(deptId)) {
			queryWrapper.eq("deptId",deptId);
		}
		List<TSysDept> resultList = daoService.findList(queryWrapper);
		return resultList;
	}

	/**根据登陆用户信息获取其所在部门id*/
	private String _getLoginUserDeptId() 
	{	
		LoginUser loginUser = sysBaseService.getLoginUser();
		Map<String, Object> userMap = loginUser.getDept();
		return TypeKit.objToStr(userMap.get("deptId"));
	}
	/**构建前端所需要部门列表的树结构*/
	private List<TSysDept> _buildDeptTree(List<TSysDept> depts) 
	{
		List<TSysDept> returnList = new ArrayList<TSysDept>();
		//保存所有部门的ID
		List<Integer> tempList = new ArrayList<Integer>();
		for (TSysDept dept : depts) {
			tempList.add(dept.getDeptId());
		}
		for (Iterator<TSysDept> iterator = depts.iterator(); iterator.hasNext(); ) 
		{
			TSysDept dept = (TSysDept) iterator.next();
			/**查找父节点不在tempList中的记录，即该记录是整个部门结构中的根节点(顶级节点)
			 * 然后，从该节点(顶级节点)开始, 调用recursionFn遍历该父节点的所有子节点
			 * */
			if (!tempList.contains(dept.getParentId())) {
				_recursionFn(depts, dept);
				returnList.add(dept);
			}
		}
		if (returnList.isEmpty()) {
			returnList = depts;
		}
		return returnList;
	}
	/** 递归列表	
	 * list：所有记录
	 * root：根节点(顶级节点)记录
	 * */
	private void _recursionFn(List<TSysDept> list, TSysDept root)
	{
		/** 得到根节点(顶级节点)记录的子节点列表*/
		List<TSysDept> childList = _getChildList(list,root);
		root.setChildren(childList);
		/**递归遍历每条记录的子节点*/
		for (TSysDept tChild : childList) {
			if (_hasChild(list, tChild)) {
				_recursionFn(list, tChild);
			}
		}
	}
	/** 得到当前记录root的所有子节点列表*/
	private List<TSysDept> _getChildList(List<TSysDept> list, TSysDept root) 
	{
		List<TSysDept> tlist = new ArrayList<TSysDept>();
		Iterator<TSysDept> it = list.iterator();
		while (it.hasNext())
		{
			TSysDept n = (TSysDept) it.next();
			/**当前记录的父节点不空，且等于当前记录root的节点ID**/
			if (IsKit.isNotNull(n.getParentId()) && n.getParentId() == root.getDeptId()){
				tlist.add(n);
			}
		}
		return tlist;
	}

	/**判断是否有子节点 */
	private boolean _hasChild(List<TSysDept> list, TSysDept t) {
		return _getChildList(list, t).size() > 0 ? true : false;
	}


	/**
	 * 修改子元素关系(祖级列表)
	 * bigInteger   被修改的部门ID
	 * newAncestors 新的父ID集合
	 * oldAncestors 旧的父ID集合
	 */
	private void _updateDeptChildren(Integer deptId,String newAncestors, String oldAncestors)
	{
		/**根据ID查询所有子部门；deptId 部门ID；返回部门列表*/
		LambdaQueryWrapper<TSysDept> queryWrapper = Wrappers.lambdaWrapper(TSysDept.class)
				//逗号分割的字符串
				.in(TSysDept::getDeptId,TypeKit.strToList(newAncestors));
		List<TSysDept> children = daoService.findList(queryWrapper);


		for (TSysDept child : children) {
			child.setAncestors(child.getAncestors().replace(oldAncestors, newAncestors));
		}
		/**此分支没有调试
		 *  UPDATE t_sys_dept SET ancestors=(CASE dept_id WHEN dept_id THEN ancestors END)
		 *  where dept_id in(deptId) ?
		 * */
		if (IsKit.isNotNullOrEmpty(children)) {
			//修改子元素关系
			daoService.updateAll(children);
		}
	}

	@Override
	public TSysDept getDeptById(Long deptId)
	{
		LambdaQueryWrapper<TSysDept> queryWrapper = Wrappers.lambdaWrapper(TSysDept.class)
				.eq(TSysDept::getDeptId, deptId);
		return daoService.findOne(queryWrapper);
	}

	/**
	 * 构建前端所需要下拉树结构
	 * @param depts 部门列表
	 * @return 下拉树结构列表
	 */
	@Override
	public List<TreeSelectVo> buildDeptTreeSelect(List<TSysDept> depts) {
		if(IsKit.isNullOrEmpty(depts)) {
			return null;
		}
		List<TSysDept> deptTrees = _buildDeptTree(depts);
		return deptTrees.stream().map(TreeSelectVo::new).collect(Collectors.toList());
	}	

	/**
	 * 根据角色ID查询部门
	 * @param roleId 角色ID
	 * @return 选中部门列表
	 * 限制部门状态为正常
	 * @Select("select  CONCAT_WS (',',ancestors ,  dept_id) as ancestors from t_sys_dept a left join t_sys_role_dept b on a.dept_id =b.dept_id where a.del_flag<>2 and b.role_id=#{roleId}")
	 */
	@Override
	public List<TSysDept> selectDeptListByRoleId(Integer roleId) {
		Map<String, Object> whereMap = new HashMap<>();
		whereMap.put("roleId", roleId);
		return TypeKit.cast(daoService.getListBySql("sys_queryDeptListByRoleId",whereMap));
	}

}

