package com.zanxiang.game.module.manage.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zanxiang.erp.base.ErpServer;
import com.zanxiang.erp.base.rpc.ISysUserRpc;
import com.zanxiang.game.module.manage.enums.KfRoomMsgOwnerEnum;
import com.zanxiang.game.module.manage.enums.KfRoomMsgTypeEnum;
import com.zanxiang.game.module.manage.pojo.dto.KfWebSocketMsgDTO;
import com.zanxiang.game.module.manage.pojo.params.KfWebSocketMsgParam;
import com.zanxiang.game.module.manage.service.IKfRoomMsgService;
import com.zanxiang.game.module.mybatis.entity.KfRoom;
import com.zanxiang.game.module.mybatis.entity.KfRoomMsg;
import com.zanxiang.game.module.mybatis.mapper.KfRoomMsgMapper;
import com.zanxiang.module.util.JsonUtil;
import com.zanxiang.module.util.bean.BeanUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.stereotype.Service;
import reactor.util.function.Tuple2;
import reactor.util.function.Tuples;

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

/**
 * @author : lingfeng
 * @time : 2024-02-23
 * @description : 客服聊天房间消息
 */
@Slf4j
@Service
public class KfRoomMsgServiceImpl extends ServiceImpl<KfRoomMsgMapper, KfRoomMsg> implements IKfRoomMsgService {

    @DubboReference(providedBy = ErpServer.SERVER_DUBBO_NAME)
    private ISysUserRpc sysUserRpc;

    @Override
    public Tuple2<KfWebSocketMsgDTO.PageBean, List<KfWebSocketMsgDTO.RoomMsgBean>> msgRoomHistory(Long roomId, KfWebSocketMsgParam.PageBean pageBean) {
        Page<KfRoomMsg> kfRoomMsgPage = super.page(new Page<>(pageBean.getPageNum(), pageBean.getPageSize()),
                new QueryWrapper<KfRoomMsg>().lambda()
                        .eq(KfRoomMsg::getRoomId, roomId)
                        .orderByDesc(KfRoomMsg::getSortTime)
        );
        //客服名字列表
        Map<Long, String> kfUserNameMap = this.getKfUserNameMap(kfRoomMsgPage.getRecords());
        //构造消息列表
        List<KfWebSocketMsgDTO.RoomMsgBean> roomMsgBeanList = kfRoomMsgPage.getRecords().stream()
                .map(roomMsgBean -> this.transform(roomMsgBean, kfUserNameMap)).collect(Collectors.toList());
        //没有查到数据
        if (CollectionUtils.isEmpty(roomMsgBeanList)) {
            return Tuples.of(KfWebSocketMsgDTO.defaultPage(pageBean.getPageNum(), pageBean.getPageSize()), Collections.emptyList());
        }
        //更新消息已读状态
        List<String> msgIdList = roomMsgBeanList.stream()
                .filter(msg -> Objects.equals(msg.getReadStatus(), Boolean.FALSE))
                .map(KfWebSocketMsgDTO.RoomMsgBean::getMsgId)
                .collect(Collectors.toList());
        if (CollectionUtils.isNotEmpty(msgIdList)) {
            super.update(new LambdaUpdateWrapper<KfRoomMsg>()
                    .set(KfRoomMsg::getReadStatus, Boolean.TRUE)
                    .set(KfRoomMsg::getUpdateTime, LocalDateTime.now())
                    .in(KfRoomMsg::getMsgId, msgIdList));
        }
        //返回分页数据, 消息列表
        return Tuples.of(KfWebSocketMsgDTO.transformPage(kfRoomMsgPage), roomMsgBeanList);
    }

    private KfWebSocketMsgDTO.RoomMsgBean transform(KfRoomMsg kfRoomMsg, Map<Long, String> kfUserNameMap) {
        if (kfRoomMsg == null) {
            return null;
        }
        KfWebSocketMsgDTO.RoomMsgBean roomMsgBean = BeanUtil.copy(kfRoomMsg, KfWebSocketMsgDTO.RoomMsgBean.class);
        roomMsgBean.setMsgType(KfRoomMsgTypeEnum.getMsgTypeEnum(kfRoomMsg.getMsgType()));
        roomMsgBean.setContent(JsonUtil.toObj(kfRoomMsg.getContent(), KfWebSocketMsgDTO.MsgContentBean.class));
        //判断是否是系统消息
        if (Objects.equals(roomMsgBean.getMsgOwner(), KfRoomMsgOwnerEnum.KF_MSG_OWNER_SYSTEM.getValue())) {
            roomMsgBean.setKfUserName("系统消息");
        }
        //客服消息, 设置客服名字
        if (Objects.equals(roomMsgBean.getMsgOwner(), KfRoomMsgOwnerEnum.KF_MSG_OWNER_KF.getValue())) {
            String kfUserName = kfUserNameMap.get(roomMsgBean.getKfUserId());
            roomMsgBean.setKfUserName(kfUserName == null ? "查询erp客服名字异常" : kfUserName);
        }
        return roomMsgBean;
    }

    @Override
    public boolean sendMsgSave(Long gameId, KfRoom kfRoom, KfWebSocketMsgParam.MsgContentBean msgContent) {
        return super.save(KfRoomMsg.builder()
                .msgId(UUID.randomUUID().toString().replace("-", ""))
                .msgType(msgContent.getMsgType().getValue())
                .gameId(gameId)
                .openId(kfRoom.getOpenId())
                .userId(kfRoom.getUserId())
                .kfUserId(kfRoom.getKfUserId())
                .readStatus(Boolean.TRUE)
                .roomId(kfRoom.getId())
                .msgOwner(KfRoomMsgOwnerEnum.KF_MSG_OWNER_KF.getValue())
                .content(JsonUtil.toString(BeanUtil.copy(msgContent, KfWebSocketMsgDTO.MsgContentBean.class)))
                .source(JsonUtil.toString(msgContent))
                .sortTime(System.currentTimeMillis())
                .createTime(LocalDateTime.now())
                .updateTime(LocalDateTime.now())
                .build());
    }

    private Map<Long, String> getKfUserNameMap(List<KfRoomMsg> roomMsgList) {
        List<Long> kfUserIdList = roomMsgList.stream()
                .filter(msg -> Objects.equals(msg.getMsgOwner(), KfRoomMsgOwnerEnum.KF_MSG_OWNER_KF.getValue()))
                .map(KfRoomMsg::getKfUserId)
                .distinct().collect(Collectors.toList());
        Map<Long, String> kfUserNameMap;
        try {
            kfUserNameMap = sysUserRpc.getUserNameByIds(kfUserIdList).getData();
        } catch (Exception e) {
            log.error("获取erp客服名字异常, kfUserIdList : {}, e : {}", JsonUtil.toString(kfUserIdList), e.getMessage());
            kfUserNameMap = Collections.emptyMap();
        }
        return kfUserNameMap;
    }
}
