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

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
import com.yonge.cooleshow.auth.api.client.SysUserFeignService;
import com.yonge.cooleshow.auth.api.entity.SysUser;
import com.yonge.cooleshow.auth.config.CustomerServiceConfig;
import com.yonge.cooleshow.biz.dal.config.RongCloudConfig;
import com.yonge.cooleshow.biz.dal.dao.ImUserFriendDao;
import com.yonge.cooleshow.biz.dal.dao.TeacherDao;
import com.yonge.cooleshow.biz.dal.dto.BasicUserInfo;
import com.yonge.cooleshow.biz.dal.entity.ImUserFriend;
import com.yonge.cooleshow.biz.dal.enums.MK;
import com.yonge.cooleshow.biz.dal.mapper.SysUserMapper;
import com.yonge.cooleshow.biz.dal.service.ImUserFriendService;
import com.yonge.cooleshow.biz.dal.wrapper.im.CustomerService;
import com.yonge.toolset.base.exception.BizException;
import io.rong.messages.BaseMessage;
import io.rong.messages.FileMessage;
import io.rong.messages.ImgMessage;
import io.rong.messages.ImgTextMessage;
import io.rong.messages.TxtMessage;
import io.rong.models.message.PrivateMessage;
import io.rong.models.message.PushExt;
import io.rong.models.response.ResponseResult;
import lombok.extern.slf4j.Slf4j;
import net.coobird.thumbnailator.Thumbnails;
import org.apache.commons.codec.binary.Base64;
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 javax.annotation.Resource;
import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * 用户通讯录表(ImUserFriend)表服务实现类
 *
 * @author zx
 * @since 2022-03-22 10:46:00
 */
@Slf4j
@Service("imUserFriendService")
public class ImUserFriendServiceImpl extends ServiceImpl<ImUserFriendDao, ImUserFriend> implements ImUserFriendService {

