package com.yonge.cooleshow.biz.dal.service.impl;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.google.common.collect.Lists;
import com.microsvc.toolkit.middleware.im.ImPluginContext;
import com.microsvc.toolkit.middleware.im.message.GroupMemberWrapper;
import com.yonge.cooleshow.biz.dal.dao.ImGroupDao;
import com.yonge.cooleshow.biz.dal.dao.ImGroupMemberDao;
import com.yonge.cooleshow.biz.dal.dao.TeacherDao;
import com.yonge.cooleshow.biz.dal.dto.BasicUserInfo;
import com.yonge.cooleshow.biz.dal.entity.ImGroup;
import com.yonge.cooleshow.biz.dal.entity.ImGroupMember;
import com.yonge.cooleshow.biz.dal.enums.ClientEnum;
import com.yonge.cooleshow.biz.dal.enums.ImGroupMemberRoleType;
import com.yonge.cooleshow.biz.dal.enums.im.EImGroupMemberRoleType;
import com.yonge.cooleshow.biz.dal.service.ImGroupMemberService;
import com.yonge.cooleshow.biz.dal.service.ImGroupService;
import com.yonge.cooleshow.biz.dal.service.im.ImGroupCoreService;
import com.yonge.cooleshow.biz.dal.wrapper.im.ImGroupMemberWrapper;
import com.yonge.toolset.base.exception.BizException;
import io.rong.models.group.GroupMember;
import org.apache.commons.collections.CollectionUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.text.MessageFormat;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * 群成员表(ImGroupMember)表服务实现类
 *
 * @author zx
 * @since 2022-03-22 10:45:58
 */
@Service("imGroupMemberService")
public class ImGroupMemberServiceImpl extends ServiceImpl<ImGroupMemberDao, ImGroupMember> implements ImGroupMemberService {

    private final static Logger log = LoggerFactory.getLogger(ImGroupMemberServiceImpl.class);

    @Resource
    private TeacherDao teacherDao;
    @Resource
    private ImGroupDao imGroupDao;

    @Autowired
    private ImPluginContext imPluginContext;

    @Autowired
    private ImGroupService imGroupService;

    @Autowired
    private ImGroupCoreService imGroupCoreService;

    @Autowired
    private ImGroupMemberDao imGroupMemberDao;

