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

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.ImGroupNoticeDao;
import com.ym.mec.biz.dal.dao.ImUserFriendDao;
import com.ym.mec.biz.dal.dto.ImGroupDto;
import com.ym.mec.biz.dal.dto.ImGroupMemberDto;
import com.ym.mec.biz.dal.dto.NameDto;
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.biz.service.ImGroupService;
import com.ym.mec.biz.service.SysUserService;
import com.ym.mec.common.dal.BaseDAO;
import com.ym.mec.common.entity.ImUserModel;
import com.ym.mec.common.exception.BizException;
import com.ym.mec.common.service.impl.BaseServiceImpl;
import com.ym.mec.common.tenant.TenantContextHolder;
import com.ym.mec.im.ImFeignService;
import com.ym.mec.im.entity.GroupMember;
import com.ym.mec.im.entity.GroupModel;
import org.apache.commons.collections.CollectionUtils;
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.function.Function;
import java.util.stream.Collectors;

@Service
public class ImGroupServiceImpl extends BaseServiceImpl<String, ImGroup> implements ImGroupService {

	@Autowired
	private ImGroupDao imGroupDao;

	@Autowired
	private ImGroupMemberDao imGroupMemberDao;

	@Autowired
	private ImGroupNoticeDao imGroupNoticeDao;

	@Autowired
	private ImGroupMemberService imGroupMemberService;

	@Autowired
	private ImFeignService imFeignService;

	@Autowired
	private SysUserService sysUserService;

	@Autowired
	private ImUserFriendDao imUserFriendDao;

