package com.tykj.dev.device.library.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.library.repository.DeviceLogDao;
import com.tykj.dev.device.library.service.DeviceLogService;
import com.tykj.dev.device.library.subject.Dto.DeviceLogDto;
import com.tykj.dev.device.library.subject.domin.DeviceLog;
import com.tykj.dev.misc.exception.ApiException;
import com.tykj.dev.misc.utils.JacksonUtil;
import com.tykj.dev.misc.utils.ResultUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;

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


/**
 * @author dengdiyi
 */
@Service
public class DeviceLogServiceImpl implements DeviceLogService {

    @Autowired
    private DeviceLogDao deviceLogDao;

    @Autowired
    private BlockChainUtil blockChainUtil;

    @Override
    public void addLog(DeviceLogDto deviceLogDto) {
        DeviceLog deviceLog = deviceLogDao.save(deviceLogDto.toDo());
        CompletableFuture.runAsync(()->{
            DeviceLog deviceLog1 = deviceLogDao.findById(deviceLog.getId()).get();
            BcHash bcText = blockChainUtil.sendHash(1000, JacksonUtil.toJSon(deviceLog1));
            String recordId = bcText.getData().getRecordID();
            deviceLog1.setRecordId(recordId);
            deviceLogDao.save(deviceLog1);
        }, TaskBeanConfig.getThreadPoolTaskScheduler());
    }

    @Override
    public void addAllLog(List<DeviceLogDto> deviceLogDtos) {
        List<DeviceLog> deviceLogs = deviceLogDao.saveAll(deviceLogDtos.stream().map(DeviceLogDto::toDo).collect(Collectors.toList()));
        CompletableFuture.runAsync(()->{
            deviceLogs.forEach(deviceLog -> {
                DeviceLog deviceLog1 = deviceLogDao.findById(deviceLog.getId()).get();
                BcHash bcText = blockChainUtil.sendHash(1000, JacksonUtil.toJSon(deviceLog1));
                String recordId = bcText.getData().getRecordID();
                deviceLog1.setRecordId(recordId);
                deviceLogDao.save(deviceLog1);
            });
        }, TaskBeanConfig.getThreadPoolTaskScheduler());
    }

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

    /**
     * @param deviceLogDtos 异步上链
     */
    @Override
    @Async
    public void sendHash(List<DeviceLogDto> deviceLogDtos) {
        deviceLogDtos.forEach(deviceLogDto -> {
            DeviceLog deviceLogEntity = deviceLogDto.toDo();
            BcHash bcText = blockChainUtil.sendHash(1000, JacksonUtil.toJSon(deviceLogEntity));
            String recordId = bcText.getData().getRecordID();
            deviceLogEntity.setRecordId(recordId);
            deviceLogDao.save(deviceLogEntity);
        });
    }

    @Override
    public DeviceLogDto getOne(Integer id) {
        Optional<DeviceLog> deviceLogEntity = deviceLogDao.findById(id);
        if (deviceLogEntity.isPresent()) {
            return deviceLogEntity.get().parse2Dto();
        } else {
            throw new ApiException(ResultUtil.failed("查询的id不存在"));
        }
    }

    @Override
    public void saveAllLog(List<DeviceLog> deviceLoList) {
        deviceLoList.forEach(deviceLog -> addLog(deviceLog.parse2Dto()));
    }

}
