package com.lz.modules.flow.service.impl;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.google.common.collect.Maps;
import com.lz.common.utils.ISelect;
import com.lz.common.utils.PageUtils;
import com.lz.common.utils.R;
import com.lz.common.utils.StringUtil;
import com.lz.modules.app.dto.StaffSimpleDto;
import com.lz.modules.app.entity.DepartmentsEntity;
import com.lz.modules.app.entity.StaffSimpleInfo;
import com.lz.modules.app.service.DepartmentsService;
import com.lz.modules.app.service.StaffOccupationService;
import com.lz.modules.app.service.StaffService;
import com.lz.modules.flow.dao.EvaluationGroupMapper;
import com.lz.modules.flow.dao.EvaluationStartStaffMapper;
import com.lz.modules.flow.entity.EvaluationGroup;
import com.lz.modules.flow.entity.FlowStart;
import com.lz.modules.flow.entity.StaffRole;
import com.lz.modules.flow.entity.StaffRoleEvaluationGroup;
import com.lz.modules.flow.req.EvaluationGroupReq;
import com.lz.modules.flow.service.EvaluationGroupService;
import com.lz.modules.flow.service.FlowStartService;
import com.lz.modules.flow.service.StaffRoleEvaluationGroupService;
import com.lz.modules.flow.service.StaffRoleService;
import com.lz.modules.performance.dto.CheckStaffDto;
import com.lz.modules.performance.req.CheckStaffReq;
import com.lz.modules.sys.entity.SysUserEntity;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Supplier;
import java.util.function.ToLongFunction;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import static java.util.stream.Collectors.toList;

/**
* <p>
* 考评组表 服务类
* </p>
*
* @author quyixiao
* @since 2020-10-13
*/
@Slf4j
@Service
public class EvaluationGroupServiceImpl extends ServiceImpl<EvaluationGroupMapper, EvaluationGroup> implements EvaluationGroupService {


    @Autowired
	private EvaluationGroupMapper evaluationGroupMapper;
    @Autowired
	private StaffService staffService;
    @Autowired
	private StaffOccupationService staffOccupationService;

    @Autowired
	private EvaluationGroupService evaluationGroupService;

    @Autowired
	private DepartmentsService departmentsService;

    @Autowired
	private FlowStartService flowStartService;

    @Autowired
	private EvaluationStartStaffMapper evaluationStartStaffMapper;

    @Autowired
	private StaffRoleService staffRoleService;

    @Autowired
	private StaffRoleEvaluationGroupService staffRoleEvaluationGroupService;



	@Override
	public EvaluationGroup selectEvaluationGroupById(Long id){
		return evaluationGroupMapper.selectEvaluationGroupById(id);
	}



	@Override
	public Long insertEvaluationGroup(EvaluationGroup evaluationGroup){
		return evaluationGroupMapper.insertEvaluationGroup(evaluationGroup);
	}



	@Override
	public int updateEvaluationGroupById(EvaluationGroup evaluationGroup){
		return evaluationGroupMapper.updateEvaluationGroupById(evaluationGroup);
	}



	@Override
	public int updateCoverEvaluationGroupById(EvaluationGroup evaluationGroup){
		return evaluationGroupMapper.updateCoverEvaluationGroupById(evaluationGroup);
	}



	@Override
	public R deleteEvaluationGroupById(Long id){
		evaluationGroupMapper.deleteEvaluationGroupById(id);
		return R.ok();
	}