	@Override
	public BaseDAO<String, ImGroup> getDAO() {
		return imGroupDao;
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public ImGroup create(String id, Integer userId, String name, String introduce, String memo, String tags, String img, String type, ImGroup.GroupTypeEnum groupType) {
		ImGroup imGroup = imGroupDao.get(id);
		if (imGroup != null) {
			return imGroup;
		}

		imGroup = new ImGroup();

		Date date = new Date();

		imGroup.setId(id);
		imGroup.setCreateTime(date);
		imGroup.setIntroduce(introduce);
		
		if(userId != null){
			imGroup.setMemberNum(1);
		}else{
			imGroup.setMemberNum(0);
		}
		imGroup.setMemo(memo);
		imGroup.setName(name);
		imGroup.setTags(tags);
		imGroup.setImg(img);
		imGroup.setType(type);
		imGroup.setGroupType(groupType);
		imGroup.setUpdateTime(date);
		imGroupDao.insert(imGroup);

		String groupId = imGroup.getId();
		
		if(userId != null){
			imGroupMemberService.join(id, userId, null, true);

			GroupMember groupMember = new GroupMember(userId.toString(), groupId);

			imFeignService.groupCreate(new GroupModel(groupId, new GroupMember[] { groupMember }, name));
		}else{
			imFeignService.groupCreate(new GroupModel(groupId, null, name));
		}

		return imGroup;
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public String createGroup(ImGroupDto imGroupDto){
		List<String> userIdList = imGroupDto.getUserIdList();
		Integer currentUserId = null;
		if (CollectionUtils.isEmpty(userIdList)){
			userIdList.add(sysUserService.getUserId().toString());
		}
		String groupName = imGroupDto.getGroupName();
		String type = imGroupDto.getType();
		Optional.ofNullable(groupName).filter(StringUtils::isNotBlank).orElseThrow(() -> new BizException("群名称不能为空"));
		Optional.ofNullable(type).filter(StringUtils::isNotBlank).orElseThrow(() -> new BizException("群类型不能为空"));
		Date date = new Date();
		ImGroup imGroup = new ImGroup();
		String groupId = UUID.randomUUID().toString();
		imGroup.setId(groupId);
		imGroup.setCreateTime(date);
		imGroup.setIntroduce(groupName);
		imGroup.setMemo(groupName);
		imGroup.setMemberNum(userIdList.size());
		imGroup.setName(groupName);
		imGroup.setType(type);
		imGroup.setGroupType(imGroupDto.getGroupType());
		imGroup.setUpdateTime(date);
		imGroupDao.insert(imGroup);
		List<ImGroupMember> groupMemberList = imGroupMemberDao.queryMembers(groupId, userIdList, TenantContextHolder.getTenantId());
		if(currentUserId != null){
			groupMemberList.get(0).setRoleType("乐团主管");
		}
		imGroupMemberDao.batchInsert(groupMemberList);
        Function<String,GroupMember> newGroup = userId ->new GroupMember(userId, groupId);
		List<GroupMember> groupMembers =  userIdList.stream().map(newGroup).collect(Collectors.toList());
		GroupMember[] members = new GroupMember[groupMembers.size()];
		groupMembers.toArray(members);
		imFeignService.groupCreate(new GroupModel(groupId,members,groupName));
        return groupId;
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public boolean cancel(String imGroupId) {
		// 删除群成员
		imGroupMemberDao.deleteByImGroupId(imGroupId);
		// 删除群公告
		imGroupNoticeDao.deleteByImGroupId(imGroupId);
		// 删除群信息
		imGroupDao.delete(imGroupId);

		imFeignService.groupDismiss(new GroupModel(imGroupId, null));

		return true;
	}

    @Override
    public List<ImGroup> queryByUserId(Integer userId, String search,String groupType) {
		return imGroupDao.queryByUserId(userId, search,groupType);
    }

    @Override
	public List<ImGroupMemberDto> queryMemberById(String imGroupId) {
		return imGroupDao.queryMemberById(imGroupId);
	}

	@Override
	public ImGroupMemberDto queryMember(String imGroupId, Integer userId) {
		ImGroupMemberDto imGroupMemberDto = imGroupDao.queryMember(imGroupId, userId);
		if(Objects.isNull(imGroupMemberDto)){
			imGroupMemberDto = imGroupDao.queryMember(null, userId);
			if (Objects.nonNull(imGroupMemberDto)){
				imGroupMemberDto.setRoleType(null);
			}
		}
		return imGroupMemberDto;
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public int updateNickName(Integer userId, String nickName) {
		//修改群成员备注
		int i = imGroupDao.updateNickname(userId, nickName);
		imGroupDao.updateUserFriendNickname(userId, nickName);
		return i;
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public void updateNickName1(Integer userId, String nickName) {
		//修改群成员备注
		imGroupDao.updateNickname(userId, nickName);
		imGroupDao.updateUserFriendNickname(userId, nickName);
		//修改sysUser名称，如果包含学员的角色，那么修改userName。否则修改realName
		SysUser sysUser = sysUserService.queryUserById(userId);
		if(sysUser.getUserType().contains("STUDENT")){
			sysUser.setUsername(nickName);
		}else {
			sysUser.setRealName(nickName);
		}
		sysUserService.updateSysUser(sysUser);
		//同步融云基本信息
		imFeignService.update(new ImUserModel(sysUser.getId().toString(),nickName,sysUser.getAvatar()));
	}

    @Override
	@Transactional(rollbackFor = Exception.class)
    public void updateImGroup(ImGroup imGroup) {
		imGroup.setMemberNum(null);
		imGroupDao.update(imGroup);
		imFeignService.groupUpdate(new GroupModel(imGroup.getId(),null,imGroup.getName()));
    }

	@Override
	@Transactional(rollbackFor = Exception.class)
	public void dismissGroup(String imGroupId) {
		imFeignService.groupDismiss(new GroupModel(imGroupId, null));
		imGroupDao.delete(imGroupId);
		imGroupMemberDao.deleteByImGroupId(imGroupId);
		imGroupNoticeDao.deleteByImGroupId(imGroupId);
	}

    @Override
    public List<NameDto> queryDetail(List<NameDto> nameDto) {
		List<NameDto> dtos = new ArrayList<>();
		if(CollectionUtils.isNotEmpty(nameDto)){
			Map<Integer, List<NameDto>> collect = nameDto.stream().collect(Collectors.groupingBy(NameDto::getType));
			for (Integer integer : collect.keySet()) {
				List<NameDto> nameDtos = collect.get(integer);
				if(CollectionUtils.isNotEmpty(nameDtos)){
					String idList = nameDtos.stream().map(e -> e.getId()).collect(Collectors.joining(","));
					if(integer.equals(3)){
						dtos.addAll(imGroupDao.queryNameByIds(idList));
					}else if (integer.equals(1)){
						Integer userId = sysUserService.getUserId();
						dtos.addAll(imUserFriendDao.queryNameByIds(idList,userId));
					}
				}
			}
		}
        return dtos;
    }
}