package com.wecloud.im.service.impl;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.metadata.OrderItem;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.json.JsonMapper;
import com.wecloud.im.entity.ImClient;
import com.wecloud.im.entity.ImConversation;
import com.wecloud.im.entity.ImMessage;
import com.wecloud.im.mapper.ImMessageMapper;
import com.wecloud.im.param.ImHistoryMessagePageParam;
import com.wecloud.im.param.ImMessagePageParam;
import com.wecloud.im.param.ImMessageQueryVo;
import com.wecloud.im.param.add.ImMsgUpdate;
import com.wecloud.im.service.ImClientService;
import com.wecloud.im.service.ImConversationService;
import com.wecloud.im.service.ImMessageService;
import com.wecloud.im.vo.ImMessageOfflineListVo;
import com.wecloud.im.vo.OfflineMsgDto;
import io.geekidea.springbootplus.framework.common.api.ApiResult;
import io.geekidea.springbootplus.framework.common.service.impl.BaseServiceImpl;
import io.geekidea.springbootplus.framework.core.pagination.PageInfo;
import io.geekidea.springbootplus.framework.core.pagination.Paging;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * 消息存储表 服务实现类
 *
 * @author wei
 * @since 2021-04-29
 */
@Slf4j
@Service
public class ImMessageServiceImpl extends BaseServiceImpl<ImMessageMapper, ImMessage> implements ImMessageService {

    @Autowired
    private ImMessageMapper imMessageMapper;

    @Autowired
    private ImClientService imClientService;

    @Autowired
    private ImConversationService imConversationService;

    @Override
    public ApiResult<Boolean> updateMsgWithdrawById(Long msgId) {
        ImClient client = imClientService.getClient();

        // 判断该消息是否是该客户端发送
        ImMessage messageById = this.getById(msgId);
        if (!messageById.getSender().equals(client.getId())) {
            log.error("判断该消息是否是该客户端发送");
            return ApiResult.fail();
        }
        if (messageById.getWithdraw()) {
            return ApiResult.ok();
        }

        messageById.setWithdraw(Boolean.TRUE);
        messageById.setWithdrawTime(new Date());
        messageById.setContent("{}");

        boolean b = this.updateById(messageById);

        if (b) {
            return ApiResult.ok();

        } else {
            return ApiResult.fail();
        }
    }

    @Override
    public ApiResult<Boolean> updateMsgById(ImMsgUpdate imMsgUpdate) {

        ImClient client = imClientService.getClient();

/*        // 判断该消息是否是该客户端发送
        ImMessage messageById = this.getById(imMsgUpdate.getId());
        if (!messageById.getSender().equals(client.getId())) {
            log.error("判断该消息是否是该客户端发送");
            return ApiResult.fail();
        }*/

        ImMessage imMessage = new ImMessage();
        imMessage.setId(imMsgUpdate.getMsgId());

        JsonMapper jsonMapper = new JsonMapper();

        try {
            String content = jsonMapper.writeValueAsString(imMsgUpdate.getContent());
            imMessage.setContent(content);
        } catch (JsonProcessingException e) {
            e.printStackTrace();
            return ApiResult.fail();
        }

        boolean isOK = this.updateById(imMessage);
        if (isOK) {
            return ApiResult.ok();
        } else {
            return ApiResult.fail();
        }
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public boolean saveImMessage(ImMessage imMessage) throws Exception {
        return super.save(imMessage);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public boolean updateImMessage(ImMessage imMessage) throws Exception {
        return super.updateById(imMessage);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public boolean deleteImMessage(Long id) throws Exception {
        return super.removeById(id);
    }

    @Override
    public ImMessageQueryVo getImMessageById(Long id) throws Exception {
        return imMessageMapper.getImMessageById(id);
    }

    @Override
    public Paging<ImMessageQueryVo> getImMessagePageList(ImMessagePageParam imMessagePageParam) throws Exception {
        Page<ImMessageQueryVo> page = new PageInfo<>(imMessagePageParam, OrderItem.desc(getLambdaColumn(ImMessage::getCreateTime)));
        IPage<ImMessageQueryVo> iPage = imMessageMapper.getImMessagePageList(page, imMessagePageParam);
        return new Paging<ImMessageQueryVo>(iPage);
    }

    @Override
    public Paging<OfflineMsgDto> getHistoryMsgConversationId(ImHistoryMessagePageParam imHistoryMessagePageParam) throws Exception {
        Page<ImMessage> page = new PageInfo<>(imHistoryMessagePageParam, OrderItem.desc(getLambdaColumn(ImMessage::getCreateTime)));

        IPage<OfflineMsgDto> iPage = imMessageMapper.getHistoryMsgConversationId(page, imHistoryMessagePageParam);

        return new Paging<>(iPage);
    }


    /**
     * 查询用户所有离线消息
     *
     * @return
     * @throws Exception
     */
    @Override
    public List<ImMessageOfflineListVo> getOfflineList() throws Exception {

        // 返回数据
        List<ImMessageOfflineListVo> imMessageOfflineListVoList = new ArrayList<>();

        ImClient client = imClientService.getClient();

        // 获取加入的所有会话
        List<ImConversation> myImConversationList = imConversationService.getMyImConversationList();


        // 遍历会话列表, 查询每个会话列表的离线消息
        for (ImConversation imConversation : myImConversationList) {

            //根据客户端id与会话id 查询离线消息
            List<OfflineMsgDto> offlineListByClientAndConversation = getOfflineListByClientAndConversation(client.getId(), imConversation.getId());

            ImMessageOfflineListVo imMessageOfflineListVo = new ImMessageOfflineListVo();
            imMessageOfflineListVo.setMsgList(offlineListByClientAndConversation);
            imMessageOfflineListVo.setConversationId(imConversation.getId());
            imMessageOfflineListVoList.add(imMessageOfflineListVo);
        }

        return imMessageOfflineListVoList;
    }

    /**
     * 根据客户端id与会话id 查询离线消息
     *
     * @param clientId
     * @param conversationId
     * @return
     */
    @Override
    public List<OfflineMsgDto> getOfflineListByClientAndConversation(Long clientId, Long conversationId) {
        return imMessageMapper.getOfflineListByClientAndConversation(clientId, conversationId);
    }


    @Override
    public OfflineMsgDto getReceivedLastMsgByConversationId(Long clientId, Long conversationId) {
        return imMessageMapper.getReceivedLastMsgByConversationId(clientId, conversationId);
    }

    @Override
    public OfflineMsgDto getLastMsgByConversationId(Long conversationId) {
        return imMessageMapper.getLastMsgByConversationId(conversationId);
    }


}
