package com.ruoyi.im.service.impl;


import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.basic.service.YjAppUserService;
import com.ruoyi.common.core.domain.entity.AppUser;
import com.ruoyi.common.im.constant.RedisKey;
import com.ruoyi.common.exception.GlobalException;
import com.ruoyi.common.im.enums.IMTerminalType;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.im.domain.Friend;
import com.ruoyi.im.domain.vo.FriendVO;
import com.ruoyi.im.domain.vo.OnlineTerminalVO;
import com.ruoyi.im.service.FriendService;
import com.ruoyi.im.mapper.FriendMapper;
import com.ruoyi.imclient.IMClient;
import com.ruoyi.system.service.SysTeacherService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.aop.framework.AopContext;
import org.springframework.cache.annotation.CacheConfig;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.stream.Collectors;

@Slf4j
@Service
@RequiredArgsConstructor
@CacheConfig(cacheNames = RedisKey.IM_CACHE_FRIEND)
public class FriendServiceImpl extends ServiceImpl<FriendMapper, Friend> implements FriendService {

    private final IMClient imClient;

   private final YjAppUserService yjAppUserService;
   private final SysTeacherService t;
    @Override
    public Map findAllFriends() {
        Long userId= SecurityUtils.getAppLoginUser().getAppUser().getId();
        Map<String, List<FriendVO>> map=new HashMap<>();
        Long manageId= SecurityUtils.getAppLoginUser().getAppUser().getManageAccountId();
        if (ObjectUtil.isNotEmpty(manageId)){
            List<FriendVO>  list=baseMapper.getFriendListForManage(userId);
            map.put("consumer",list);
            map.put("all",list);//所有好友
            return  map;
        }
        Long storeId=SecurityUtils.getAppLoginUser().getAppUser().getVisitStore();

        List<FriendVO>  list=baseMapper.getFriendListForConsumer(storeId);
        Map<Long, List<FriendVO>> friendMap = list.stream().collect(Collectors.groupingBy(FriendVO::getRoleId));

        map.put("storeManager",friendMap.get(105l));//店长
        map.put("coach",friendMap.get(104l));//教练
        map.put("adviser",friendMap.get(103l));//课程顾问
        map.put("customerService",friendMap.get(108l));//客服
        map.put("all",list);//所有好友

        return  map;

    }


    @Override
    public List<Friend> findByFriendIds(List<Long> friendIds) {
        Long userId= SecurityUtils.getAppLoginUser().getAppUser().getId();
        LambdaQueryWrapper<Friend> wrapper = Wrappers.lambdaQuery();
        wrapper.eq(Friend::getUserId, userId);
        wrapper.in(Friend::getFriendId, friendIds);
        wrapper.eq(Friend::getDeleted,false);
        return this.list(wrapper);
    }



