package com.ym.mec.biz.service.impl;

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

import com.ym.mec.biz.dal.enums.GroupType;
import com.ym.mec.biz.service.ImUserFriendService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.ym.mec.auth.api.client.SysUserFeignService;
import com.ym.mec.auth.api.entity.SysUser;
import com.ym.mec.auth.api.enums.YesOrNoEnum;
import com.ym.mec.biz.dal.dao.ClassGroupDao;
import com.ym.mec.biz.dal.dao.EmployeeDao;
import com.ym.mec.biz.dal.dao.SysUserCashAccountDao;
import com.ym.mec.biz.dal.dao.TeacherDao;
import com.ym.mec.biz.dal.dto.EmployeeDto;
import com.ym.mec.biz.dal.dto.EmployeeLevelDto;
import com.ym.mec.biz.dal.dto.SimpleUserDto;
import com.ym.mec.biz.dal.entity.Employee;
import com.ym.mec.biz.dal.entity.SysUserCashAccount;
import com.ym.mec.biz.dal.enums.EmployeeOperateEnum;
import com.ym.mec.biz.dal.enums.ParamEnum;
import com.ym.mec.biz.dal.page.EmployeeQueryInfo;
import com.ym.mec.biz.service.EmployeeService;
import com.ym.mec.biz.service.ImGroupMemberService;
import com.ym.mec.common.dal.BaseDAO;
import com.ym.mec.common.entity.ImGroupMember;
import com.ym.mec.common.entity.ImGroupModel;
import com.ym.mec.common.entity.ImResult;
import com.ym.mec.common.entity.ImUserModel;
import com.ym.mec.common.exception.BizException;
import com.ym.mec.common.page.PageInfo;
import com.ym.mec.common.service.impl.BaseServiceImpl;
import com.ym.mec.im.ImFeignService;
import com.ym.mec.util.collection.MapUtil;

@Service
public class EmployeeServiceImpl extends BaseServiceImpl<Integer, Employee>  implements EmployeeService {
	
	@Autowired
	private EmployeeDao employeeDao;
	@Autowired
	private ImFeignService imFeignService;
	@Autowired
	private ImGroupMemberService imGroupMemberService;
	@Autowired
	private SysUserFeignService sysUserFeignService;
	@Autowired
	private TeacherDao teacherDao;
	@Autowired
	private SysUserCashAccountDao sysUserCashAccountDao;
	@Autowired
	private ClassGroupDao classGroupDao;
	@Autowired
	private ImUserFriendService imUserFriendService;