	@Override
	public PageUtils selectEvaluationGroupByReq(EvaluationGroupReq req, SysUserEntity sysUserEntity){
		List<Long> gIds = null;
		if(req.getStartId() != null){//发起评分时调用，传发起的id
			FlowStart flowStart = flowStartService.selectFlowStartById(req.getStartId());
			if(flowStart == null){
				return null;
			}
			gIds = Arrays.stream(flowStart.getGroupIds().split(","))
					.map(new Function<String, Long>() {
						@Override
						public Long apply(String s) {
							return Long.parseLong(s);
						}
					})
					.collect(Collectors.toList());
		}else{
			//考评组管理
			List<StaffRole> staffRoles = staffRoleService.selectAllByStaffId(sysUserEntity.getUserId());//一个人只会有一个
			if(staffRoles.size() == 0){
				log.info("非绩效管理员登录查询");
				return null;
			}
			if(staffRoles.get(0).getEvaluationGroupId().longValue() != 0L){//管理指定考评组的
				List<StaffRoleEvaluationGroup> staffRoleEvaluationGroups =
						staffRoleEvaluationGroupService.selectStaffRoleEvaluationsGroupByStaffRoles(staffRoles);
				if(staffRoleEvaluationGroups.size() == 0){
					log.info("查询的管理组为空");
					return null;
				}

				gIds = new ArrayList<>();
				for (StaffRoleEvaluationGroup staffRoleEvaluationGroup:staffRoleEvaluationGroups
				) {
					if(staffRoleEvaluationGroup.getEvaluationGroupId().longValue() == 0l){//管理所有组
						gIds = null;
						log.info("管理所有组");
						break;
					}
					gIds.add(staffRoleEvaluationGroup.getEvaluationGroupId());//管理特定组

				}
			}

		}
		List<Long> finalGIds = gIds;
		PageUtils pageUtils = PageUtils.startPage(req.getCurrPage(), req.getPageSize())
				.doSelect(page -> evaluationGroupMapper.seleteEvaluationGroupByReq(page, req, finalGIds));
		//下面实时统计考核人数
		List<EvaluationGroup> groups = pageUtils.getList();
		for (EvaluationGroup group:groups
			 ) {
			List<String> ids = evaluationGroupService.selectAllStaffIdsByGroupId(group.getId());
			group.setCounts(ids.size());
			//是否通知评分
			if(req.getStartId()!=null){
				EvaluationGroup scoreGroup = evaluationGroupMapper.selectEvaluationGroupByCopyId(group.getId(),req.getStartId());
				if(scoreGroup!=null){
					int i = evaluationStartStaffMapper.existByStartIdAndEvaluationId(req.getStartId(),scoreGroup.getId());
					if(i>0){
						group.setScore(1);
					}
				}
			}
		}
		return pageUtils;
	}


	@Override
	public List<String> selectAllStaffIdsByGroupId(Long id) {
		EvaluationGroup evaluationGroup = this.selectEvaluationGroupById(id);
		if(evaluationGroup ==null ){
			return Collections.EMPTY_LIST;
		}
		return getStaffIdsByGroup(evaluationGroup);
	}


	private List<String> getStaffIdsByGroup(EvaluationGroup evaluationGroup){
		String depIds = evaluationGroup.getDepIds();
		Set<String> allDeparmentIds = new HashSet<>();
		if(StringUtils.isNotBlank(depIds)){
			String[] split = depIds.split(",");
			for(String s:split){
				List<String> strings = staffService.selectAllDeparmentIdsByDepartmentParentId(s);
				allDeparmentIds.addAll(strings);
			}
		}
		List<String> depStaffIds = staffService.staffsByAllDeparmentIds(new ArrayList<>(allDeparmentIds));

		String staffIds = evaluationGroup.getStaffIds();
		if(StringUtils.isNotBlank(staffIds)){
			String[] split = staffIds.split(",");
			depStaffIds.addAll(Arrays.asList(split));
		}
		String outIds = evaluationGroup.getOutIds();
		if(StringUtils.isNotBlank(outIds)){
			String[] split = outIds.split(",");
			depStaffIds.removeAll(Arrays.asList(split));
		}
		List<String> distDepStaffIds = new ArrayList<>(new HashSet(depStaffIds));
		//去除离职
		List<String> data = staffOccupationService.removeDimissionStaffByStaffIds(distDepStaffIds);
		return data;
	}
	@Override
	public List<EvaluationGroup> selectEvaluationGroupByIds(List<Long> ids){
		return evaluationGroupMapper.selectEvaluationGroupByIds(ids);
	}


