package com.tykj.dev.rfid.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.service.DeviceLibraryService;
import com.tykj.dev.device.library.subject.domin.DeviceLibrary;
import com.tykj.dev.misc.utils.JacksonUtil;
import com.tykj.dev.rfid.entity.domin.InputOutputDevice;
import com.tykj.dev.rfid.repository.InputOutputDeviceDao;
import com.tykj.dev.rfid.service.InputOutputDeviceService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.List;
import java.util.concurrent.CompletableFuture;

/**
 * @author HuangXiahao
 * @version V1.0
 * @class InputOutputDeviceServiceImpl
 * @packageName com.tykj.dev.rfid.service.impl
 **/
@Service
public class InputOutputDeviceServiceImpl implements InputOutputDeviceService {

    @Autowired
    InputOutputDeviceDao inputOutputDeviceDao;

    @Resource
    DeviceLibraryService deviceLibraryService;

    @Autowired
    private BlockChainUtil blockChainUtil;

    @Override
    public void addEntity(InputOutputDevice inputOutputDevice) {
        InputOutputDevice inputOutputDevice1 = inputOutputDeviceDao.save(inputOutputDevice);
        CompletableFuture.runAsync(()->{
            InputOutputDevice inputOutputDevice2 = inputOutputDeviceDao.findById(inputOutputDevice1.getId()).get();
            BcHash bcText = blockChainUtil.sendHash(1000, JacksonUtil.toJSon(inputOutputDevice2));
            String recordId = bcText.getData().getRecordID();
            inputOutputDevice2.setRecordId(recordId);
            inputOutputDeviceDao.save(inputOutputDevice2);
        }, TaskBeanConfig.getThreadPoolTaskScheduler());
    }

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

    /**
     * @param inputOutputDevices 异步上链
     */
    @Override
    @Async
    public void sendHash(List<InputOutputDevice> inputOutputDevices) {
        inputOutputDevices.forEach(inputOutputDevice1 -> {
            BcHash bcText = blockChainUtil.sendHash(1000, JacksonUtil.toJSon(inputOutputDevice1));
            String recordId = bcText.getData().getRecordID();
            inputOutputDevice1.setRecordId(recordId);
            inputOutputDeviceDao.save(inputOutputDevice1);
        });
    }

    @Override
    public List<InputOutputDevice> getByUnitIdAndDirection(Integer unitId,Integer direction) {
        return inputOutputDeviceDao.findAllByUnitIdAndDirection(unitId,direction);
    }

    @Override
    public void deleteAll(List<InputOutputDevice> inputOutputDevices) {
        inputOutputDevices.forEach(inputOutputDevice -> {
            inputOutputDeviceDao.deleteById(inputOutputDevice.getId());
            blockChainUtil.appendText(JacksonUtil.toJSon(inputOutputDevice),inputOutputDevice.getRecordId());
        });
    }

    /**
     * @param deviceIds 允许出入库的装备id列表
     * @param unitId    出入库的单位
     * @param direction 允许出入库的方向   0为入  1为出
     */
    @Override
    public void addWhiteDevices(List<Integer> deviceIds, Integer unitId, Integer direction) {
        deviceIds.forEach(integer -> {
            DeviceLibrary deviceLibrary = deviceLibraryService.getOne(integer);
            InputOutputDevice inputOutputDevice = new InputOutputDevice();
            inputOutputDevice.setDeviceId(integer);
            inputOutputDevice.setRfidCardId(deviceLibrary.getRfidCardId());
            inputOutputDevice.setDirection(direction);
            inputOutputDevice.setUnitId(unitId);
            addEntity(inputOutputDevice);
        });
    }

    /**
     * 设置白名单已经被读取到
     */
    @Override
    public void setRead(List<InputOutputDevice> inputOutputDevices) {
        inputOutputDevices.forEach(inputOutputDevice -> {
            if (inputOutputDevice.getIsRead()==0) {
                inputOutputDevice.setIsRead(1);
                inputOutputDeviceDao.save(inputOutputDevice);
            }
        });
    }


}