    @Override
    public ImGroupMemberDao getDao() {
        return this.baseMapper;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void insertBatch(List<ImGroupMember> imGroupMembers) {
        if(CollectionUtils.isEmpty(imGroupMembers)){
            throw new BizException("群成员列表不可为空");
        }
        for (ImGroupMember imGroupMember : imGroupMembers) {
            imGroupMember.setGroupMute(false);
            if (Boolean.TRUE.equals(imGroupMember.getIsAdmin())) {
                imGroupMember.setGroupRoleType(EImGroupMemberRoleType.Owner);
            } else {
                imGroupMember.setGroupRoleType(ImGroupMemberRoleType.TEACHER.equals(imGroupMember.getRoleType()) ? EImGroupMemberRoleType.Admin : EImGroupMemberRoleType.Member);
            }
        }
        this.baseMapper.insertBatch(imGroupMembers);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public List<ImGroupMember> initGroupMember(String imGroupId, Long userId, Boolean isAdmin, ImGroupMemberRoleType roleType){
        //记录群成员
        BasicUserInfo basicUserInfo = teacherDao.getBasicUserInfo(userId);
        ImGroupMember imGroupMember = new ImGroupMember(imGroupId,userId,basicUserInfo.getUsername(),basicUserInfo.getAvatar(), isAdmin, roleType);
        Date date = new Date();
        imGroupMember.setCreateTime(date);
        imGroupMember.setUpdateTime(date);
        imGroupMember.setGroupMute(false);
        if (Boolean.TRUE.equals(isAdmin)) {
            imGroupMember.setGroupRoleType(EImGroupMemberRoleType.Owner);
        } else {
            imGroupMember.setGroupRoleType(ImGroupMemberRoleType.TEACHER.equals(roleType) ? EImGroupMemberRoleType.Admin : EImGroupMemberRoleType.Member);
        }
        this.baseMapper.insert(imGroupMember);
        //加入融云群
        List<ImGroupMember> groupMemberList = new ArrayList<>();

        groupMemberList.add(imGroupMember);
        return groupMemberList;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public List<ImGroupMember> initGroupMembers(String imGroupId, Set<Long> userIds, ImGroupMemberRoleType roleType){
        //记录群成员
        List<ImGroupMember> imGroupMembers = baseMapper.initImGroupMember(imGroupId,userIds,roleType.getCode());
        if(CollectionUtils.isNotEmpty(imGroupMembers)){

            for (ImGroupMember item : imGroupMembers) {

                // 用户身份
                item.setRoleType(roleType);
                // 管理员村识
                item.setIsAdmin(ImGroupMemberRoleType.TEACHER == roleType);
                // 默认不禁言
                item.setGroupMute(false);
                if (Boolean.TRUE.equals(item.getIsAdmin())) {
                    item.setGroupRoleType(EImGroupMemberRoleType.Owner);
                } else {
                    item.setGroupRoleType(ImGroupMemberRoleType.TEACHER.equals(roleType) ? EImGroupMemberRoleType.Admin : EImGroupMemberRoleType.Member);
                }
            }
            baseMapper.insertBatch(imGroupMembers);

            return imGroupMembers;
        }
        return new ArrayList<>();
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void join(List<ImGroupMember> groupMemberList,String imGroupId) throws Exception {

        if (CollectionUtils.isEmpty(groupMemberList)) {
            // 群成员为空，直接忽略
            return;
        }

        // 判断群ID是否有效
        ImGroup imGroup = imGroupDao.selectById(imGroupId);
        if (Objects.isNull(imGroup)) {
            throw new BizException("群组不存在");
        }
        List<com.yonge.cooleshow.biz.dal.wrapper.im.ImGroupMemberWrapper.ImGroupMember> groupMembers = Lists.newArrayList();
        for (ImGroupMember groupMember : groupMemberList) {
            groupMembers.add(com.yonge.cooleshow.biz.dal.wrapper.im.ImGroupMemberWrapper.ImGroupMember.builder()
                    .groupId(groupMember.getGroupId())
                    .userId(groupMember.getUserId())
                    .clientType(groupMember.getRoleType().getCode())
                    .avatar(groupMember.getAvatar())
                    .nickname(groupMember.getNickname())
                    .isAdmin(groupMember.getIsAdmin())
                    .imUserId(imGroupCoreService.getImUserId(groupMember.getUserId().toString(), groupMember.getRoleType().getCode()))
                    .roleType(groupMember.getRoleType().getCode())
                    .groupMute(groupMember.getGroupMute())
                    .groupRoleType(groupMember.getIsAdmin()?EImGroupMemberRoleType.Owner:
                            (ImGroupMemberRoleType.TEACHER.equals(groupMember.getRoleType())?EImGroupMemberRoleType.Admin:EImGroupMemberRoleType.Member))
                    .build());
        }
        // 添加群成员到当前群组
        imGroupCoreService.saveImGroupMemberList(imGroup.getId(), groupMembers);

    }



    @Override
    @Transactional(rollbackFor = Exception.class)
    public void delByGroupId(String groupId) {
        this.baseMapper.delByGroupId(groupId);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ImGroupMember getUserDetail(String imUserId, String groupId) {

        // 用户ID
        Long userId = Long.parseLong(imGroupService.analysisImUserId(imUserId));

        // 客户端类型
        ClientEnum clientType = ClientEnum.valueOf(imGroupService.analysisImUserClient(imUserId));

        // 群组信息
        ImGroupMember imGroupMember = baseMapper.findByUserIdAndGroupId(userId, groupId, clientType);

        // 用户基本信息
        BasicUserInfo basicUserInfo = teacherDao.getBasicUserInfo(userId);
        if(Objects.isNull(imGroupMember)){
            imGroupMember = new ImGroupMember();
            imGroupMember.setGroupId(groupId);
            imGroupMember.setUserId(userId);
        }
        //更新当前用户关联的该用户的详情信息
        imGroupMember.setNickname(basicUserInfo.getUsername());
        imGroupMember.setAvatar(basicUserInfo.getAvatar());
        if(imGroupMember.getId() != null){
            imGroupMember.setUpdateTime(new Date());
            baseMapper.updateById(imGroupMember);
        }

        // 设置IM好友ID
        imGroupMember.setImUserId(imUserId);

        return imGroupMember;
    }

    @Transactional(rollbackFor = Exception.class)
    public void startTransactional(Runnable runnable){
        runnable.run();
    }


    /**
     * 群组成员信息
     *
     * @param params Map<String, Object>
     * @return List<ImGroupMember>
     */
    @Override
    public List<ImGroupMember> findChatGroupAllMemberInfo(Map<String, Object> params) {

        Object search = params.get("search");
        if (search == null) {
            search = params.get("keyword");
        }
        Object keyword = search;

        Boolean groupMute = params.get("groupMute") == null ? null : Boolean.valueOf(params.get("groupMute").toString());
        List<String> groupRoleTypes = params.get("groupRoleTypes") == null ? new ArrayList() : ((List) params.get("groupRoleTypes"));
        String groupRoleTypesTr = String.join(",", groupRoleTypes);
        List<ImGroupMember> members = getBaseMapper().selectList(Wrappers.<ImGroupMember>query().lambda()
                .and(Objects.nonNull(keyword) && StringUtils.isNotEmpty(keyword.toString()),
                        e->e.eq(ImGroupMember::getUserId, keyword).or()
                                .like(ImGroupMember::getNickname, keyword))
                .eq(ImGroupMember::getGroupId, params.get("groupId"))
                .eq(groupMute != null, ImGroupMember::getGroupMute, groupMute)
                .apply(StringUtils.isNotEmpty(groupRoleTypesTr), "find_in_set(group_role_type_,'" + groupRoleTypesTr + "')")
                .orderByDesc(ImGroupMember::getId));

        if (CollectionUtils.isNotEmpty(members)) {

            for (ImGroupMember item : members) {

                if (ImGroupMemberRoleType.STUDENT == item.getRoleType()) {
                    item.setImUserId(imGroupService.getImUserId(String.valueOf(item.getUserId()),ClientEnum.STUDENT.name()));
                }else if(ImGroupMemberRoleType.TEACHER == item.getRoleType()){
                    item.setImUserId(imGroupService.getImUserId(String.valueOf(item.getUserId()),ClientEnum.TEACHER.name()));
                }
            }
        }

        return Optional.ofNullable(members).orElse(Lists.newArrayList());
    }

    @Override
    public IPage<ImGroupMemberWrapper.ImGroupMember> selectPage(IPage<ImGroupMemberWrapper.ImGroupMember> page, ImGroupMemberWrapper.ImGroupMemberQuery query) {
        return page.setRecords(imGroupMemberDao.selectPage(page, query));
    }
}

