package com.yeejoin.precontrol.common.service.impl;

import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.pagehelper.util.StringUtil;
import com.yeejoin.amos.feign.systemctl.Systemctl;
import com.yeejoin.amos.feign.systemctl.model.DictionarieValueModel;
import com.yeejoin.precontrol.common.dto.CompanyDepartmentDto;
import com.yeejoin.precontrol.common.entity.Company;
import com.yeejoin.precontrol.common.entity.CompanyDepartment;
import com.yeejoin.precontrol.common.entity.Person;
import com.yeejoin.precontrol.common.entity.PersonAscription;
import com.yeejoin.precontrol.common.exception.BaseException;
import com.yeejoin.precontrol.common.mapper.CompanyDepartmentMapper;
import com.yeejoin.precontrol.common.service.ICompanyDepartmentService;
import com.yeejoin.precontrol.common.service.ICompanyService;
import com.yeejoin.precontrol.common.service.IPersonAscriptionService;
import com.yeejoin.precontrol.common.service.IPersonService;

/**
 * 部门信息 服务实现类
 *
 * @author duanwei
 * @date 2021-09-07
 */
@Service
public class CompanyDepartmentServiceImpl extends ServiceImpl<CompanyDepartmentMapper, CompanyDepartment>
		implements ICompanyDepartmentService {

	@Autowired
	IPersonAscriptionService iPersonAscriptionService;

	@Autowired
	ICompanyService iCompanyService;

	@Autowired
	IPersonService iPersonService;

	@Override
	public List<CompanyDepartmentDto> treeByCompanyId(Long companyId, String name) {
		List<CompanyDepartment> list = this
				.list(new LambdaQueryWrapper<CompanyDepartment>().eq(CompanyDepartment::getCompanyId, companyId));
		List<DictionarieValueModel> deptLevel = Systemctl.dictionarieClient.dictValues("FBS_DEPT_LEVEL").getResult();
		List<CompanyDepartmentDto> result = arrayToTree(list, 1L, deptLevel);
		if (StringUtils.isNotEmpty(name)) {
			return filterNode(result, name);
		} else {
			return result;
		}
	}

	private List<CompanyDepartmentDto> arrayToTree(List<CompanyDepartment> arr, Long parentId,
			List<DictionarieValueModel> deptLevel) {
		List<CompanyDepartmentDto> temp = new ArrayList<>();
		List<CompanyDepartment> treeArr = arr;
		treeArr.forEach(item -> {
			if (item.getParentId().longValue() == parentId.longValue()) {
				CompanyDepartmentDto companyDepartment = new CompanyDepartmentDto();
				BeanUtils.copyProperties(item, companyDepartment);
				companyDepartment.setKey(item.getId());
				companyDepartment.setLevelText(processLevel(deptLevel, item.getLevel()));
				List<CompanyDepartmentDto> children = arrayToTree(treeArr, companyDepartment.getId(), deptLevel);
				if (children.size() > 0) {
					companyDepartment.setChildren(children);
				}
				temp.add(companyDepartment);
			}
		});
		return temp;
	}

	/**
	 * 处理部门类型
	 * 
	 * @param deptLevel
	 * @param level
	 * @return
	 */
	private String processLevel(List<DictionarieValueModel> deptLevel, String level) {
		if (deptLevel != null && deptLevel.size() > 0 && StringUtil.isNotEmpty(level)) {
			for (DictionarieValueModel dictionarieValueModel : deptLevel) {
				if (level.equals(dictionarieValueModel.getDictDataKey())) {
					return dictionarieValueModel.getDictDataValue();
				}
			}
		}
		return "";
	}

	private List<CompanyDepartmentDto> filterNode(List<CompanyDepartmentDto> nodes, String name) {
		List<CompanyDepartmentDto> newNodes = new ArrayList<>();
		List<CompanyDepartmentDto> tagNodes = new ArrayList<>();
		for (CompanyDepartmentDto node : nodes) {
			if (node.getName() != null && node.getName().contains(name)) {
				newNodes.add(node);
			}
			if (node.getChildren() != null && node.getChildren().size() > 0) {
				List<CompanyDepartmentDto> retNodes = filterNode(node.getChildren(), name);
				if (retNodes.size() > 0) {
					node.setChildren(retNodes);
					newNodes.add(node);
				} else {
					// 没有子节点情况
					node.setChildren(null);
					// 标记,循环结束后删除
					tagNodes.add(node);
				}
			} else {
				tagNodes.add(node);
			}
		}
		nodes.removeAll(tagNodes);
		return newNodes;
	}

	@Override
	public boolean removeTreeById(Long id) {
		List<CompanyDepartment> list = getChildrenList(id);
		Set<Long> deptIds = list.stream().map(i -> i.getId()).collect(Collectors.toSet());
		deptIds.add(id);
		int count = iPersonAscriptionService
				.count(new LambdaQueryWrapper<PersonAscription>().in(PersonAscription::getDepartmentId, deptIds));
		if (count > 0) {
			throw new BaseException("部门或者子部门下存在人员,无法删除");
		}
		this.remove(new LambdaQueryWrapper<CompanyDepartment>().in(CompanyDepartment::getId, deptIds));
		return true;
	}

	private List<CompanyDepartment> getChildrenList(Long id) {
		List<CompanyDepartment> children = this
				.list(new LambdaQueryWrapper<CompanyDepartment>().eq(CompanyDepartment::getParentId, id));
		List<CompanyDepartment> childrens = new ArrayList<CompanyDepartment>();
		if (children == null) {
			children = new ArrayList<CompanyDepartment>();
		}
		for (CompanyDepartment companyDepartment : children) {
			childrens.addAll(getChildrenList(companyDepartment.getId()));
		}
		children.addAll(childrens);
		return children;
	}

	@Override
	public boolean saveOne(CompanyDepartment companyDepartment) {
		// 设置deptorgcode
		CompanyDepartment companyDepartmentMax = this.getOne(new LambdaQueryWrapper<CompanyDepartment>()
				.orderByDesc(CompanyDepartment::getDeptOrgCode).last("limit 1"));
		int deptorgcode = 1;
		if (companyDepartmentMax != null && companyDepartmentMax.getDeptOrgCode() != null) {
			deptorgcode = Integer.valueOf(companyDepartmentMax.getDeptOrgCode()) + 1;
		}
		companyDepartment.setDeptOrgCode(deptorgcode);
		// 设置orgcode
		CompanyDepartment companyDepartmentParent = null;
		if (companyDepartment.getParentId() == null) {
			companyDepartment.setParentId(1L);
		} else {
			companyDepartmentParent = this.getOne(new LambdaQueryWrapper<CompanyDepartment>()
					.eq(CompanyDepartment::getId, companyDepartment.getParentId()));
		}
		String orgcode = "";
		if (companyDepartmentParent != null) {
			orgcode = companyDepartmentParent.getOrgCode() + "*" + deptorgcode;
		} else {
			Company company = iCompanyService.getById(companyDepartment.getCompanyId());
			orgcode = company.getCompanyOrgCode() + "-" + deptorgcode;
		}
		companyDepartment.setOrgCode(orgcode);
		this.save(companyDepartment);
		return true;
	}

	@Override
	@Transactional
	public boolean updateOneById(CompanyDepartment companyDepartment) {
		CompanyDepartment companyDepartmentOld = this.getById(companyDepartment.getId());
		// 设置orgcode
		CompanyDepartment companyDepartmentParent = null;
		if (companyDepartment.getParentId() == null) {
			companyDepartment.setParentId(1L);
		} else {
			companyDepartmentParent = this.getOne(new LambdaQueryWrapper<CompanyDepartment>()
					.eq(CompanyDepartment::getId, companyDepartment.getParentId()));
		}
		String orgcode = "";
		if (companyDepartmentParent != null) {
			orgcode = companyDepartmentParent.getOrgCode() + "*" + companyDepartmentOld.getDeptOrgCode();
		} else {
			Company company = iCompanyService.getById(companyDepartment.getCompanyId());
			orgcode = company.getCompanyOrgCode() + "-" + companyDepartmentOld.getDeptOrgCode();
		}
		// 设置字节orgcode
		List<CompanyDepartment> list = getChildrenList(companyDepartment.getId());
		for (CompanyDepartment i : list) {
			i.setOrgCode(i.getOrgCode().replace(companyDepartment.getOrgCode(), orgcode));
		}
		companyDepartment.setOrgCode(orgcode);
		list.add(companyDepartment);
		this.updateBatchById(list);
		return true;
	}

	@Override
	public List<CompanyDepartmentDto> allChildrenList(Long departmentId) {
		return this.baseMapper.allChildrenList(departmentId);
	}

	@Override
	public int countChildrenPerson(Long departmentId, Set<String> roleIds, Long projectId) {
		List<CompanyDepartmentDto> children = this.baseMapper.allChildrenList(departmentId);
		List<Long> deptIds = children.stream().map(i -> i.getId()).collect(Collectors.toList());
		LambdaQueryWrapper<PersonAscription> awrapper = new LambdaQueryWrapper<PersonAscription>()
				.in(PersonAscription::getDepartmentId, deptIds);
		if (projectId != null) {
			awrapper.eq(PersonAscription::getProjectId, projectId);
		}
		List<PersonAscription> ascriptions = iPersonAscriptionService.list(awrapper);
		Set<Long> personIds = ascriptions.stream().map(i -> i.getPersonId()).collect(Collectors.toSet());
		if (personIds.isEmpty()) {
			return 0;
		}
		LambdaQueryWrapper<Person> wrapper = new LambdaQueryWrapper<Person>().in(Person::getId, personIds);
				if(!com.yeejoin.precontrol.common.utils.StringUtil.isEmpty(roleIds)) 
				{
					wrapper.and(iwrapper -> {
						for (String id : roleIds) {
							iwrapper.apply(id != null, "locate ('" + id + "',roles) > 0").or();
						}
					});
				}
				
		int count = iPersonService.count(wrapper);
		return count;
	}

}
