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

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ym.mec.auth.api.client.SysUserFeignService;
import com.ym.mec.auth.api.entity.SysUser;
import com.ym.mec.biz.dal.dao.ImLiveRoomBlackDao;
import com.ym.mec.biz.dal.entity.ImLiveRoomBlack;
import com.ym.mec.biz.dal.vo.ImLiveRoomBlackVo;
import com.ym.mec.biz.service.ImLiveRoomBlackService;
import com.ym.mec.common.entity.ImRoomMessage;
import com.ym.mec.common.exception.BizException;
import com.ym.mec.common.page.PageInfo;
import com.ym.mec.common.page.PageUtil;
import com.ym.mec.common.page.WrapperUtil;
import com.ym.mec.common.tenant.TenantContextHolder;
import com.ym.mec.im.ImFeignService;
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 java.util.*;

/**
 * 直播房间黑名单表(ImLiveRoomBlack)表服务实现类
 *
 * @author hgw
 * @since 2022-05-30 14:58:32
 */
@Service("imLiveRoomBlackService")
public class ImLiveRoomBlackServiceImpl extends ServiceImpl<ImLiveRoomBlackDao, ImLiveRoomBlack> implements ImLiveRoomBlackService {

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

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

    /**
     * 查询当前机构学生 -下拉框
     *
     * @param param 参数
     *              <p> search - 搜索关键字
     *              <p> roomUid - 房间uid
     */
    @Override
    public PageInfo<SysUser> queryStudentList(Map<String, Object> param) {
        Page<SysUser> pageInfo = PageUtil.getPageInfo(param);
        pageInfo.setDesc("id_");
        Integer tenantId = TenantContextHolder.getTenantId();
        //管理员机构id 是-1
        if (Objects.nonNull(tenantId) && tenantId != -1) {
            param.put("tenantId", tenantId);
        }
        return PageUtil.pageInfo(baseMapper.queryStudent(pageInfo, param));
    }

    /**
     * 添加用户到房间黑名单中
     *
     * @param param 参数
     *              <P> roomUid 直播房间uid
     *              <P> userIdList  用户id
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void add(Map<String, Object> param) {
        String roomUid = WrapperUtil.toStr(param, "roomUid");
        List<String> userIdList = WrapperUtil.toList(WrapperUtil.toStr(param, "userIdList", "用户id不能为空"));
        userIdList.forEach(userIdStr -> {
            Integer userId = Integer.parseInt(userIdStr);
            int count = this.count(Wrappers.<ImLiveRoomBlack>lambdaQuery()
                    .eq(ImLiveRoomBlack::getRoomUid, roomUid)
                    .eq(ImLiveRoomBlack::getUserId, userId));
            if (count > 0) {
                throw new BizException("该用户已在黑名单中");
            }
            ImLiveRoomBlack imLiveRoomBlack = new ImLiveRoomBlack();
            imLiveRoomBlack.setRoomUid(roomUid);
            imLiveRoomBlack.setUserId(userId);
            imLiveRoomBlack.setType(0);
            imLiveRoomBlack.setCreateBy(getSysUser().getId());
            imLiveRoomBlack.setCreateTime(new Date());
            this.save(imLiveRoomBlack);
            //发送消息到直播房间
            this.sendBlackMsg(roomUid, userId, userId, ImRoomMessage.BLOCK_BLACK_USER);
            //调用融云方法加入禁言
            imFeignService.addUserUnableSpeak(roomUid, userIdStr);
        });
    }

    /**
     * 删除该用户从房间黑名单中移除
     *
     * @param param 参数
     *              <P> roomUid 直播房间uid
     *              <P> userIdList  用户id
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void delete(Map<String, Object> param) {
        String roomUid = WrapperUtil.toStr(param, "roomUid");
        List<String> userIdList = WrapperUtil.toList(WrapperUtil.toStr(param, "userIdList", "用户id不能为空"));
        userIdList.forEach(userIdStr -> {
            Integer userId = Integer.parseInt(userIdStr);
            this.remove(Wrappers.<ImLiveRoomBlack>lambdaQuery()
                    .eq(ImLiveRoomBlack::getRoomUid, roomUid)
                    .eq(ImLiveRoomBlack::getUserId, userId));
            //发送消息到直播房间
            this.sendBlackMsg(roomUid, userId, userId, ImRoomMessage.UNBLOCK_BLACK_USER);
            //调用融云方法加入禁言
            imFeignService.removeUserUnableSpeak(roomUid, userIdStr);
        });
    }

    /**
     * 查询房间的黑名单学生
     * <P> roomUid 直播房间uid
     * <P> search  搜索关键字
     */
    @Override
    public PageInfo<ImLiveRoomBlackVo> queryBlackList(Map<String, Object> param) {
        WrapperUtil.toStr(param, "roomUid", "房间编号不能为空");
        Page<ImLiveRoomBlackVo> pageInfo = PageUtil.getPageInfo(param);
        pageInfo.setDesc("a.create_time_");
        IPage<ImLiveRoomBlackVo> imLiveRoomBlackVoIPage = baseMapper.queryBlackList(pageInfo, param);
        return PageUtil.pageInfo(imLiveRoomBlackVoIPage);
    }

    /**
     * 发送黑名单消息到直播房间
     *
     * @param roomUid    房间uid
     * @param fromUserId 发送人id
     * @param userId     用户id
     */
    public void sendBlackMsg(String roomUid, Integer fromUserId, Integer userId, String type) {
        //校验传入参数，房间uid和发送人id不能为空
        if (!WrapperUtil.checkObj(roomUid, fromUserId, userId, type)) {
            log.info(" sendBlackMsg>>>> param is null   roomUid: {}  fromUserId:{}  type:{}", roomUid, fromUserId, type);
            return;
        }
        ImRoomMessage message = new ImRoomMessage();
        message.setIsIncludeSender(1);
        message.setObjectName(type);
        message.setToChatroomId(roomUid);
        HashMap<String, Integer> sendMap = new HashMap<>();
        sendMap.put("userId", userId);
        message.setFromUserId(fromUserId.toString());
        message.setContent(sendMap);
        //发送消息
        try {
            imFeignService.publishRoomMsg(message);
            log.info("sendBlackMsg>>>> message: {}", JSONObject.toJSONString(message));
        } catch (Exception e) {
            log.error("sendBlackMsg>>>> error {}", e.getMessage());
            log.error("sendBlackMsg>>>> sendMessage {} :", JSONObject.toJSONString(message));
        }
    }

    private SysUser getSysUser() {
        //修改机构基础信息
        return Optional.ofNullable(sysUserFeignService.queryUserInfo())
                .orElseThrow(() -> new BizException("用户不存在"));
    }

}