	@Override
	public List<EvaluationGroup> selectEvaluationGroupByNotIds(List<Long> ids){
		return evaluationGroupMapper.selectEvaluationGroupByNotIds(ids);
	}

	@Override
	public EvaluationGroup selectEvaluationGroupByName(String name){
		return evaluationGroupMapper.selectEvaluationGroupByName(name);
	}

	@Override
	public List<StaffSimpleInfo> selectAllStaffSimpleInfoByGroupId(EvaluationGroup evaluationGroup){
		List<StaffSimpleInfo> staffSimpleInfos = new ArrayList<>();
		//下面获取部门人员
		if(!StringUtil.isEmpty(evaluationGroup.getDepIds())){


			List<String> dIds = Arrays.stream(evaluationGroup.
					getDepIds().split(",")).map(new Function<String, String>() {
				@Override
				public String apply(String s) {
					return s;
				}
			}).collect(Collectors.toList());
			//获取所有部门信息，包括子部门
			List<DepartmentsEntity> departmentsEntities = departmentsService.selectAllDepartmentIds(dIds);
			//下面获取部门下面的所有在职人员
			for (DepartmentsEntity depart:departmentsEntities
				 ) {

				List<StaffSimpleInfo> staffSimpleInfos1 = staffService.selectAllStaffSimpleInfos(depart);
				if(staffSimpleInfos1 != null){
					staffSimpleInfos.addAll(staffSimpleInfos1);
				}
			}
		}

		//下面获取指定人员
		if(!StringUtil.isEmpty(evaluationGroup.getStaffIds())){

			List<Long> sIds = Arrays.stream(evaluationGroup.getStaffIds()
			.split(",")).map(new Function<String, Long>() {
				@Override
				public Long apply(String s) {
					return Long.parseLong(s);
				}
			}).collect(Collectors.toList());
			List<StaffSimpleInfo> staffSimpleInfos1 = staffService.selectStaffSimpleInfos(sIds);
			if(staffSimpleInfos1 != null){
				staffSimpleInfos.addAll(staffSimpleInfos1);
			}
		}
		//下面去重
		if(staffSimpleInfos.size() > 1){
			//下面去除跨部门的人员，只保留第一次添加进来的人员
			Map<Long, StaffSimpleInfo> staffSimpleInfoMap =
					staffSimpleInfos.stream().collect(Collectors.toMap(StaffSimpleInfo::getId, Function.identity(), (e, replace) -> e));
			//下面删除排除人员信息
			if(!StringUtil.isEmpty(evaluationGroup.getOutIds())){
				List<Long> oIds = Arrays.stream(evaluationGroup.getOutIds().split(",")).map(new Function<String, Long>() {
					@Override
					public Long apply(String s) {
						return Long.parseLong(s);
					}
				}).collect(Collectors.toList());

				for (Long id:oIds
					 ) {
					staffSimpleInfoMap.remove(id);
				}
			}


			staffSimpleInfos = staffSimpleInfoMap.values().stream().collect(Collectors.toList());
		}


		return staffSimpleInfos;
	}


	@Override
	public void deleteByCopyIds(List<Long> ids,Long startId) {
		evaluationGroupMapper.deleteByCopyIds(ids,startId);
	}


