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

import com.ym.mec.auth.api.entity.SysUser;
import com.ym.mec.biz.dal.dao.*;
import com.ym.mec.biz.dal.dto.ImGroupMemberDto;
import com.ym.mec.biz.dal.entity.*;
import com.ym.mec.biz.dal.enums.GroupType;
import com.ym.mec.biz.dal.page.GroupMemberQueryInfo;
import com.ym.mec.biz.service.ImGroupMemberService;
import com.ym.mec.biz.service.ImGroupService;
import com.ym.mec.common.dal.BaseDAO;
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.im.entity.GroupMember;
import com.ym.mec.im.entity.GroupModel;
import com.ym.mec.util.collection.MapUtil;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

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

@Service
public class ImGroupMemberServiceImpl extends BaseServiceImpl<Long, ImGroupMember> implements ImGroupMemberService {
	@Autowired
	private ImGroupMemberDao imGroupMemberDao;
	@Autowired
	private ImGroupDao imGroupDao;
	@Autowired
	private ImGroupService imGroupService;
	@Autowired
	private TeacherDao teacherDao;
	@Autowired
	private ClassGroupDao classGroupDao;
	@Autowired
	private MusicGroupDao musicGroupDao;
	@Autowired
	private PracticeGroupDao practiceGroupDao;
	@Autowired
	private VipGroupDao vipGroupDao;
	@Autowired
	private ClassGroupTeacherMapperDao classGroupTeacherMapperDao;
	@Autowired
	private ClassGroupStudentMapperDao classGroupStudentMapperDao;
	@Autowired
	private ImFeignService imFeignService;
	@Override
	public BaseDAO<Long, ImGroupMember> getDAO() {
		return imGroupMemberDao;
	}

