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

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Objects;
import java.util.stream.Collectors;

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 com.ym.mec.auth.api.client.SysUserFeignService;
import com.ym.mec.auth.api.entity.SysUser;
import com.ym.mec.biz.dal.dao.ImGroupDao;
import com.ym.mec.biz.dal.dao.ImGroupMemberDao;
import com.ym.mec.biz.dal.dao.TeacherDao;
import com.ym.mec.biz.dal.entity.ImGroup;
import com.ym.mec.biz.dal.entity.ImGroupMember;
import com.ym.mec.biz.service.ImGroupMemberService;
import com.ym.mec.common.dal.BaseDAO;
import com.ym.mec.common.exception.BizException;
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;

@Service
public class ImGroupMemberServiceImpl extends BaseServiceImpl<Long, ImGroupMember> implements ImGroupMemberService {

	@Autowired
	private ImGroupMemberDao imGroupMemberDao;

	@Autowired
	private ImGroupDao imGroupDao;

	@Autowired
	private TeacherDao teacherDao;

	@Autowired
	private ImFeignService imFeignService;
	
	@Autowired
	private SysUserFeignService sysUserFeignService;

	@Override
	public BaseDAO<Long, ImGroupMember> getDAO() {
		return imGroupMemberDao;
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public boolean join(Long imGroupId, Integer userId, String roleType, boolean isAdmin) {
		ImGroup imGroup = imGroupDao.getLocked(imGroupId);
		if (imGroup == null) {
			throw new BizException("加入群组失败：群组[{}]不存在", imGroupId);
		}
		//检查用户是否已存在
		List<ImGroupMember> imGroupMemberList = imGroupMemberDao.queryByImGroupIdAndUserId(imGroupId.toString(), userId.toString());
		if(imGroupMemberList != null && imGroupMemberList.size() > 0){
			return true;
		}
		
		SysUser user = sysUserFeignService.queryUserById(userId);
		
		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);
		imGroupMember.setNickname(StringUtils.isBlank(user.getUsername()) ? user.getRealName() : user.getUsername());

		imGroupMemberDao.insert(imGroupMember);

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

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

		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(Long imGroupId, Map<Integer, String> userRoleMap) {
		ImGroup imGroup = imGroupDao.getLocked(imGroupId);
		if (imGroup == null) {
			throw new BizException("加入群组失败：群组[{}]不存在", imGroupId);
		}
		//检查用户是否已存在
		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();
		Map<Integer, String> nameIdMap= MapUtil.convertIntegerMap(teacherDao.queryUserNameByIdList(new ArrayList<>(userRoleMap.keySet())));
		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());
			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) {
			imGroupMemberDao.batchInsert(imGroupMemberList);

			imGroup.setMemberNum(imGroup.getMemberNum() + 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(Long 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<Long> imGroupIdList, Integer userId) {
		for (Long imGroupId : imGroupIdList) {
			quit(imGroupId, userId);
		}
		return true;
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public boolean quit(Long 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(imGroup.getMemberNum() - 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(Long 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;
	}

}
