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

import java.util.*;
import java.util.stream.Collectors;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.ym.mec.biz.dal.dao.*;
import com.ym.mec.biz.dal.entity.Organization;
import com.ym.mec.biz.dal.enums.GroupType;
import com.ym.mec.biz.service.ImUserFriendService;
import com.ym.mec.im.entity.GroupMember;
import com.ym.mec.im.entity.GroupModel;
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.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;
import org.springframework.util.CollectionUtils;

@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;
	@Autowired
	private OrganizationDao organizationDao;
	@Autowired
	private ImGroupDao imGroupDao;
	@Autowired
	private CooperationOrganDao cooperationOrganDao;

	@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());
		SysUser sysUser = sysUserFeignService.queryUserByMobile(employee.getPhone());
		if(StringUtils.isNotEmpty(employee.getPhone())){
			if(sysUser != null && !sysUser.getId().equals(employee.getUserId())){
				throw new BizException("手机号已存在");
			}
			if(sysUser == null){
				sysUser = sysUserFeignService.queryUserInfo();
			}
		}
		employeeDao.update(employee);
		//删除当前用户角色
		employeeDao.delEmployeeRole(employee.getId());
		//新增用户角色
		employeeDao.batchAddEmployeeRole(employee.getId(),employee.getRoleIds());
		teacherDao.updateUser(employee);
		imGroupDao.updateNickname(employee.getUserId(), employee.getRealName());
		imGroupDao.updateUserFriendNickname(employee.getUserId(), employee.getRealName());
		imFeignService.update(new ImUserModel(employee.getUserId().toString(),employee.getRealName(),sysUser.getAvatar()));
	}

	@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);
			List<Integer> allOrganIds = new ArrayList<>();
			for (EmployeeDto employeeDto : dataList) {
				if(StringUtils.isBlank(employeeDto.getOrganIdStr())){
					continue;
				}
				List<Integer> organIds = Arrays.stream(employeeDto.getOrganIdStr().split(",")).map(s -> Integer.valueOf(s)).collect(Collectors.toList());
				allOrganIds.addAll(organIds);
			}
			if(!CollectionUtils.isEmpty(allOrganIds)){
				List<Organization> allOrgans = organizationDao.findOrgans(allOrganIds);
				for (EmployeeDto employeeDto : dataList) {
					if(StringUtils.isBlank(employeeDto.getOrganIdStr())){
						continue;
					}
					List<Integer> organIds = Arrays.stream(employeeDto.getOrganIdStr().split(",")).map(s -> Integer.valueOf(s)).collect(Collectors.toList());
					List<Organization> organs = allOrgans.stream().filter(organ -> organIds.contains(organ.getId())).collect(Collectors.toList());
					List<String> organNames = organs.stream().map(Organization::getName).collect(Collectors.toList());
					employeeDto.setOrganNameList(organNames);
					employeeDto.setOrganIdList(organIds.stream().mapToLong(Long::valueOf).boxed().collect(Collectors.toList()));
				}
			}
		}
		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<>();
		//获取用户需要加入的群组列表
		Map<String, List<EmployeeLevelDto>> collect = employeeLevelDtos.stream().collect(Collectors.groupingBy(e -> e.getRoleName()));
		Set<String> roleNames = collect.keySet();
		Set<Integer> userIds = new HashSet<>();
		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("交接人校验失败,请重新填写");
					}
					userIds.add(employeeLevelDto.getTransferUserId());
					//获取关联的预报名的群聊
					educationGroupModels.addAll(classGroupDao.queryApplyGroups(employeeLevelDto.getTransferUserId(),levelUserId,organId));
					switch (roleName){
						case "education":
							//替换当前分部合作单位关联的乐团主管
							cooperationOrganDao.batchUpdateEduId(employeeLevelDto.getTransferUserId(),levelUserId,organId);
							//教务老师所需加入的群组
							educationGroupModels.addAll(classGroupDao.queryEducationGroups(employeeLevelDto.getTransferUserId(),levelUserId,organId));
							break;
						case "teamTeacher":
							//运营主管所需加入的群组
							educationGroupModels.addAll(classGroupDao.queryTeamTeacherGroups(employeeLevelDto.getTransferUserId(),levelUserId,organId));
							break;
						case "director":
							//乐队指导所需加入的群组
							educationGroupModels.addAll(classGroupDao.queryDirectorGroups(employeeLevelDto.getTransferUserId(),levelUserId,organId));
							break;
					}
				}
			}
		}
		Date date = new Date();
		if(educationGroupModels.size() > 0){
			Map<Integer, String> realNameMap = MapUtil.convertIntegerMap(teacherDao.queryNameByIdList(new ArrayList<>(userIds)));
			//❤️用户加群
			List<com.ym.mec.biz.dal.entity.ImGroupMember> imGroupMemberList = new ArrayList<>();
			List<GroupModel> groupModelList = new ArrayList<>();
			for (ImGroupModel imGroupModel : educationGroupModels) {
				String userId = imGroupModel.getMemberList().get(0).getId();
				com.ym.mec.biz.dal.entity.ImGroupMember imGroupMember = new com.ym.mec.biz.dal.entity.ImGroupMember();
				imGroupMember.setCreateTime(date);
				imGroupMember.setImGroupId(Long.parseLong(imGroupModel.getId()));
				imGroupMember.setIsAdmin(false);
				imGroupMember.setRoleType(imGroupModel.getUserRole());
				imGroupMember.setUpdateTime(date);
				imGroupMember.setUserId(Integer.parseInt(userId));
				imGroupMember.setNickname(realNameMap.get(imGroupMember.getUserId()));
				imGroupMemberList.add(imGroupMember);
				GroupMember groupMember = new GroupMember(userId, imGroupModel.getId());
				GroupModel groupModel = new GroupModel(imGroupModel.getId(), new GroupMember[] { groupMember }, imGroupModel.getName());
				groupModelList.add(groupModel);
			}
			imGroupMemberService.batchInsert(imGroupMemberList);
			imFeignService.groupBatchJoin(groupModelList);
		}
		//原有员工退群
		List<ImGroupModel> groupModels = classGroupDao.queryTeacherQuitGroups(levelUserId);
		//原有员工退预报名群
		groupModels.addAll(classGroupDao.queryQuitApplyGroups(levelUserId));
		if(groupModels.size() > 0){
			List<com.ym.mec.biz.dal.entity.ImGroupMember> imGroupMemberList = new ArrayList<>();
			List<GroupModel> groupModelList = new ArrayList<>();
			for (ImGroupModel imGroupModel : groupModels) {
				com.ym.mec.biz.dal.entity.ImGroupMember imGroupMember = new com.ym.mec.biz.dal.entity.ImGroupMember();
				imGroupMember.setImGroupId(Long.parseLong(imGroupModel.getId()));
				imGroupMember.setUserId(Integer.parseInt(imGroupModel.getMemberList().get(0).getId()));
				imGroupMemberList.add(imGroupMember);

				GroupMember groupMember = new GroupMember(imGroupMember.getUserId().toString(), imGroupModel.getId());
				GroupModel groupModel = new GroupModel(imGroupModel.getId(), new GroupMember[] { groupMember }, imGroupModel.getName());
				groupModelList.add(groupModel);
			}
			imGroupMemberService.batchDeleteByGroupIdAndUserId(imGroupMemberList);
			imFeignService.groupBatchQuit(groupModelList);
		}
		//更换教务老师等数据
		employeeDao.employeeLevel(employeeLevelDtos);
		//新增离职时间
		employeeDao.updateUserDemissionDate(levelUserId);
		//冻结用户
		employeeDao.updateUserLock(levelUserId,1);
		//获取用户担任教务老师、维修技师的所有乐团列表
		List<String> musicGroupIds = employeeDao.queryMusicGroupIdByUserId(levelUserId);
		//获取用户担任教务老师的所有网管课列表
		List<String> practiceGroupIds = employeeDao.queryPracticeGroupIdByUserId(levelUserId);
		//获取用户担任教务老师的所有VIP课列表
		List<String> vipGroupIds = employeeDao.queryVipGroupIdByUserId(levelUserId);
		if(musicGroupIds.size() > 0){
			for (String musicGroupId : musicGroupIds) {
				imUserFriendService.refreshGroupImUserFriend(musicGroupId, GroupType.MUSIC);
			}
		}
		if(practiceGroupIds.size() > 0){
			for (String musicGroupId : practiceGroupIds) {
				imUserFriendService.refreshGroupImUserFriend(musicGroupId, GroupType.PRACTICE);
			}
		}
		if(vipGroupIds.size() > 0){
			for (String musicGroupId : vipGroupIds) {
				imUserFriendService.refreshGroupImUserFriend(musicGroupId, GroupType.VIP);
			}
		}
		//更新群成员数量
		imGroupDao.updateMemberNum();
		//删除重复的群成员
		imGroupMemberService.delRepeat();
	}

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

	@Override
	public List<Integer> queryUserRole(Integer sysUserId) {
		return employeeDao.queryUserRole(sysUserId);
	}
}