	public ImGroup joinGroup(String imGroupId, Integer userId, String roleType, boolean isAdmin,Map<Integer,String> userRoleMap){
		int groupId = Integer.parseInt(imGroupId);
		ClassGroup classGroup = classGroupDao.get(groupId);
		String tags = classGroup.getName();
		//相关用户加入群组
		//获取班级关联的老师列表
		Set<Integer> teacherIds = classGroupTeacherMapperDao.queryTeacherIdsByClassGroupId(groupId,null,null);
		//获取班级关联的学员列表
		Set<Integer> studentIds = classGroupStudentMapperDao.queryStudentIdsByClassGroupId(groupId,null,null);
		if(studentIds != null && studentIds.size() > 0){
			for(Integer studentId : studentIds){
				userRoleMap.put(studentId, null);
			}
		}
		if(teacherIds != null && teacherIds.size() > 0){
			for(Integer teacherId : teacherIds){
				userRoleMap.put(teacherId, "指导老师");
			}
		}
		if(classGroup.getGroupType() == GroupType.MUSIC){
			MusicGroup musicGroup = musicGroupDao.get(classGroup.getMusicGroupId());
			tags = musicGroup.getName();
			if(musicGroup.getEducationalTeacherId() != null){
				userRoleMap.put(musicGroup.getEducationalTeacherId(), "乐团主管");
			}
			if(musicGroup.getTeamTeacherId() != null){
				userRoleMap.put(musicGroup.getTeamTeacherId(), "运营主管");
			}
			if(musicGroup.getDirectorUserId() != null){
				userRoleMap.put(musicGroup.getDirectorUserId(), "乐队指导");
			}
			if(musicGroup.getTransactionTeacherId() != null){
				userRoleMap.put(musicGroup.getTransactionTeacherId(), "衔接老师");
			}
		}else if(classGroup.getGroupType() == GroupType.PRACTICE){
			PracticeGroup practiceGroup = practiceGroupDao.get(Long.parseLong(classGroup.getMusicGroupId()));
			tags = practiceGroup.getName();
			userRoleMap.put(practiceGroup.getUserId(), "指导老师");
			if(practiceGroup.getEducationalTeacherId() != null){
				userRoleMap.put(practiceGroup.getEducationalTeacherId(), "乐团主管");
			}
		}else if(classGroup.getGroupType() == GroupType.VIP){
			VipGroup vipGroup = vipGroupDao.get(Long.parseLong(classGroup.getMusicGroupId()));
			userRoleMap.put(vipGroup.getUserId(), "指导老师");
			if(vipGroup.getEducationalTeacherId() != null){
				userRoleMap.put(vipGroup.getEducationalTeacherId(), "乐团主管");
			}
			tags = vipGroup.getName();
		}
		ImGroup imGroup = imGroupService.create(imGroupId, null, classGroup.getName(), tags,
				tags, tags, null, classGroup.getGroupType().getCode(), ImGroup.GroupTypeEnum.valueOf(classGroup.getType().getCode()));
		if(userId != null){
			join(imGroupId,userId,roleType,isAdmin);
		}
		join(imGroupId,userRoleMap);
		return imGroup;
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public boolean join(String imGroupId, Integer userId, String roleType, boolean isAdmin) {
		ImGroup imGroup = imGroupDao.getLocked(imGroupId);
		if (imGroup == null) {
			joinGroup(imGroupId,userId,roleType,isAdmin,new HashMap<>());
			return true;
		}
		//检查用户是否已存在
		List<ImGroupMember> imGroupMemberList = imGroupMemberDao.queryByImGroupIdAndUserId(imGroupId.toString(), userId.toString());
		if(imGroupMemberList != null && imGroupMemberList.size() > 0){
			return true;
		}

		ImGroupMember imGroupMember = new ImGroupMember();
		Date date = new Date();

		imGroupMember.setCreateTime(date);
		imGroupMember.setImGroupId(imGroupId);
		imGroupMember.setIsAdmin(isAdmin);
		imGroupMember.setRoleType(roleType);
		imGroupMember.setUpdateTime(date);
		imGroupMember.setUserId(userId);
		SysUser user = teacherDao.getUser(userId);
		if (StringUtils.isBlank(roleType)) {
			imGroupMember.setNickname(user.getUsername()==null?user.getRealName():user.getUsername());
		} else {
			imGroupMember.setNickname(user.getRealName()==null?user.getUsername():user.getRealName());
		}

		imGroupMemberDao.insert(imGroupMember);

		imGroup.setMemberNum(1);
		imGroup.setUpdateTime(date);
		imGroupDao.update(imGroup);

		String groupId = imGroup.getId();

		GroupMember groupMember = new GroupMember(userId.toString(), groupId);
		imFeignService.groupJoin(new GroupModel(groupId, new GroupMember[] { groupMember }, imGroup.getName()));
		return true;
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public boolean join(String imGroupId,String roleType, boolean isAdmin,ImGroup imGroup,SysUser user) {
		if (imGroup == null) {
			imGroup = imGroupDao.getLocked(imGroupId);
		}
		if (imGroup == null) {
			joinGroup(imGroupId,user.getId(),roleType,isAdmin,new HashMap<>());
			return true;
		}
		//检查用户是否已存在
		List<ImGroupMember> imGroupMemberList = imGroupMemberDao.queryByImGroupIdAndUserId(imGroupId.toString(), user.getId().toString());
		if(imGroupMemberList != null && imGroupMemberList.size() > 0){
			return true;
		}

		ImGroupMember imGroupMember = new ImGroupMember();
		Date date = new Date();

		imGroupMember.setCreateTime(date);
		imGroupMember.setImGroupId(imGroupId);
		imGroupMember.setIsAdmin(isAdmin);
		imGroupMember.setRoleType(roleType);
		imGroupMember.setUpdateTime(date);
		imGroupMember.setUserId(user.getId());
		if (StringUtils.isBlank(roleType)) {
			imGroupMember.setNickname(user.getUsername()==null?user.getRealName():user.getUsername());
		} else {
			imGroupMember.setNickname(user.getRealName()==null?user.getUsername():user.getRealName());
		}

		imGroupMemberDao.insert(imGroupMember);

		imGroup.setMemberNum(1);
		imGroup.setUpdateTime(date);
		imGroupDao.update(imGroup);

		String groupId = imGroup.getId().toString();

		GroupMember groupMember = new GroupMember(user.getId().toString(), groupId);
		imFeignService.groupJoin(new GroupModel(groupId, new GroupMember[] { groupMember }, imGroup.getName()));

		return true;
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public boolean join(String imGroupId, Map<Integer, String> userRoleMap) {
		ImGroup imGroup = imGroupDao.getLocked(imGroupId);
		if (imGroup == null) {
			joinGroup(imGroupId,null,null,false,userRoleMap);
			return true;
		}
		//检查用户是否已存在
		List<Integer> existUserIdList = imGroupMemberDao.queryByImGroupIdAndUserId(imGroupId.toString(), userRoleMap.keySet().stream().filter(Objects::nonNull).map(Objects::toString)
		.collect(Collectors.joining(","))).stream().map(e -> e.getUserId()).collect(Collectors.toList());

		Date date = new Date();
		List<ImGroupMember> imGroupMemberList = new ArrayList<ImGroupMember>();
		List<GroupMember> groupMemberList = new ArrayList<GroupMember>();

		String groupId = imGroup.getId().toString();
		List<Integer> usernameIds = new ArrayList<>();
		List<Integer> realNameIds = new ArrayList<>();

//		Map<Integer, String> nameIdMap = MapUtil.convertIntegerMap(teacherDao.queryNickNameByRole(userRoleMap.keySet(),userRoleMap));
		for (Entry<Integer, String> entry : userRoleMap.entrySet()) {
			if(existUserIdList.contains(entry.getKey())||Objects.isNull(entry.getKey())){
				continue;
			}
			ImGroupMember imGroupMember = new ImGroupMember();
			imGroupMember.setCreateTime(date);
			imGroupMember.setImGroupId(imGroupId);
			imGroupMember.setIsAdmin(false);
			imGroupMember.setRoleType(entry.getValue());
			if(StringUtils.isEmpty(entry.getValue())){
				usernameIds.add(entry.getKey());
			}else {
				realNameIds.add(entry.getKey());
			}
			imGroupMember.setUpdateTime(date);
			imGroupMember.setUserId(entry.getKey());
//			imGroupMember.setNickname(nameIdMap.get(imGroupMember.getUserId()));
			imGroupMemberList.add(imGroupMember);
			groupMemberList.add(new GroupMember(imGroupMember.getUserId().toString(), groupId));
		}


		if (imGroupMemberList.size() > 0) {
			Map<Integer, String> usernameMap = new HashMap<>();
			Map<Integer, String> realNameMap = new HashMap<>();
			if(usernameIds.size() > 0){
				usernameMap = MapUtil.convertIntegerMap(teacherDao.queryUserNameByIdList(usernameIds));
			}
			if(realNameIds.size() > 0){
				realNameMap = MapUtil.convertIntegerMap(teacherDao.queryNameByIdList(realNameIds));
			}
			for (ImGroupMember imGroupMember : imGroupMemberList) {
				if(StringUtils.isEmpty(imGroupMember.getRoleType())){
					imGroupMember.setNickname(usernameMap.get(imGroupMember.getUserId()));
				}else {
					imGroupMember.setNickname(realNameMap.get(imGroupMember.getUserId()));
				}
			}
			imGroupMemberDao.batchInsert(imGroupMemberList);
			imGroup.setMemberNum(imGroupMemberList.size());
			imGroup.setUpdateTime(date);
			imGroupDao.update(imGroup);

			imFeignService.groupJoin(new GroupModel(groupId, groupMemberList.stream().toArray(GroupMember[]::new), imGroup.getName()));
		}

		return true;
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public boolean quit(String imGroupId, Integer userId) {
		List<Integer> userIdList = new ArrayList<Integer>();
		userIdList.add(userId);

		return quit(imGroupId, userIdList);
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public boolean quit(List<String> imGroupIdList, Integer userId) {
		for (String imGroupId : imGroupIdList) {
			quit(imGroupId, userId);
		}
		return true;
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public boolean quit(String imGroupId, List<Integer> userIdList) {

		ImGroup imGroup = imGroupDao.getLocked(imGroupId);
		if (imGroup == null) {
			return true;
		}

		List<ImGroupMember> imGroupMemberList = imGroupMemberDao.queryByImGroupIdAndUserId(imGroupId.toString(), userIdList.stream().map(Objects::toString)
				.collect(Collectors.joining(",")));

		if (imGroupMemberList == null || imGroupMemberList.size() == 0) {
			return true;
		}

		imGroupMemberDao.batchDelete(imGroupMemberList);

		imGroup.setMemberNum(-userIdList.size());
		imGroup.setUpdateTime(new Date());
		imGroupDao.update(imGroup);

		String groupId = imGroup.getId().toString();

		List<GroupMember> groupMemberList = new ArrayList<GroupMember>();
		for (Integer userId : userIdList) {
			groupMemberList.add(new GroupMember(userId.toString(), groupId));
		}
		imFeignService.groupQuit(new GroupModel(groupId, groupMemberList.stream().toArray(GroupMember[]::new), imGroup.getName()));

		return true;
	}

	@Override
	public boolean updateRoleType(String imGroupId, Integer userId, String roleType) {
		List<Integer> userIdList = new ArrayList<Integer>();
		userIdList.add(userId);
		List<ImGroupMember> imGroupMemberList = imGroupMemberDao.queryByImGroupIdAndUserId(imGroupId.toString(), userIdList.stream().map(Objects::toString)
				.collect(Collectors.joining(",")));

		if (imGroupMemberList == null || imGroupMemberList.size() == 0) {
			throw new BizException("更新失败：找不到用户信息");
		}

		Date date = new Date();
		for (ImGroupMember imGroupMember : imGroupMemberList) {
			imGroupMember.setRoleType(roleType);
			imGroupMember.setUpdateTime(date);
		}
		imGroupMemberDao.batchUpdate(imGroupMemberList);

		return true;
	}

	@Override
	public void batchInsert(List<ImGroupMember> imGroupMemberList) {
		imGroupMemberDao.batchInsert(imGroupMemberList);
	}

	@Override
	public void batchDelete(List<ImGroupMember> imGroupMemberList) {
		imGroupMemberDao.batchDelete(imGroupMemberList);
	}

	@Override
	public void batchDeleteByGroupIdAndUserId(List<ImGroupMember> imGroupMemberList) {
		imGroupMemberDao.batchDeleteByGroupIdAndUserId(imGroupMemberList);
	}

	@Override
	public boolean isExit(String groupId, String userId) {
		return imGroupMemberDao.isExit(groupId,userId);
	}

	@Override
	public void delRepeat() {
		imGroupMemberDao.delRepeat();
	}

	@Override
	public List<ImGroupMember> queryMembers(String groupId, List<String> userIdList, Integer tenantId) {
		return imGroupMemberDao.queryMembers(groupId, userIdList, tenantId);
	}

    @Override
    public PageInfo<ImGroupMemberDto> queryGroupMemberPage(GroupMemberQueryInfo queryInfo) {
		PageInfo<ImGroupMemberDto> pageInfo = new PageInfo<>(queryInfo.getPage(), queryInfo.getRows());
		Map<String, Object> params = new HashMap<String, Object>();
		MapUtil.populateMap(params, queryInfo);

		List<ImGroupMemberDto> dataList = null;
		int count = imGroupMemberDao.countGroupMember(params);
		if (count > 0) {
			pageInfo.setTotal(count);
			params.put("offset", pageInfo.getOffset());
			dataList = imGroupMemberDao.queryGroupMemberPage(params);
		}
		if (count == 0) {
			dataList = new ArrayList<>();
		}
		pageInfo.setRows(dataList);
		return pageInfo;
    }

	@Override
	public void batchJoin(String imGroupId, String userId, String roleType) {
		List<Integer> userIds = Arrays.stream(userId.split(",")).mapToInt(Integer::parseInt).boxed().collect(Collectors.toList());
		Map<Integer, String> userRoleMap = new HashMap<>(userIds.size());
		userIds.stream().forEach(e->userRoleMap.put(e,roleType));
		this.join(imGroupId,userRoleMap);
	}
}