    @Resource
    private TeacherDao teacherDao;
    @Resource
    private SysUserFeignService sysUserFeignService;
    @Autowired
    private CustomerServiceConfig customerServiceConfig;
    @Autowired
    private SysUserMapper sysUserMapper;

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

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void saveUserFriend(Long teacherId, Set<Long> studentIds) {
        Date now = new Date();
        //老师添加学员联系人
        List<ImUserFriend> imUserFriends = new ArrayList<>();
        BasicUserInfo basicUserInfo = teacherDao.getBasicUserInfo(teacherId);
        List<BasicUserInfo> basicUserInfoList = teacherDao.findBasicUserInfo(studentIds);
        basicUserInfoList.add(basicUserInfo);
        Map<Long, List<BasicUserInfo>> basicUserInfoMap = basicUserInfoList.stream().collect(Collectors.groupingBy(BasicUserInfo::getUserId));
        for(Long studentId : studentIds){
            //老师关联学员
            ImUserFriend teacherFriend = new ImUserFriend();
            //学员关联老师
            ImUserFriend studentFriend = new ImUserFriend();
            List<BasicUserInfo> basicUserInfos = basicUserInfoMap.get(studentId);
            if(CollectionUtils.isNotEmpty(basicUserInfos)){
                BasicUserInfo info = basicUserInfos.get(0);
                teacherFriend.setFriendAvatar(info.getAvatar());
                teacherFriend.setFriendNickname(info.getUsername());
                studentFriend.setFriendAvatar(basicUserInfo.getAvatar());
                studentFriend.setFriendNickname(basicUserInfo.getUsername());
            }
            teacherFriend.setFriendId(studentId);
            teacherFriend.setUserId(teacherId);
            teacherFriend.setCreateTime(now);
            teacherFriend.setUpdateTime(now);

            studentFriend.setFriendId(teacherId);
            studentFriend.setUserId(studentId);
            studentFriend.setCreateTime(now);
            studentFriend.setUpdateTime(now);
            imUserFriends.add(teacherFriend);
            imUserFriends.add(studentFriend);
        }
        baseMapper.insertBatch(imUserFriends);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ImUserFriend getDetail(Long userId) {
        SysUser sysUser = sysUserFeignService.queryUserInfo();
        BasicUserInfo basicUserInfo = teacherDao.getBasicUserInfo(userId);
        if(sysUser != null && sysUser.getId() != null){
            ImUserFriend imUserFriend = baseMapper.findByUserIdAndFriendId(sysUser.getId(),userId);
            if(Objects.nonNull(imUserFriend)){
                //更新当前用户关联的该用户的详情信息
                imUserFriend.setFriendAvatar(basicUserInfo.getAvatar());
                imUserFriend.setFriendNickname(basicUserInfo.getUsername());
                imUserFriend.setUpdateTime(new Date());
                baseMapper.updateById(imUserFriend);
                return imUserFriend;
            }
        }
        ImUserFriend imUserFriend = new ImUserFriend();
        imUserFriend.setFriendAvatar(basicUserInfo.getAvatar());
        imUserFriend.setFriendNickname(basicUserInfo.getUsername());
        imUserFriend.setFriendId(userId);
        return imUserFriend;
    }

    /**
     * 新用户自动添加客服
     *
     * @param userId    新用户ID
     * @param friendIds 好友ID
     * @return Integer
     */
    @Override
    public Integer registerUserBindCustomerService(Long userId, List<Long> friendIds) {

        // 添加新用户好友
        saveUserFriend(userId, Sets.newHashSet(friendIds));

        try {

            // 设置默认值
            String customerMessage = customerServiceConfig.getCustomerMessage();
            if (StringUtils.isEmpty(customerMessage)) {
                customerMessage = MK.IM_SYS_FRIEND;
            }

            String customerTitle = customerServiceConfig.getCustomerTitle();
            if (StringUtils.isEmpty(customerTitle)) {
                customerTitle = MK.IM_SYS_TITLE;
            }

            // 发送消息
            TxtMessage txtMessage = new TxtMessage(customerMessage, "");

            // 拓展消息
            PushExt pushExt = PushExt.build(customerTitle, 1,
                    new PushExt.HW("channelId", "NORMAL"), new PushExt.VIVO("1"),
                    new PushExt.APNs("", ""),
                    new PushExt.OPPO(""));

            // 发送用户IM通知消息
            PrivateMessage privateMessage = new PrivateMessage()
                    .setSenderId(String.valueOf(friendIds.get(0)))
                    .setTargetId(new String[]{String.valueOf(userId)})
                    .setObjectName(txtMessage.getType())
                    .setContent(txtMessage)
                    .setPushExt(pushExt)
                    .setIsIncludeSender(1);

            ResponseResult privateResult = RongCloudConfig.rongCloud.message.msgPrivate.send(privateMessage);
            log.info("registerUserBindCustomerService userId={}, ret={}", userId, privateResult.getCode());
        } catch (Exception e) {
            log.error("registerUserBindCustomerService userId={}", userId, e);
        }

        return CollectionUtils.size(friendIds);
    }

    /**
     * 发送系统客服消息
     *
     * @param sender 发送者
     * @param info   CustomerService.NotifyMessage
     */
    @Override
    public void sendCustomerServiceNotifyMessage(String sender, CustomerService.NotifyMessage info) {

        // 发送者信息
        com.yonge.cooleshow.biz.dal.entity.SysUser senderUser = sysUserMapper.selectOne(Wrappers.<com.yonge.cooleshow.biz.dal.entity.SysUser>lambdaQuery()
                .eq(com.yonge.cooleshow.biz.dal.entity.SysUser::getPhone, sender));

        if (Objects.isNull(senderUser)) {
            throw new BizException("无效的客服联系方式");
        }

        LambdaQueryWrapper<com.yonge.cooleshow.biz.dal.entity.SysUser> wrapper = Wrappers.<com.yonge.cooleshow.biz.dal.entity.SysUser>lambdaQuery()
                .select(com.yonge.cooleshow.biz.dal.entity.SysUser::getId,
                        com.yonge.cooleshow.biz.dal.entity.SysUser::getUsername)
                .in(com.yonge.cooleshow.biz.dal.entity.SysUser::getPhone, info.getReceives());

        wrapper.last("LIMIT 1000");
        // 接收者信息
        List<com.yonge.cooleshow.biz.dal.entity.SysUser> sysUsers = sysUserMapper.selectList(wrapper);

        // 发送图片消息
        ImgMessage imgMessage = new ImgMessage(imageToBase64(info.getImgMessage(), "png"), "", info.getImgUrl());

        // 发送文本消息
        TxtMessage txtMessage = new TxtMessage(info.getTxtMessage(), "");

        List<BaseMessage> messages = Lists.newArrayList(imgMessage, txtMessage);

        // 拓展消息
        PushExt pushExt = PushExt.build(info.getTitle(), 1,
                new PushExt.HW("channelId", "NORMAL"), new PushExt.VIVO("1"),
                new PushExt.APNs("", ""),
                new PushExt.OPPO(""));

        // 分批次发送用户消息
        List<String> receiveUserIds = sysUsers.stream()
                .map(com.yonge.cooleshow.biz.dal.entity.SysUser::getId)
                .map(String::valueOf)
                .collect(Collectors.toList());

        String senderId = String.valueOf(senderUser.getId());
        PrivateMessage privateMessage;
        ResponseResult privateResult;
        for (List<String> item : Lists.partition(receiveUserIds, 100)) {

            try {

                for (BaseMessage message : messages) {

                    // 发送用户IM通知消息
                    privateMessage = new PrivateMessage()
                            .setSenderId(senderId)
                            .setTargetId(item.toArray(new String[0]))
                            .setObjectName(message.getType())
                            .setContent(message)
                            .setPushExt(pushExt)
                            .setIsIncludeSender(0);

                    privateResult = RongCloudConfig.rongCloud.message.msgPrivate.send(privateMessage);
                    log.info("sendCustomerServiceNotifyMessage senderId={}, ret={}", senderId, privateResult.getCode());
                }

            } catch (Exception e) {
                log.error("sendCustomerServiceNotifyMessage senderId={}", senderId, e);
            }

        }

    }

    public static String imageToBase64(String imgMessage, String suffix) {

        Base64 encoder = new Base64();
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        try {
            URL url = new URL(imgMessage);
            BufferedImage bufferedImage = Thumbnails.of(url).scale(0.1f).outputQuality(0.25f).asBufferedImage();
            ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
            ImageIO.write(bufferedImage, suffix, outputStream);

            byte[] bytes = outputStream.toByteArray();
            outputStream.close();
            int length = bytes.length;
            //文件大小不能超过393216 Bytes
            if (length > 393216) {
                throw new BizException("文件过大请调整 像素 或 文件大小");
            }

            ImageIO.write(bufferedImage, suffix, baos);
        } catch (IOException e) {
            log.error("imageToBase64", e);
        }
        return new String(encoder.encode((baos.toByteArray())));
    }



}

