package com.wecloud.im.service.impl;

import io.geekidea.springbootplus.framework.common.exception.BusinessException;
import io.geekidea.springbootplus.framework.shiro.util.SecurityUtils;
import lombok.AllArgsConstructor;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import org.springframework.stereotype.Service;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.wecloud.im.entity.ImApplication;
import com.wecloud.im.entity.ImClient;
import com.wecloud.im.entity.ImConversation;
import com.wecloud.im.entity.ImConversationMembers;
import com.wecloud.im.entity.ImMessage;
import com.wecloud.im.mapper.ImConversationMapper;
import com.wecloud.im.param.add.ServerImConversationCreate;
import com.wecloud.im.post.MessageBuilder;
import com.wecloud.im.sdk.enums.ChatTypeEnum;
import com.wecloud.im.sdk.enums.GroupRoleEnum;
import com.wecloud.im.sdk.enums.MutedEnum;
import com.wecloud.im.service.ImApplicationService;
import com.wecloud.im.service.ImClientService;
import com.wecloud.im.service.ImConversationMembersService;
import com.wecloud.im.service.ImConversationService;
import com.wecloud.im.service.ImGroupService;
import com.wecloud.im.service.ImMessageService;
import com.wecloud.im.ws.enums.MsgTypeEnum;
import com.wecloud.imserver.client.model.enums.DeviceTypeEnum;
import com.wecloud.utils.JsonUtils;
import com.wecloud.utils.SnowflakeUtil;

/**
 * 群服务
 * @Author luozh
 * @Date 2022年05月10日 15:23
 * @Version 1.0
 */
@AllArgsConstructor
@Service
public class ImGroupServiceImpl implements ImGroupService {

    /**
     * 应用服务
     */
    private final ImApplicationService applicationService;

    /**
     * 客户端服务
     */
    private final ImClientService clientService;

    /**
     * 会话服务
     */
    private final ImConversationService conversationService;

    /**
     * 会话成员服务
     */
    private final ImConversationMembersService conversationMembersService;

    /**
     * 会话mapper
     */
    private final ImConversationMapper imConversationMapper;

    /**
     * 消息服务
     */
    private final ImMessageService imMessageService;

    @Override
    public Long createGroup(String creatorClientId, String groupName, List<String> memberIds) {
        // 获取应用
        Long appId = SecurityUtils.getCurrentAppId();
        ImApplication application = applicationService.getCacheById(appId);

        // 获取创建人信息
        ImClient creator = clientService.getCacheImClient(appId, creatorClientId);
        if (creator == null) {
            throw new BusinessException("创建人不存在");
        }

        // 获取群成员信息
        List<ImClient> members =
                clientService.list(Wrappers.<ImClient>lambdaQuery().eq(ImClient::getFkAppid, appId).in(ImClient::getClientId, memberIds));
        if (members.isEmpty()) {
            throw new BusinessException("群成员列表为空");
        }

        ServerImConversationCreate serverImConversationCreate = new ServerImConversationCreate();
        serverImConversationCreate.setName(groupName);
        serverImConversationCreate.setApplication(application);
        serverImConversationCreate.setCreator(creator);
        serverImConversationCreate.setMembers(members);
        serverImConversationCreate.setChatType(ChatTypeEnum.NORMAL_GROUP);
        serverImConversationCreate.setPlatform(DeviceTypeEnum.IOS);

        ImConversation conversation =
                conversationService.serverCreateImConversation(serverImConversationCreate);

        return conversation.getId();
    }

    @Override
    public Boolean dismissGroup(String userId, String groupId) {
        // 获取应用
        Long appId = SecurityUtils.getCurrentAppId();
        ImApplication application = applicationService.getCacheById(appId);

        // 查询操作人
        ImClient operator = clientService.getCacheImClient(appId, userId);
        if (operator == null) {
            throw new BusinessException("操作人不存在");
        }
        // 查询会话
        ImConversation conversation =
                conversationService.getOne(Wrappers.<ImConversation>lambdaQuery().eq(ImConversation::getFkAppid,
                        appId).eq(ImConversation::getId, groupId));
        if (conversation == null) {
            throw new BusinessException("群组不存在");
        }

        // 查询该会话所有成员
        List<ImConversationMembers> membersList = conversationMembersService.list(
                new QueryWrapper<ImConversationMembers>().lambda()
                        .eq(ImConversationMembers::getFkAppid, appId)
                        .eq(ImConversationMembers::getFkConversationId, conversation.getId())
        );
        if (membersList.isEmpty()) {
            throw new BusinessException("群聊成员列表为空");
        }
        // 删除所有成员
        conversationMembersService.deleteByConversationId(conversation.getId());

        // 保存事件消息

        Map<String, Object> content = new HashMap<>();
        content.put("operator", operator.getClientId());

        ImMessage imMessage = MessageBuilder.buildEventMessage(MsgTypeEnum.CONVERSATION_DISBAND, application,
                operator, conversation, JsonUtils.encodeJson(content));
        //  保存消息至消息表
        imMessageService.save(imMessage);
        conversationService.sendMsgToMembers(conversation, membersList, operator, imMessage, content);
        return true;

    }

