package com.ruoyi.app.service.impl;

import com.ruoyi.app.DTO.HookBindDetailDTO;
import com.ruoyi.app.DTO.NFIDReadGroupDTO;
import com.ruoyi.app.DTO.PorkSideProduceDTO;
import com.ruoyi.app.domain.NFIDReadRecord;
import com.ruoyi.app.domain.NFIDReaderEvent;
import com.ruoyi.app.domain.PorkSideProduce;
import com.ruoyi.app.domain.request.ReqValidNFIDRecord;
import com.ruoyi.app.mapper.HookMapper;
import com.ruoyi.app.mapper.NFIDReadRecordMapper;
import com.ruoyi.app.service.IHookBindService;
import com.ruoyi.app.service.IHookRegisterService;
import com.ruoyi.app.service.INFIDReadRecordService;
import com.ruoyi.common.utils.DateUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.stereotype.Service;

import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Objects;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

/**
 * 识别记录Service业务层处理
 */
@Service
public class NFIDReadRecordServiceImpl implements INFIDReadRecordService {
    @Autowired
    private NFIDReadRecordMapper NFIDReadRecordMapper;
    @Autowired
    private IHookBindService hookBindService;

    @Autowired
    private IHookRegisterService hookRegisterService;

    private final ApplicationEventPublisher eventPublisher;

    public NFIDReadRecordServiceImpl(ApplicationEventPublisher eventPublisher) {
        this.eventPublisher = eventPublisher;

        //测试使用
      //  ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(2);

//        scheduler.scheduleAtFixedRate(
//                this::testBatchAdd,
//                1, 10, TimeUnit.SECONDS
//        );

//        scheduler.scheduleAtFixedRate(
//                this::testNotice,
//                1, 7, TimeUnit.SECONDS
//        );
    }

    //测试批量新增
    private void testBatchAdd(){
        List<NFIDReadRecord> records = new ArrayList<>();
        NFIDReadRecord record = new NFIDReadRecord();
        record.setCreateTime(DateUtils.getNowDate());
        record.setHookNo("0002");
        records.add(record);
        insertNFIDReadRecordBatch(records);
    }

    //测试称重识别提醒
    private void testNotice(){
        PorkSideProduceDTO porkSideProduce = new PorkSideProduceDTO();
        porkSideProduce.setEpcNo("E28068940000502A8A1624D0");
        porkSideProduce.setHookNo(hookRegisterService.selectHookNoByEpcNo("E28068940000502A8A1624D0"));
        porkSideProduce.setDeviceSerial("N60040000241219B04F4");
        porkSideProduce.setProduceTime(new Date());
        porkSideProduce.setCreateTime(new Date());
        porkSideProduce.setProductName(PorkSideProduce.DEFAULT_NAME);

        if(!Objects.equals(porkSideProduce.getHookNo(), "")){
            //获取吊钩绑定关联信息
            HookBindDetailDTO hookBindDetail = hookBindService.selectHookBindDetail(porkSideProduce.getHookNo());
            porkSideProduce.setEntranceBatchId(hookBindDetail.getEntranceBatchId());
            porkSideProduce.setDistributeBatchId(hookBindDetail.getDistributeBatchId());
            porkSideProduce.setSlaughterCode(hookBindDetail.getSlaughterCode());
            porkSideProduce.setPurchaserName(hookBindDetail.getPurchaserName());
            porkSideProduce.setAnimalCertNo(hookBindDetail.getAnimalCertNo());
            porkSideProduce.setSupplierName(hookBindDetail.getSupplierName());
        }
        noticeNFIDReadRecord(porkSideProduce);
    }
    /**
     * 查询nfid识别记录信息
     *
     * @return nfid识别记录
     */
    @Override
    public List<NFIDReadRecord> selectNFIDReadRecordList(){
        return NFIDReadRecordMapper.selectNFIDReadRecordList();
    }

    /**
     * 查询可用的nfid识别记录信息
     *
     * @return nfid识别记录
     */
    @Override
    public List<NFIDReadRecord> selectValidNFIDReadRecord(ReqValidNFIDRecord req){
        return NFIDReadRecordMapper.selectValidNFIDReadRecord(req);
    }

    /**
     * 通过ID查询识记录
     *
     * @param id 记录ID
     * @return nfid识别记录信息
     */
    @Override
    public NFIDReadRecord selectNFIDReadRecordById(Long id){
        return NFIDReadRecordMapper.selectNFIDReadRecordById(id);
    }

    /**
     * 新增nfid识别记录
     *
     * @param record nfid识别记录
     * @return 结果
     */
    @Override
    public int insertNFIDReadRecord(NFIDReadRecord record){
        record.setCreateTime(DateUtils.getNowDate());
        return NFIDReadRecordMapper.insertNFIDReadRecord(record);
    }

    /**
     * 批量新增
     *
     * @param list nfid识别记录
     * @return 结果
     */
    @Override
    public int insertNFIDReadRecordBatch(List<NFIDReadRecord> list){
        int row =  NFIDReadRecordMapper.insertNFIDReadRecordBatch(list);
        if(row >0){
            // 发布事件
            for(NFIDReadRecord record : list){
                eventPublisher.publishEvent(new NFIDReaderEvent<>(this,NFIDReaderEvent.HookBind,record));
            }
        }
        return row;
    }
    /**
     * 通过设备序列号查询识别器信息
     *
     * @param ids 需要修改的数据主键集合
     * @return nfid识别记录信息
     */
    @Override
    public int setBindByHook(String[] ids){
        return NFIDReadRecordMapper.setBindByHook(ids);
    }

    /**
     * 将识别记录按照数量分组
     *
     * @return nfid识别记录
     */
    @Override
    public List<NFIDReadGroupDTO> selectNFIDReadByGroup(){
        return NFIDReadRecordMapper.selectNFIDReadByGroup();
    }

    /**
     * 将识别记录按照数量分组
     *
     * @return nfid识别记录
     */
    @Override
    public NFIDReadGroupDTO selectHookRange(){
        return NFIDReadRecordMapper.selectHookRange();
    }

    /**
     * 获取分组详情
     *
     * @return nfid识别记录
     */
    @Override
    public List<NFIDReadRecord> selectNFIDReadRecordListByGroup(ReqValidNFIDRecord req){
        return NFIDReadRecordMapper.selectNFIDReadRecordListByGroup(req);
    }

    /**
     * 提醒识别成功
     *
     * @param porkSideProduceDTO nfid识别的称重信息
     * @return 结果
     */
    @Override
    public void noticeNFIDReadRecord(PorkSideProduceDTO porkSideProduceDTO){
        eventPublisher.publishEvent(new NFIDReaderEvent<>(this, porkSideProduceDTO.getDeviceSerial(),porkSideProduceDTO));
    }
}
