package com.tykj.dev.device.user.read.service.impl;

import com.tykj.dev.blockcha.subject.entity.BcHash;
import com.tykj.dev.blockcha.subject.service.BlockChainUtil;
import com.tykj.dev.config.TaskBeanConfig;
import com.tykj.dev.device.user.read.repository.MessageDao;
import com.tykj.dev.device.user.read.service.MessageService;
import com.tykj.dev.device.user.read.subject.bto.MessageBto;
import com.tykj.dev.device.user.read.subject.domin.Message;
import com.tykj.dev.device.user.read.subject.vo.MessageUserVo;
import com.tykj.dev.device.user.util.UserUtils;
import com.tykj.dev.misc.exception.ApiException;
import com.tykj.dev.misc.utils.JacksonUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;

import java.util.Comparator;
import java.util.Date;
import java.util.List;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;
import java.util.stream.Collectors;

/**
 * @author dengdiyi
 */
@Service
public class MessageServiceImpl implements MessageService {

    @Autowired
    private MessageDao messageDao;

    @Autowired
    private UserUtils userUtils;

    @Autowired
    BlockChainUtil blockChainUtil;

    @Override
    public void add(MessageBto messageBto) {
        Message message = messageDao.save(messageBto.toDo());
        CompletableFuture.runAsync(()->{
            Message message1 = get(message.getId());
            BcHash bcText = blockChainUtil.sendHash(1000, JacksonUtil.toJSon(message1));
            String recordId = bcText.getData().getRecordID();
            message1.setRecordId(recordId);
            messageDao.save(message1);
        }, TaskBeanConfig.getThreadPoolTaskScheduler());
    }

    @Override
    @Async
    public void sendHash(Message message) {
        BcHash bcText = blockChainUtil.sendHash(1000, JacksonUtil.toJSon(message));
        String recordId = bcText.getData().getRecordID();
        message.setRecordId(recordId);
        messageDao.save(message);
    }

    @Override
    public Message update(Message message) {
        return messageDao.save(message);
    }

    @Override
    public Message get(Integer id) {
        Optional<Message> message = messageDao.findById(id);
        if (message.isPresent()){
            return message.get();
        }
        else {
            throw  new ApiException("Id不存在");
        }
    }

    @Override
    public void delete(Integer id) {
        messageDao.deleteById(id);
    }

    @Override
    public List<MessageUserVo> getList() {
        Integer userId = userUtils.getCurrentUserId();
        return messageDao.findAll().stream()
                .map(Message::parse2Bto)
                .filter(messageBto -> messageBto.getInvolveUserIdList().contains(userId)&&!messageBto.getCompleteUserIdList().contains(userId))
                .map(MessageBto::toVo)
                .sorted(Comparator.comparing(MessageUserVo::getCreateTime,Comparator.nullsLast(Date::compareTo)).reversed())
                .collect(Collectors.toList());
    }

    @Override
    public List<MessageBto> getBtoList() {
        Integer userId = userUtils.getCurrentUserId();
        return messageDao.findAll().stream()
                .map(Message::parse2Bto)
                .filter(messageBto -> messageBto.getInvolveUserIdList().contains(userId)&&!messageBto.getCompleteUserIdList().contains(userId))
                .collect(Collectors.toList());
    }

    /**
     * @param messageId 阅知信息id
     */
    @Override
    public Message read(Integer messageId) {
        Integer userId = userUtils.getCurrentUserId();
        MessageBto messageBto = get(messageId).parse2Bto();
        List<Integer> userIds = messageBto.getUserReadDetailList();
        userIds.add(userId);
        messageBto.setUserReadDetailList(userIds);
        List<Integer> userIds2 = messageBto.getCompleteUserIdList();
        userIds2.add(userId);
        messageBto.setCompleteUserIdList(userIds2);
        return messageDao.save(messageBto.toDo());
    }

    /**
     * @param messageId 阅知信息id
     *                  完成该阅知信息
     */
    @Override
    public Message complete(Integer messageId) {
        Integer userId = userUtils.getCurrentUserId();
        MessageBto messageBto = get(messageId).parse2Bto();
        List<Integer> userIds = messageBto.getCompleteUserIdList();
        userIds.add(userId);
        messageBto.setCompleteUserIdList(userIds);
        return messageDao.save(messageBto.toDo());
    }
}