    @Override
    public Integer joinGroup(String groupId, List<String> memberClientIds) {
        Long appId = SecurityUtils.getCurrentAppId();
        ImApplication imApplication = applicationService.getCacheById(appId);
        // 查询会话
        ImConversation conversation =
                conversationService.getOne(Wrappers.<ImConversation>lambdaQuery().eq(ImConversation::getFkAppid,
                        appId).eq(ImConversation::getId, groupId));
        if (conversation == null) {
            throw new BusinessException("群组不存在");
        }
        // 查询客户端信息
        List<ImClient> clientList = clientService.list(Wrappers.<ImClient>lambdaQuery().eq(ImClient::getFkAppid,
                appId).in(ImClient::getClientId, memberClientIds));

        // 查找已经在群组里的客户端
        List<ImConversationMembers> existMemberList =
                conversationMembersService.list(Wrappers.<ImConversationMembers>lambdaQuery()
                        .eq(ImConversationMembers::getFkConversationId, conversation.getId())
                        .in(ImConversationMembers::getClientId, memberClientIds));
        if (!existMemberList.isEmpty()) {
            List<String> existMemberClientIds =
                    existMemberList.stream().map(ImConversationMembers::getClientId).collect(Collectors.toList());

            clientList = clientList.stream().filter(client -> !existMemberClientIds.contains(client.getClientId())).collect(Collectors.toList());
        }
        // 加入群聊
        // 将他人添加到会话
        List<ImConversationMembers> newMemberList = new ArrayList<>();
        for (ImClient client : clientList) {
            Date now = new Date();
            Long imConversationMembersId2 = SnowflakeUtil.getId();
            ImConversationMembers newMember = new ImConversationMembers();
            newMember.setUpdateTime(now);
            newMember.setId(imConversationMembersId2);
            newMember.setCreateTime(now);
            newMember.setFkAppid(imApplication.getId());
            newMember.setFkConversationId(conversation.getId());
            newMember.setFkClientId(client.getId());
            newMember.setClientId(client.getClientId());
            newMember.setMuted(MutedEnum.NO.getCode());
            newMember.setRole(GroupRoleEnum.NORMAL.getCode());
            newMemberList.add(newMember);

        }
        conversationMembersService.saveBatch(newMemberList);
        // 将群成员数量增加
        imConversationMapper.addMemberCount(imApplication.getId(), conversation.getId(), clientList.size());

        return clientList.size();
    }

    @Override
    public Integer leaveGroup(String groupId, List<String> memberClientIds) {
        Long appId = SecurityUtils.getCurrentAppId();
        ImApplication imApplication = applicationService.getCacheById(appId);
        // 查询会话
        ImConversation conversation =
                conversationService.getOne(Wrappers.<ImConversation>lambdaQuery().eq(ImConversation::getFkAppid,
                        appId).eq(ImConversation::getId, groupId));
        if (conversation == null) {
            throw new BusinessException("群组不存在");
        }

        // 查找在群组里的客户端
        List<ImConversationMembers> existMemberList =
                conversationMembersService.list(Wrappers.<ImConversationMembers>lambdaQuery()
                        .eq(ImConversationMembers::getFkConversationId, conversation.getId())
                        .in(ImConversationMembers::getClientId, memberClientIds));
        if (!existMemberList.isEmpty()) {
            List<Long> conversationMemberIds =
                    existMemberList.stream().map(ImConversationMembers::getId).collect(Collectors.toList());
            conversationMembersService.removeByIds(conversationMemberIds);
            // 将群成员数量减
            imConversationMapper.addMemberCount(imApplication.getId(), conversation.getId(), -existMemberList.size());
        }
        return existMemberList.size();
    }

    @Override
    public List<String> listGroupMembers(String groupId) {
        Long appId = SecurityUtils.getCurrentAppId();
        // 获取会话
        ImConversation conversation =
                conversationService.getOne(Wrappers.<ImConversation>lambdaQuery()
                        .eq(ImConversation::getFkAppid, appId)
                        .eq(ImConversation::getId, groupId));
        if (conversation == null) {
            throw new BusinessException("群组不存在");
        }
        // 获取群成员
        List<ImConversationMembers> membersList =
                conversationMembersService.list(Wrappers.<ImConversationMembers>lambdaQuery().eq(ImConversationMembers::getFkConversationId, groupId));

        return membersList.stream().map(ImConversationMembers::getClientId).collect(Collectors.toList());
    }
}