    @Transactional(rollbackFor = Exception.class)
    @Override
    public void addFriend(Long friendId) {
        Long userId= SecurityUtils.getAppLoginUser().getAppUser().getId();
        if (friendId.equals(userId)) {
            throw new GlobalException("不允许添加自己为好友");
        }
        // 互相绑定好友关系
        FriendServiceImpl proxy = (FriendServiceImpl)AopContext.currentProxy();
        proxy.bindFriend(userId, friendId);
        proxy.bindFriend(friendId, userId);
        // 推送添加好友提示
        sendAddTipMessage(friendId);
        log.info("添加好友，用户id:{},好友id:{}", userId, friendId);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void delFriend(Long friendId) {
        Long userId= SecurityUtils.getAppLoginUser().getAppUser().getId();
        // 互相解除好友关系，走代理清理缓存
        FriendServiceImpl proxy = (FriendServiceImpl)AopContext.currentProxy();
        proxy.unbindFriend(userId, friendId);
        proxy.unbindFriend(friendId, userId);
        // 推送解除好友提示
        sendDelTipMessage(friendId);
        log.info("删除好友，用户id:{},好友id:{}", userId, friendId);
    }

    @Cacheable(key = "#userId1+':'+#userId2")
    @Override
    public Boolean isFriend(Long userId1, Long userId2) {
        LambdaQueryWrapper<Friend> wrapper = Wrappers.lambdaQuery();
        wrapper.eq(Friend::getUserId, userId1);
        wrapper.eq(Friend::getFriendId, userId2);
        wrapper.eq(Friend::getDeleted,false);

        return this.count(wrapper)==0l?false:true;
    }

    /**
     * 单向绑定好友关系
     *
     * @param userId   用户id
     * @param friendId 好友的用户id
     */
    @CacheEvict(key = "#userId+':'+#friendId")
    public void bindFriend(Long userId, Long friendId) {
        QueryWrapper<Friend> wrapper = new QueryWrapper<>();
        wrapper.lambda().eq(Friend::getUserId, userId).eq(Friend::getFriendId, friendId);
        Friend friend = this.getOne(wrapper);
        if (Objects.isNull(friend)) {
            friend = new Friend();
        }
        friend.setUserId(userId);
        friend.setFriendId(friendId);
        AppUser friendInfo = yjAppUserService.getById(friendId);
        friend.setFriendHeadImage(friendInfo.getAvatar());
        friend.setFriendNickName(friendInfo.getNickName());
        friend.setDeleted(false);
        this.saveOrUpdate(friend);
//        // 推送好友变化信息s
//        sendAddFriendMessage(userId, friendId, friend);
    }

    /**
     * 单向解除好友关系
     *
     * @param userId   用户id
     * @param friendId 好友的用户id
     */
    @CacheEvict(key = "#userId+':'+#friendId")
    public void unbindFriend(Long userId, Long friendId) {
        // 逻辑删除
        LambdaUpdateWrapper<Friend> wrapper = Wrappers.lambdaUpdate();
        wrapper.eq(Friend::getUserId, userId);
        wrapper.eq(Friend::getFriendId, friendId);
        wrapper.set(Friend::getDeleted,true);
        this.update(wrapper);
        // 推送好友变化信息
        sendDelFriendMessage(userId, friendId);
    }

    @Override
    @CacheEvict(key = "#userId+':'+#friendId")
    public FriendVO findFriend(Long userId, Long friendId) {
        LambdaQueryWrapper<Friend> wrapper = Wrappers.lambdaQuery();
        wrapper.eq(Friend::getUserId, userId);
        wrapper.eq(Friend::getFriendId, friendId);
        Friend friend = this.getOne(wrapper);
        if (Objects.isNull(friend)) {
            friend = new Friend();
        }
        friend.setUserId(userId);
        friend.setFriendId(friendId);
        AppUser friendInfo = yjAppUserService.getById(friendId);
        friend.setFriendHeadImage(friendInfo.getAvatar());
        friend.setFriendNickName(friendInfo.getNickName());
        friend.setDeleted(false);
        this.saveOrUpdate(friend);
        return conver(friend);
    }

    private FriendVO conver(Friend f) {
        FriendVO vo = new FriendVO();
        vo.setId(f.getFriendId());
        vo.setHeadImage(f.getFriendHeadImage());
        vo.setNickName(f.getFriendNickName());
        vo.setDeleted(f.getDeleted());
        return vo;
    }

    void sendAddFriendMessage(Long userId, Long friendId, Friend friend) {
        // 推送好友状态信息
//        PrivateMessageVO msgInfo = new PrivateMessageVO();
//        msgInfo.setSendId(friendId);
//        msgInfo.setRecvId(userId);
//        msgInfo.setSendTime(new Date());
//        msgInfo.setType(MessageType.FRIEND_NEW.code());
//        FriendVO vo = conver(friend);
//        msgInfo.setContent(JSON.toJSONString(vo));
//        IMPrivateMessage<PrivateMessageVO> sendMessage = new IMPrivateMessage<>();
//        sendMessage.setSender(new IMUserInfo(friendId, IMTerminalType.UNKNOW.code()));
//        sendMessage.setRecvId(userId);
//        sendMessage.setData(msgInfo);
//        sendMessage.setSendToSelf(false);
//        sendMessage.setSendResult(false);
//        imClient.sendPrivateMessage(sendMessage);
    }

    void sendDelFriendMessage(Long userId, Long friendId) {
        // 推送好友状态信息
//        PrivateMessageVO msgInfo = new PrivateMessageVO();
//        msgInfo.setSendId(friendId);
//        msgInfo.setRecvId(userId);
//        msgInfo.setSendTime(new Date());
//        msgInfo.setType(MessageType.FRIEND_DEL.code());
//        IMPrivateMessage<PrivateMessageVO> sendMessage = new IMPrivateMessage<>();
//        sendMessage.setSender(new IMUserInfo(friendId, IMTerminalType.UNKNOW.code()));
//        sendMessage.setRecvId(userId);
//        sendMessage.setData(msgInfo);
//        sendMessage.setSendToSelf(false);
//        sendMessage.setSendResult(false);
//        imClient.sendPrivateMessage(sendMessage);
    }

    void sendAddTipMessage(Long friendId) {
//        UserSession session = SessionContext.getSession();
//        PrivateMessage msg = new PrivateMessage();
//        msg.setSendId(session.getUserId());
//        msg.setRecvId(friendId);
//        msg.setContent("你们已成为好友，现在可以开始聊天了");
//        msg.setSendTime(new Date());
//        msg.setStatus(MessageStatus.UNSEND.code());
//        msg.setType(MessageType.TIP_TEXT.code());
//        privateMessageMapper.insert(msg);
//        // 推给对方
//        PrivateMessageVO messageInfo = BeanUtils.copyProperties(msg, PrivateMessageVO.class);
//        IMPrivateMessage<PrivateMessageVO> sendMessage = new IMPrivateMessage<>();
//        sendMessage.setSender(new IMUserInfo(session.getUserId(), session.getTerminal()));
//        sendMessage.setRecvId(friendId);
//        sendMessage.setSendToSelf(false);
//        sendMessage.setData(messageInfo);
//        imClient.sendPrivateMessage(sendMessage);
//        // 推给自己
//        sendMessage.setRecvId(session.getUserId());
//        imClient.sendPrivateMessage(sendMessage);
    }

    void sendDelTipMessage(Long friendId){
//        UserSession session = SessionContext.getSession();
//        // 推送好友状态信息
//        PrivateMessage msg = new PrivateMessage();
//        msg.setSendId(session.getUserId());
//        msg.setRecvId(friendId);
//        msg.setSendTime(new Date());
//        msg.setType(MessageType.TIP_TEXT.code());
//        msg.setStatus(MessageStatus.UNSEND.code());
//        msg.setContent("你们的好友关系已被解除");
//        privateMessageMapper.insert(msg);
//        // 推送
//        PrivateMessageVO messageInfo = BeanUtils.copyProperties(msg, PrivateMessageVO.class);
//        IMPrivateMessage<PrivateMessageVO> sendMessage = new IMPrivateMessage<>();
//        sendMessage.setSender(new IMUserInfo(friendId, IMTerminalType.UNKNOW.code()));
//        sendMessage.setRecvId(friendId);
//        sendMessage.setData(messageInfo);
//        imClient.sendPrivateMessage(sendMessage);
    }

    @Override
    public List<OnlineTerminalVO> getOnlineTerminals(String userIds) {
        List<Long> userIdList = Arrays.stream(userIds.split(",")).map(Long::parseLong).collect(Collectors.toList());
        // 查询在线的终端
        Map<Long, List<IMTerminalType>> terminalMap = imClient.getOnlineTerminal(userIdList);
        // 组装vo
        List<OnlineTerminalVO> vos = new LinkedList<>();
        terminalMap.forEach((userId, types) -> {
            List<Integer> terminals = types.stream().map(IMTerminalType::code).collect(Collectors.toList());
            vos.add(new OnlineTerminalVO(userId, terminals));
        });
        return vos;
    }
}
