package com.tykj.dev.rfid.service.impl;

import com.github.wenhao.jpa.PredicateBuilder;
import com.github.wenhao.jpa.Specifications;
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.misc.utils.JacksonUtil;
import com.tykj.dev.rfid.entity.domin.RfidChangeLog;
import com.tykj.dev.rfid.entity.vo.RfidChangeLogSelectVo;
import com.tykj.dev.rfid.repository.RfidChangeLogDao;
import com.tykj.dev.rfid.service.RfidChangeLogService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.concurrent.CompletableFuture;

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

    @Autowired
    RfidChangeLogDao rfidChangeLogDao;

    @Autowired
    private BlockChainUtil blockChainUtil;

    @Override
    public RfidChangeLog getOne(Integer id) {
        return rfidChangeLogDao.getOne(id);
    }

    @Override
    public List<RfidChangeLog> getList(RfidChangeLogSelectVo rfidChangeLogSelectVo) {
        return rfidChangeLogDao.findAll(getSelectSpecification(rfidChangeLogSelectVo));

    }

    @Override
    public RfidChangeLog addEntity(RfidChangeLog rfidChangeLog) {
        RfidChangeLog rfidChangeLog1 = rfidChangeLogDao.save(rfidChangeLog);
        CompletableFuture.runAsync(()->{
            RfidChangeLog rfidChangeLog2 = getOne(rfidChangeLog1.getId());
            BcHash bcText = blockChainUtil.sendHash(1000, JacksonUtil.toJSon(rfidChangeLog2));
            String recordId = bcText.getData().getRecordID();
            rfidChangeLog2.setRecordId(recordId);
            rfidChangeLogDao.save(rfidChangeLog2);
        }, TaskBeanConfig.getThreadPoolTaskScheduler());
        return rfidChangeLog1;
    }

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

    @Override
    public RfidChangeLog updateEntity(RfidChangeLog rfidChangeLog) {
        RfidChangeLog rfidChangeLog1 = rfidChangeLogDao.save(rfidChangeLog);
        CompletableFuture.runAsync(()->blockChainUtil.appendHash(JacksonUtil.toJSon(rfidChangeLog1),rfidChangeLog1.getRecordId()), TaskBeanConfig.getThreadPoolTaskScheduler());
        return rfidChangeLog1;
    }


    private Specification<RfidChangeLog> getSelectSpecification(RfidChangeLogSelectVo rfidChangeLogSelectVo) {
        PredicateBuilder<RfidChangeLog> predicateBuilder = Specifications.and();
        if (rfidChangeLogSelectVo != null) {
            if (rfidChangeLogSelectVo.getValidTag() != null) {
                predicateBuilder.eq("validTag", rfidChangeLogSelectVo.getValidTag());
            }
            if (rfidChangeLogSelectVo.getBillId() != null) {
                predicateBuilder.eq("rfidChangeBillId", rfidChangeLogSelectVo.getBillId());
            }
            if (rfidChangeLogSelectVo.getDeviceId() != null) {
                predicateBuilder.eq("deviceId", rfidChangeLogSelectVo.getDeviceId());
            }
        }
        return predicateBuilder.build();
    }

}