	@Override
	public R checkStaff(CheckStaffReq checkStaffReq) {
		EvaluationGroup evaluationGroup = new EvaluationGroup();
		BeanUtils.copyProperties(checkStaffReq,evaluationGroup);
		//本次参加人员
		List<String> staffIdsByGroup = getStaffIdsByGroup(evaluationGroup);
		//其他组全部成员
		List<String> allStaffIdsByGroup = new ArrayList<>();

		//获取其他组成员
		List<Long> ids  = new ArrayList<>();
		if(evaluationGroup.getId()!=null){
			ids.add(evaluationGroup.getId());
		}
		List<EvaluationGroup> evaluationGroups = evaluationGroupMapper.selectEvaluationGroupByNotIds(ids);
		//根据组id成员分组
		Map<Long,List<String>> map = Maps.newHashMap();
		if(CollectionUtils.isNotEmpty(evaluationGroups)){
			evaluationGroups.forEach(evaluationGroup1 -> {
                List<String> staffIds = getStaffIdsByGroup(evaluationGroup1);
                allStaffIdsByGroup.addAll(staffIds);
				map.put(evaluationGroup1.getId(),staffIds);

			});
		}

		//是否存在其他组成员
		staffIdsByGroup.retainAll(allStaffIdsByGroup);
		if(CollectionUtils.isNotEmpty(staffIdsByGroup)){
			List<Long> longCollect = staffIdsByGroup.stream().distinct().map(s -> Long.valueOf(s)).collect(toList());
			List<StaffSimpleDto> staffSimpleDtos = staffService.selectStaffSimpleInfoByIds(longCollect);
			String notInGroupNames = StringUtil.EMPTY;
			for(StaffSimpleDto dto:staffSimpleDtos){
				notInGroupNames = notInGroupNames + dto.getName() + " ";
			}

			if(evaluationGroup.getConfirm()==0){

				return R.error(504,notInGroupNames + "已在其他类型为月度的考评组中，是否改为到此考评组中进行考核").put("data",staffSimpleDtos);
			}

			List<String> stringCollect = staffIdsByGroup.stream().distinct().collect(toList());
			evaluationGroups.forEach(evaluationGroup12 -> {
                List<String> staffs = map.get(evaluationGroup12.getId());
                //如果组里面有他，删除掉
				staffs.retainAll(stringCollect);
                if(CollectionUtils.isNotEmpty(staffs)){
					//添加到保存时添加
                    //删除存在得
					log.info("需删除其他组信息，staffs:" + JSON.toJSONString(staffs));
                    removeStaffsToAssessGroup(stringCollect,evaluationGroup12);
                }

            });
			return R.ok();

		}
		//直接添加
		return R.ok();
	}

	private int removeStaffsToAssessGroup(List<String> ids,EvaluationGroup group) {
		String staffIds = group.getStaffIds();
		String outIds = group.getOutIds();
		//删除选中人员
        if(StringUtil.isNotBlank(staffIds)){
			String[] staffs = staffIds.split(",");
			Set<String> staffsSet = new HashSet(Arrays.asList(staffs));
			staffsSet.removeAll(ids);
			group.setStaffIds(StringUtils.join(staffsSet, ","));
		}

		//增加排除人员
		if(StringUtil.isBlank(outIds)){
			group.setOutIds(StringUtils.join(ids, ","));
		}
		else {
			String[] outs = outIds.split(",");
			Set<String> outsSet = new HashSet(Arrays.asList(outs));
			outsSet.addAll(ids);
			group.setOutIds(StringUtils.join(outsSet, ","));
		}

		return evaluationGroupMapper.updateById(group);
	}

	@Override
	public String getEvaluationCopyIdsByEvaluationIds(String evaluationIds,Long startId) {
		if(StringUtil.isBlank(evaluationIds)){
			return StringUtil.EMPTY;
		}
		List<Long> ids = evaluationGroupMapper.selectIdsByCopyIds(evaluationIds,startId);
		if(CollectionUtils.isEmpty(ids)){
			return StringUtil.EMPTY;
		}
		return StringUtils.join(ids,",");
	}

	@Override
	public EvaluationGroup selectEvaluationGroupByCopyId(Long copyId, Long startId){
		return evaluationGroupMapper.selectEvaluationGroupByCopyId(copyId, startId);
	}
}