	@Override
	public BaseDAO<Integer, Employee> getDAO() {
		return employeeDao;
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public void add(Employee employee){
		SysUser user = sysUserFeignService.queryUserByMobile(employee.getPhone());
		if(user != null && user.getId() != null){
			Employee employee1 = employeeDao.get(user.getId());
			if(employee1 == null){
				if(StringUtils.isEmpty(user.getPassword())){
					employee.setPassword(new BCryptPasswordEncoder().encode(ParamEnum.INIT_PASSWORD.getCode().toString()));
				}
				employee.setUserId(user.getId());
				employee.setId(user.getId());
				employeeDao.insert(employee);
				//新增用户角色
				employeeDao.batchAddEmployeeRole(user.getId(),employee.getRoleIds());
				employee.setUserType(user.getUserType() + ",SYSTEM");
				teacherDao.updateUser(employee);
				return;
			}else{
				throw new BizException("员工已存在");
			}
		}
		employee.setPassword(new BCryptPasswordEncoder().encode(ParamEnum.INIT_PASSWORD.getCode().toString()));
		employee.setUserType("SYSTEM");
		teacherDao.addSysUser(employee);
		employee.setUserId(employee.getId());
        employeeDao.insert(employee);
		//新增用户角色
		employeeDao.batchAddEmployeeRole(employee.getId(),employee.getRoleIds());
		//添加用户现金账户
		sysUserCashAccountDao.insert(new SysUserCashAccount(employee.getId(),"CNY"));
		ImResult imResult = imFeignService.register(new ImUserModel(employee.getId().toString(), employee.getUsername(),null));
		employee.setImToken(imResult.getToken());
		teacherDao.updateUser(employee);
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public void updateEmployee(Employee employee) {
		Employee employee1 = employeeDao.get(employee.getId());
		if(null==employee1){
			throw new BizException("员工信息不存在");
		}
		employee.setUserId(employee.getId());
		if(StringUtils.isNotEmpty(employee.getPhone())){
			SysUser sysUser = sysUserFeignService.queryUserByMobile(employee.getPhone());
			if(sysUser != null && !sysUser.getId().equals(employee.getUserId())){
				throw new BizException("手机号已存在");
			}
		}
		employeeDao.update(employee);
		//删除当前用户角色
		employeeDao.delEmployeeRole(employee.getId());
		//新增用户角色
		employeeDao.batchAddEmployeeRole(employee.getId(),employee.getRoleIds());
		teacherDao.updateUser(employee);
	}

	@Override
	public void deleteEmployee(Long userId) {
		SysUser sysUser=new SysUser();
		sysUser.setId(userId.intValue());
		sysUser.setDelFlag(YesOrNoEnum.YES);
		teacherDao.updateUser(sysUser);
	}

	@Override
	public PageInfo queryEmployByOrganId(EmployeeQueryInfo queryInfo) throws Exception {
		SysUser user = sysUserFeignService.queryUserInfo();
		if(user == null){
			throw new BizException("获取用户信息失败");
		}
		PageInfo<EmployeeDto> pageInfo = new PageInfo<>(queryInfo.getPage(), queryInfo.getRows());
		Map<String, Object> params = new HashMap<>();
		MapUtil.populateMap(params, queryInfo);
		List<EmployeeDto> dataList = null;
		int count = employeeDao.queryEmployByOrganIdCount(params);
		if (count > 0) {
			pageInfo.setTotal(count);
			params.put("offset", pageInfo.getOffset());
			dataList = employeeDao.queryEmployByOrganId(params);
		}
		if (count == 0) {
			dataList = new ArrayList<>();
		}
		pageInfo.setRows(dataList);
		return pageInfo;
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public void employeeOperate(Integer employeeId, EmployeeOperateEnum operate) {
		Employee employee = employeeDao.get(employeeId);
		SysUser sysUser = sysUserFeignService.queryUserById(employeeId);
		switch (operate){
			case RESET_PASSWORD:
				employeeDao.updatePassword(employeeId,new BCryptPasswordEncoder().encode(ParamEnum.INIT_PASSWORD.getCode().toString()));
				break;
			case LOCK_UNLOCK:
				if(employee != null && employee.getDemissionDate() != null && sysUser.getLockFlag() == 1){
					throw new BizException("操作失败：离职员工不允许解冻");
				}
				employeeDao.updateUserLockStatus(employeeId);
				if(sysUser.getUserType().contains("TEACHER")){
					sysUserFeignService.exitByPhone("teacher", sysUser.getPhone());
				}else if(sysUser.getUserType().contains("SYSTEM")){
					sysUserFeignService.exitByPhone("system", sysUser.getPhone());
				}
				break;
			case DEMISSION:
				employeeDao.updateUserLock(employeeId,1);
				employeeDao.updateUserDemissionDate(employeeId);
				sysUserFeignService.exitByPhone("system", sysUser.getPhone());
				break;
			case REINSTATE:
				//离职，如果有关联课程组教务老师，
				employeeDao.updateUserDemissionDate(employeeId);
				break;
		}
	}

	@Override
	public List<SimpleUserDto> findByRole(String roleIds, String organIds) {
		return employeeDao.findByRole(roleIds,organIds);
	}

	@Override
	public HashMap<String, Integer> hasCourseGroupRelation(Integer employeeId) {
		Integer hasCourseGroupRelation = employeeDao.hasCourseGroupRelation(employeeId);
		Integer hasCourseSchedule = employeeDao.hasCourseSchedule(employeeId);
		HashMap<String, Integer> map = new HashMap<>(2);
		map.put("hasCourseGroupRelation",hasCourseGroupRelation);
		map.put("hasCourseSchedule",hasCourseSchedule);
		return map;
	}

	@Override
	public void updateEducationTeacherId(Integer currentUserId, Integer targetUserId) {
		employeeDao.updateEducationTeacherId(currentUserId,targetUserId);
	}

	@Override
	public Map<String, Object> levelDetail(Integer userId) {
		Map<String,Object> resultMap = new HashMap<>(4);
		//维修技师所在分部列表
		List<Integer> repair = employeeDao.queryRepairOrganList(userId);
		resultMap.put("repair",repair);
		//教务老师所在分部列表
		List<Integer> education = employeeDao.queryEducationOrganList(userId);
		resultMap.put("education",education);
		//运营主管所在分部列表
		List<Integer> teamTeacher = employeeDao.queryTeamTeacherOrganList(userId);
		resultMap.put("teamTeacher",teamTeacher);
		//乐队指导所在分部列表
		List<Integer> director = employeeDao.queryDirectorOrganList(userId);
		resultMap.put("director",director);
		return resultMap;
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public void level(List<EmployeeLevelDto> employeeLevelDtos) {
		Integer levelUserId = employeeLevelDtos.get(0).getLevelUserId();
		List<ImGroupModel> educationGroupModels = new ArrayList<>();
		List<ImGroupModel> teamGroupModels = new ArrayList<>();
		List<ImGroupModel> directorGroupModels = new ArrayList<>();
		//获取用户需要加入的群组列表
		Map<String, List<EmployeeLevelDto>> collect = employeeLevelDtos.stream().collect(Collectors.groupingBy(e -> e.getRoleName()));
		Set<String> roleNames = collect.keySet();
		for (String roleName : roleNames) {
			List<EmployeeLevelDto> levelDtos = collect.get(roleName);
			Map<Integer, List<EmployeeLevelDto>> organIdMap = levelDtos.stream().collect(Collectors.groupingBy(e -> e.getOrganId()));
			Set<Integer> organIds = organIdMap.keySet();
			for (Integer organId : organIds) {
				List<EmployeeLevelDto> levelDtoList = organIdMap.get(organId);
				for (EmployeeLevelDto employeeLevelDto : levelDtoList) {
					if(employeeLevelDto.getLevelUserId() == employeeLevelDto.getTransferUserId()){
						throw new BizException("交接人校验失败,请重新填写");
					}
					switch (roleName){
						case "education":
							//教务老师所需加入的群组
							educationGroupModels.addAll(classGroupDao.queryEducationGroups(employeeLevelDto.getTransferUserId(),levelUserId,organId));
							break;
						case "teamTeacher":
							//运营主管所需加入的群组
							teamGroupModels.addAll(classGroupDao.queryTeamTeacherGroups(employeeLevelDto.getTransferUserId(),levelUserId,organId));
							break;
						case "director":
							//乐队指导所需加入的群组
							directorGroupModels.addAll(classGroupDao.queryDirectorGroups(employeeLevelDto.getTransferUserId(),levelUserId,organId));
							break;
					}
				}
			}
		}
		if(educationGroupModels.size() > 0){
			//❤️用户加群
			for (ImGroupModel imGroupModel : educationGroupModels) {
				Map<Integer,String> userRoleMap = new HashMap<Integer, String>();
				
				List<ImGroupMember> memberList = imGroupModel.getMemberList();
				for(ImGroupMember member : memberList){
					userRoleMap.put(Integer.parseInt(member.getId()), "乐团主管");
				}
				imGroupMemberService.join(Long.parseLong(imGroupModel.getId()), userRoleMap);
			}
		}
		if(teamGroupModels.size() > 0){
			//❤️用户加群
			for (ImGroupModel imGroupModel : teamGroupModels) {
				Map<Integer,String> userRoleMap = new HashMap<Integer, String>();
				
				List<ImGroupMember> memberList = imGroupModel.getMemberList();
				for(ImGroupMember member : memberList){
					userRoleMap.put(Integer.parseInt(member.getId()), "运营主管");
				}
				imGroupMemberService.join(Long.parseLong(imGroupModel.getId()), userRoleMap);
			}
		}
		if(directorGroupModels.size() > 0){
			//❤️用户加群
			for (ImGroupModel imGroupModel : directorGroupModels) {
				Map<Integer,String> userRoleMap = new HashMap<Integer, String>();
				
				List<ImGroupMember> memberList = imGroupModel.getMemberList();
				for(ImGroupMember member : memberList){
					userRoleMap.put(Integer.parseInt(member.getId()), "乐队指导");
				}
				imGroupMemberService.join(Long.parseLong(imGroupModel.getId()), userRoleMap);
			}
		}
		//原有员工退群
		List<ImGroupModel> groupModels = classGroupDao.queryTeacherQuitGroups(levelUserId);
		if(groupModels.size() > 0){
			List<Long> imGroupIdList = new ArrayList<Long>();
			for (ImGroupModel imGroupModel : groupModels) {
				imGroupIdList.add(Long.parseLong(imGroupModel.getId()));
			}
			imGroupMemberService.quit(imGroupIdList, levelUserId);
		}
		//更换教务老师等数据
		employeeDao.employeeLevel(employeeLevelDtos);
		//新增离职时间
		employeeDao.updateUserDemissionDate(levelUserId);
		//冻结用户
		employeeDao.updateUserLock(levelUserId,1);
		//获取用户担任教务老师的所有乐团列表
		List<String> musicGroupIds = employeeDao.queryMusicGroupIdByUserId(levelUserId);
		if(musicGroupIds.size() > 0){
			for (String musicGroupId : musicGroupIds) {
				imUserFriendService.refreshGroupImUserFriend(musicGroupId, GroupType.MUSIC);
			}
		}
		//获取用户担任教务老师的所有网管课列表
		List<String> practiceGroupIds = employeeDao.queryPracticeGroupIdByUserId(levelUserId);
		if(practiceGroupIds.size() > 0){
			for (String musicGroupId : practiceGroupIds) {
				imUserFriendService.refreshGroupImUserFriend(musicGroupId, GroupType.PRACTICE);
			}
		}
		//获取用户担任教务老师的所有VIP课列表
		List<String> vipGroupIds = employeeDao.queryVipGroupIdByUserId(levelUserId);
		if(vipGroupIds.size() > 0){
			for (String musicGroupId : vipGroupIds) {
				imUserFriendService.refreshGroupImUserFriend(musicGroupId, GroupType.VIP);
			}
		}
	}

	@Override
	public List<SimpleUserDto> findAllByRole(String roleIds, String organIds) {
		return employeeDao.findAllByRole(roleIds,organIds);
	}
}
