package com.yeejoin.equipmanage.service.impl;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.atomic.AtomicReference;
import java.util.stream.Collectors;

import javax.annotation.Resource;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.typroject.tyboot.core.restful.exception.instance.BadRequest;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yeejoin.amos.boot.biz.common.bo.ReginParams;
import com.yeejoin.amos.feign.privilege.model.AgencyUserModel;
import com.yeejoin.equipmanage.common.entity.Equipment;
import com.yeejoin.equipmanage.common.entity.EquipmentDetail;
import com.yeejoin.equipmanage.common.entity.EquipmentIndex;
import com.yeejoin.equipmanage.common.entity.EquipmentManageEntity;
import com.yeejoin.equipmanage.common.entity.EquipmentSpecific;
import com.yeejoin.equipmanage.common.entity.EquipmentSpecificIndex;
import com.yeejoin.equipmanage.common.entity.EquipmentSystemSourceStatistics;
import com.yeejoin.equipmanage.common.entity.FireFightingSystemEntity;
import com.yeejoin.equipmanage.common.entity.Journal;
import com.yeejoin.equipmanage.common.entity.ManufacturerInfo;
import com.yeejoin.equipmanage.common.entity.Stock;
import com.yeejoin.equipmanage.common.entity.StockBill;
import com.yeejoin.equipmanage.common.entity.StockBillDetail;
import com.yeejoin.equipmanage.common.entity.StockDetail;
import com.yeejoin.equipmanage.common.entity.WarehouseStructure;
import com.yeejoin.equipmanage.common.entity.vo.EquipmentDetailDownloadVO;
import com.yeejoin.equipmanage.common.enums.BillContentEnum;
import com.yeejoin.equipmanage.common.enums.EquipStatusEnum;
import com.yeejoin.equipmanage.common.enums.JournalTypeEnum;
import com.yeejoin.equipmanage.common.enums.NoticeEnum;
import com.yeejoin.equipmanage.common.enums.StockBillTypeEnum;
import com.yeejoin.equipmanage.common.utils.ExcelUtils;
import com.yeejoin.equipmanage.common.utils.QRCodeUtil;
import com.yeejoin.equipmanage.common.utils.StringUtil;
import com.yeejoin.equipmanage.common.vo.StockDataVO;
import com.yeejoin.equipmanage.config.EquipmentIotMqttReceiveConfig;
import com.yeejoin.equipmanage.dto.EquipmentDetailDownloadTemplateDto;
import com.yeejoin.equipmanage.mapper.EquipmentDetailMapper;
import com.yeejoin.equipmanage.mapper.EquipmentMapper;
import com.yeejoin.equipmanage.mapper.EquipmentSpecificMapper;
import com.yeejoin.equipmanage.mapper.StockMapper;
import com.yeejoin.equipmanage.service.EquipmentManageService;
import com.yeejoin.equipmanage.service.IEquipmentIndexService;
import com.yeejoin.equipmanage.service.IEquipmentSpecificIndexSerivce;
import com.yeejoin.equipmanage.service.IEquipmentSystemSourceStatisticsService;
import com.yeejoin.equipmanage.service.IFireFightingSystemService;
import com.yeejoin.equipmanage.service.IJournalService;
import com.yeejoin.equipmanage.service.IManufacturerInfoService;
import com.yeejoin.equipmanage.service.INoticeService;
import com.yeejoin.equipmanage.service.IStockBillDetailService;
import com.yeejoin.equipmanage.service.IStockBillService;
import com.yeejoin.equipmanage.service.IStockDetailService;
import com.yeejoin.equipmanage.service.IStockService;
import com.yeejoin.equipmanage.service.IWarehouseStructureService;
import com.yeejoin.equipmanage.service.ProductionQRCode;
import com.yeejoin.equipmanage.utils.RelationRedisUtil;

/**
 * 库存台账 服务实现类
 *
 * @author wujiang
 * @date 2020-07-07
 */
@Service
public class StockServiceImpl extends ServiceImpl<StockMapper, Stock> implements IStockService {

    @Autowired
    private IStockDetailService stockDetailService;
    @Autowired
    private IStockBillService stockBillService;
    @Autowired
    private IStockBillDetailService stockBillDetailService;
    @Autowired
    private IJournalService journalService;
    @Autowired
    private INoticeService noticeService;
    @Autowired
    private EquipmentManageService equipmentManageService;
    @Autowired
    private EquipmentSpecificMapper equipmentSpecificMapper;
    @Autowired
    private IEquipmentSystemSourceStatisticsService equipmentSystemSourceStatisticsService;
    @Autowired
    private IWarehouseStructureService warehouseStructureService;
    @Autowired
    private EquipmentDetailMapper equipmentDetailMapper;
    @Autowired
    private EquipmentMapper equipmentMapper;
    @Resource(name = "equipmentProductionQRCode")
    private ProductionQRCode equipmentProductionQRCode;
    @Autowired
    private IEquipmentSpecificIndexSerivce iEquipmentSpecificIndexSerivce;
    @Autowired
    EquipmentIotMqttReceiveConfig equipmentIotMqttReceiveConfig;
    @Autowired
    IManufacturerInfoService manufacturerInfoService;

    @Autowired
    private IEquipmentIndexService iEquipmentIndexService;

    @Autowired
    @Lazy
    private IFireFightingSystemService fireFightingSystemService;

    @Autowired
    private RelationRedisUtil relationRedisUtil;

    @Override
    @Transactional(rollbackFor = {Exception.class})
    public StockBill in(List<StockDetail> list, String type, AgencyUserModel agencyUserModel) {
        List<EquipmentSpecific> equipmentSpecifics = new ArrayList<>();
        list.forEach(x -> {
            QueryWrapper<EquipmentSpecific> equipmentSpecificQueryWrapper = new QueryWrapper<>();
            equipmentSpecificQueryWrapper.lambda().eq(EquipmentSpecific::getQrCode, x.getQrCode());
            EquipmentSpecific equipmentSpecific = equipmentSpecificMapper.selectOne(equipmentSpecificQueryWrapper);
            x.setEquipmentSpecificId(equipmentSpecific.getId());
            equipmentSpecifics.add(equipmentSpecific);
        });
        // 除灭火药剂外，创建物联矩阵记录
        if (!type.equals("3")) {
            initEquipmentSystemSourceStatistics(equipmentSpecifics);
        }

        // wl_stock表
        List<Stock> newStockList = new ArrayList<>();
        //待更新的库存主表
        List<Stock> updateStockList = new ArrayList<>();
        for (StockDetail stockDetail : list) {
            EquipmentDetail equipmentDetail = new EquipmentDetail();
            if (StringUtil.isNotEmpty(stockDetail.getDescription())) {
                equipmentDetail.setArea(stockDetail.getDescription());
                equipmentDetailMapper.update(equipmentDetail, new UpdateWrapper<EquipmentDetail>().eq("id", stockDetail.getEquipmentDetailId()));
            }
            Map<String, Object> columnMap = new HashMap<>();
            columnMap.put("equipment_detail_id", stockDetail.getEquipmentDetailId());
            columnMap.put("warehouse_id", stockDetail.getWarehouseId());
            List<Stock> oldStockList = (List<Stock>) listByMap(columnMap);
            // 如果该仓库有该装备信息，则库存有只需要修改数量
            if (oldStockList.size() > 0) {
                Double amount = oldStockList.get(0).getAmount();
                Stock exsitsStock = getStockByEquipDetailId(updateStockList, stockDetail.getEquipmentDetailId());
                if (exsitsStock != null) {
                    exsitsStock.setAmount(exsitsStock.getAmount() + (stockDetail.getAmount()));
                } else {
                    oldStockList.get(0).setAmount(amount + (stockDetail.getAmount()));
                    updateStockList.add(oldStockList.get(0));
                }
            } else {
                Stock exsitsStock = getStockByEquipDetailId(newStockList, stockDetail.getEquipmentDetailId());
                if (exsitsStock != null) {
                    exsitsStock.setAmount(exsitsStock.getAmount() + (stockDetail.getAmount()));
                } else {
                    Stock stock = new Stock();
                    stock.setAmount(stockDetail.getAmount());
                    stock.setWarehouseId(stockDetail.getWarehouseId());
                    stock.setEquipmentDetailId(stockDetail.getEquipmentDetailId());
                    newStockList.add(stock);
                }
            }
        }
        if (newStockList.size() > 0) {
            this.saveBatch(newStockList);
        }
        if (updateStockList.size() > 0) {
            this.updateBatchById(updateStockList);
        }
        // wl_stock_detail表
        for (StockDetail stockDetail : list) {
            Map<String, Object> columnMap = new HashMap<>();
            columnMap.put("equipment_detail_id", stockDetail.getEquipmentDetailId());
            columnMap.put("warehouse_id", stockDetail.getWarehouseId());
            List<Stock> oldStockList = (List<Stock>) listByMap(columnMap);
            oldStockList.addAll(newStockList);
            stockDetail.setStockId(oldStockList.stream().filter(x -> x.getEquipmentDetailId().equals(stockDetail.getEquipmentDetailId())
                    && x.getWarehouseId().equals(stockDetail.getWarehouseId())).findFirst().get().getId());
            stockDetail.setBatchNum(new SimpleDateFormat("yyyy-MM-dd").format(new Date()));
            stockDetail.setStatus(EquipStatusEnum.REPERTORY.getCode().toString());
            EquipmentSpecific equipmentSpecific = equipmentSpecificMapper.selectOne(new QueryWrapper<EquipmentSpecific>().eq("equipment_detail_id", stockDetail.getEquipmentDetailId()));
            stockDetail.setEquipmentSpecificId(equipmentSpecific.getId());
            // 如果是灭火药剂 入账 在原基础上修改数量
            if (BillContentEnum.MHYJ.getCode().equals(type)) {
                List<StockDetail> oldStockDetail = stockDetailService.list(
                        new QueryWrapper<StockDetail>().eq("equipment_detail_id", stockDetail.getEquipmentDetailId())
                                .eq("warehouse_structure_id", stockDetail.getWarehouseStructureId())
                                .eq("status", EquipStatusEnum.REPERTORY.getCode().toString()));
                if (oldStockDetail.size() > 0) {
                    stockDetail.setAmount(oldStockDetail.get(0).getAmount() + stockDetail.getAmount());
                    stockDetail.setId(oldStockDetail.get(0).getId());
                }
            }

        }
        boolean bool = stockDetailService.saveOrUpdateBatch(list);
        List<StockDataVO> dataList = new ArrayList<StockDataVO>();
        if (bool) {
            list.forEach(x -> {
                StockDataVO stockDataVO = new StockDataVO();
                stockDataVO.setStockDetailId(x.getId());
                stockDataVO.setQrCode(x.getQrCode());
                stockDataVO.setEquipmentDetailId(x.getEquipmentDetailId());
                dataList.add(stockDataVO);
            });
        }

        // wl_stock_bill表
        StockBill stockBill = new StockBill();
        stockBill.setBillType(type);
        stockBill.setBillCode(stockBillService.generateQrCode("RK"));
        stockBill.setWarehouseId(list.get(0).getWarehouseId());
        stockBill.setCreatorName(agencyUserModel.getRealName());
        stockBillService.save(stockBill);
        // wl_stock_bill_detail表
        List<StockBillDetail> stockBillDetailList = new ArrayList<StockBillDetail>();
        for (StockDetail stockDetail : list) {
            StockBillDetail stockBillDetail = new StockBillDetail();
            stockBillDetail.setWarehouseStructureId(stockDetail.getWarehouseStructureId());
            stockBillDetail.setStockDetailId(stockDetail.getId());
            stockBillDetail.setStockBillId(stockBill.getId());
            stockBillDetail.setAmount(stockDetail.getAmount());
            stockBillDetail.setEquipmentDetailId(stockDetail.getEquipmentDetailId());
            stockBillDetail.setSingleEquipCode(stockDetail.getQrCode());
            stockBillDetail.setBatchNum(new SimpleDateFormat("yyyy-MM-dd").format(new Date()));

            stockBillDetailList.add(stockBillDetail);
        }
        stockBillDetailService.saveBatch(stockBillDetailList);
        // wl_journal表
        List<Journal> journalList = new ArrayList<Journal>();
        for (StockDetail stockDetail : list) {
            Journal journal = new Journal();
            journal.setAmount(stockDetail.getAmount());
            journal.setEquipmentDetailId(stockDetail.getEquipmentDetailId());
            journal.setStockDetailId(stockDetail.getId());
            journal.setRemark(JournalTypeEnum.RK.getName());
            journal.setWarehouseStructureId(stockDetail.getWarehouseStructureId());
            journal.setState(JournalTypeEnum.RK.getCode());
            journalList.add(journal);
        }
        journalService.saveBatch(journalList);
        // wl_notice表
        noticeService.saveNotice(NoticeEnum.RK, stockBill.getId(), stockBill.getBillCode(),
                BillContentEnum.getEnum(type));
        stockBill.setStockDataVOS(dataList);
        return stockBill;
    }

    @Async
    void initEquipmentSystemSourceStatistics(List<EquipmentSpecific> equipmentSpecifics) {
        List<EquipmentSystemSourceStatistics> list = new ArrayList<>();
        equipmentSpecifics.parallelStream().forEach(x -> {
            //插入统计区域设备关表，初始化数据
            EquipmentSystemSourceStatistics equipmentSystemSourceStatistics = new EquipmentSystemSourceStatistics();
            equipmentSystemSourceStatistics.setEquipmentSpecificId(x.getId());
            equipmentSystemSourceStatistics.setStatus(1);
            if (x.getStockDetail() != null && x.getStockDetail().getWarehouseStructureId() != null) {
                WarehouseStructure warehouseStructure = warehouseStructureService.getById(x.getStockDetail().getWarehouseStructureId());
                while (warehouseStructure.getParentId() != null && !warehouseStructure.getParentId().equals(warehouseStructure.getWarehouseId())) {
                    warehouseStructure = warehouseStructureService.getById(warehouseStructure.getParentId());
                }
                equipmentSystemSourceStatistics.setSourceId(warehouseStructure.getId());
            }
            list.add(equipmentSystemSourceStatistics);
        });
        equipmentSystemSourceStatisticsService.saveBatch(list);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public List<EquipmentSpecific> uploadListByTemplate(List<EquipmentDetailDownloadTemplateDto> equipmentDetailDownloadVOS, ReginParams reginParams, AgencyUserModel agencyUserModel) {
        StringBuffer fireFightSysIdsBuffer = new StringBuffer();
        SimpleDateFormat stf = new SimpleDateFormat("yyyy-MM-dd");
        List<EquipmentSpecific> list = new ArrayList<>();
        if (equipmentDetailDownloadVOS.size() == 0) {
            throw new BadRequest("请填写数据后再上传！");
        }
        for (int i = 0; i < equipmentDetailDownloadVOS.size(); i++) {
            //查询装备定义信息
            QueryWrapper<Equipment> equipmentQueryWrapper = new QueryWrapper<>();
            equipmentQueryWrapper.lambda().eq(Equipment::getCode, equipmentDetailDownloadVOS.get(i).getCode());
            Equipment equipment = equipmentMapper.selectOne(equipmentQueryWrapper);
            if (equipment == null) {
                throw new BadRequest(String.format("装备(器材)编码[%S]填写错误，请输入正确的装备(器材)编码！",equipmentDetailDownloadVOS.get(i).getCode()));
            }
            String sysCode = equipmentDetailDownloadVOS.get(i).getSystemCode();
            if (StringUtils.isNotEmpty(sysCode) && StringUtils.isNotEmpty(sysCode.trim())) {
                Integer code = equipmentSpecificMapper.selectCount(new QueryWrapper<EquipmentSpecific>().eq("code", sysCode.trim()));
                if (code != 0) {
                    throw new BadRequest(String.format("设备编码[%S]填写重复，请重新输入！",sysCode));
                }
            }
            String iot = equipmentDetailDownloadVOS.get(i).getIotCode();
            if (StringUtils.isNotEmpty(iot) && StringUtils.isNotEmpty(iot.trim())) {
                Integer iot_code = equipmentSpecificMapper.selectCount(new QueryWrapper<EquipmentSpecific>().eq("iot_code", iot.trim()));
                if (iot_code != 0) {
                    throw new BadRequest(String.format("物联编码[%S]填写重复，请重新输入！",iot));
                }
            }
            AtomicReference<String> fightSysIds = new AtomicReference<>("");
            String fightingSysCodes = equipmentDetailDownloadVOS.get(i).getFightingSysCodes();
            if (StringUtils.isNotBlank(fightingSysCodes)) {
                String[] idsArr = fightingSysCodes.split("-");
                List<FireFightingSystemEntity> fightingSystemList = fireFightingSystemService.getFightingSysByCodes(idsArr);
                if (!fightingSystemList.isEmpty()) {
                    fightingSystemList.stream().forEach(x -> {
                        String sysCodes = fightSysIds.get();
                        if (StringUtils.isNotBlank(sysCodes)) {
                            fightSysIds.set(String.join(",", sysCodes, String.valueOf(x.getId())));
                        } else {
                            fightSysIds.set(String.join(",", String.valueOf(x.getId())));
                        }
                    });
                }
            }



            //插入模板信息
            EquipmentDetail equipmentDetail = new EquipmentDetail();
            equipmentDetail.setCode(equipmentDetailDownloadVOS.get(i).getCode());
            equipmentDetail.setBrand(equipmentDetailDownloadVOS.get(i).getBrand());
            equipmentDetail.setStandard(equipmentDetailDownloadVOS.get(i).getStandard());
            LambdaQueryWrapper<ManufacturerInfo> queryWrapper = new LambdaQueryWrapper<>();
            ManufacturerInfo info = manufacturerInfoService.getOne(queryWrapper.eq(ManufacturerInfo::getName, equipmentDetailDownloadVOS.get(i).getManufacturerName()));
            if (StringUtil.isNotEmpty(info)) {
               // throw new BadRequest("名称为" + equipmentDetailDownloadVOS.get(i).getManufacturerName() + "的生产厂商不存在！");
                equipmentDetail.setManufacturerId(info.getId());
                equipmentDetail.setManufacturerName(equipmentDetailDownloadVOS.get(i).getManufacturerName());
            }
            equipmentDetail.setEquipmentId(equipment.getId());
            equipmentDetail.setName(equipmentDetailDownloadVOS.get(i).getName());
            equipmentDetail.setArea(equipmentDetailDownloadVOS.get(i).getDescription());

            // 导入新增所属单位

            if (StringUtils.isNotBlank(equipmentDetailDownloadVOS.get(i).getCompanyName())) {
                String[] company = equipmentDetailDownloadVOS.get(i).getCompanyName().split("@");
                equipmentDetail.setCompanyName(company[0]);
            }


            equipmentDetailMapper.insert(equipmentDetail);

            //生成单件设备信息
            String qrCode = QRCodeUtil.generateQRCode();
            EquipmentSpecific equipmentSpecific = new EquipmentSpecific();
            equipmentSpecific.setQrCode(qrCode);
            equipmentSpecific.setEquipmentDetailId(equipmentDetail.getId());
            equipmentSpecific.setOrgCode(reginParams.getCompany().getOrgCode());
            equipmentSpecific.setEquipmentCode(equipmentDetail.getCode());
            equipmentSpecific.setName(equipmentDetail.getName());
            String iotCode = equipmentDetailDownloadVOS.get(i).getIotCode();
            iotCode = ExcelUtils.replaceAllBlank(iotCode);
            equipmentSpecific.setIotCode(iotCode);
            equipmentSpecific.setCode(equipmentDetailDownloadVOS.get(i).getSystemCode());
            equipmentSpecific.setSystemId(fightSysIds.get());
            equipmentSpecific.setNum(1);
            equipmentSpecific.setSingle(true);
            fireFightSysIdsBuffer.append(fightSysIds.get() + ",");
            // 导入新增所属队伍
            if (StringUtils.isNotBlank(equipmentDetailDownloadVOS.get(i).getFireTeam())) {
                String[] fireTeam = equipmentDetailDownloadVOS.get(i).getFireTeam().split("@");
                equipmentSpecific.setTeamName(fireTeam[0]);
                equipmentSpecific.setTeamId(fireTeam[1]);
            }
            // 导入新增所属单位

            if (StringUtils.isNotBlank(equipmentDetailDownloadVOS.get(i).getCompanyName())) {
                String[] company = equipmentDetailDownloadVOS.get(i).getCompanyName().split("@");
                equipmentSpecific.setAgencyId(company[1]);
            }
            equipmentSpecificMapper.insert(equipmentSpecific);

            //位置编码不为空入库
            if (equipmentDetailDownloadVOS.get(i) != null && equipmentDetailDownloadVOS.get(i).getWarehouseStructCode() != null) {
                QueryWrapper<WarehouseStructure> warehouseStructureQueryWrapper = new QueryWrapper<>();
                warehouseStructureQueryWrapper.lambda().eq(WarehouseStructure::getCode, equipmentDetailDownloadVOS.get(i).getWarehouseStructCode());
                WarehouseStructure warehouseStructure = warehouseStructureService.getOne(warehouseStructureQueryWrapper);
                if (warehouseStructure == null) {
                    throw new BadRequest(String.format("货位编码[%S]填写错误，请输入正确的货位编码！",equipmentDetailDownloadVOS.get(i).getWarehouseStructCode()));
                } else {
                    equipmentSpecific.setPosition(warehouseStructure.getFullName());
                    equipmentSpecificMapper.updateById(equipmentSpecific);
                }
                // 插入库存
                Stock stock = new Stock();
                stock.setAmount(Double.valueOf(equipmentSpecific.getNum()));
                stock.setCompanyName(reginParams.getCompany().getCompanyName());
                stock.setCompanyName(reginParams.getCompany().getOrgCode());
                stock.setDepartmentOrgcode(reginParams.getDepartment().getOrgCode());
                stock.setCompanyName(reginParams.getDepartment().getDepartmentName());
                stock.setEquipmentDetailId(equipmentSpecific.getEquipmentDetailId());
                stock.setWarehouseId(warehouseStructure.getWarehouseId());
                equipmentSpecific.setStock(stock);
                this.save(stock);

                //库存详情
                StockDetail stockDetail = new StockDetail();
                stockDetail.setCompanyName(reginParams.getCompany().getCompanyName());
                stockDetail.setOrgCode(reginParams.getCompany().getOrgCode());
                stockDetail.setDepartmentName(reginParams.getDepartment().getDepartmentName());
                stockDetail.setDepartmentOrgcode(reginParams.getDepartment().getOrgCode());
                stockDetail.setEquipmentDetailId(equipmentSpecific.getEquipmentDetailId());
                stockDetail.setEquipmentSpecificId(equipmentSpecific.getId());
                stockDetail.setStockId(stock.getId());
                stockDetail.setStatus(StockBillTypeEnum.DBRK.getValue());
                stockDetail.setUpdateDate(new Date());
                stockDetail.setQrCode(qrCode);
                stockDetail.setWarehouseStructureId(warehouseStructure.getId());
                stockDetail.setDescription(equipmentDetailDownloadVOS.get(i).getDescription());
                stockDetail.setWarehouseId(warehouseStructure.getWarehouseId());
                stockDetail.setAmount(1.00);
                equipmentSpecific.setStockDetail(stockDetail);
                stockDetailService.save(stockDetail);

                //生成入库单
                StockBill stockBill = new StockBill();
                stockBill.setCreatorId(Long.valueOf(agencyUserModel.getUserId()));
                stockBill.setCreatorName(agencyUserModel.getRealName());
                stockBill.setCompanyName(reginParams.getCompany().getCompanyName());
                stockBill.setDepartmentName(reginParams.getDepartment().getDepartmentName());
                stockBill.setDepartmentOrgcode(String.valueOf(reginParams.getDepartment().getDeptOrgCode()));
                stockBill.setOrgCode(reginParams.getCompany().getOrgCode());
                stockBill.setWarehouseId(warehouseStructure.getWarehouseId());
                stockBill.setBillCode(stockBillService.generateQrCode("RK"));
                stockBill.setBillType(StockBillTypeEnum.DBRK.getValue());
                stockBillService.save(stockBill);

                //生成入库单详情
                StockBillDetail stockBillDetail = new StockBillDetail();
                stockBillDetail.setAmount(stockDetail.getAmount());
                stockBillDetail.setEquipmentDetailId(equipmentDetail.getId());
                stockBillDetail.setStockDetailId(stockDetail.getId());
                stockBillDetail.setBatchNum(stf.format(new Date()));
                stockBillDetail.setCreatorId(Long.valueOf(agencyUserModel.getUserId()));
                stockBillDetail.setSingleEquipCode(stockDetail.getQrCode());
                stockBillDetail.setStockBillId(stockBill.getId());
                stockBillDetail.setWarehouseStructureId(warehouseStructure.getId());
                stockBillDetailService.save(stockBillDetail);
            }
            list.add(equipmentSpecific);
            this.equipmentSpecificIndexSave(equipmentDetail, equipmentSpecific);
        }
        relationRedisUtil.delSysRedisKey(fireFightSysIdsBuffer.toString());
        return list;
    }

    private void equipmentSpecificIndexSave(EquipmentDetail equipmentDetail, EquipmentSpecific equipmentSpecific) {
        List<EquipmentIndex> equipmentIndexList = iEquipmentIndexService.list(new LambdaQueryWrapper<EquipmentIndex>().eq(EquipmentIndex::getEquipmentId, equipmentDetail.getEquipmentId()));
        List<EquipmentSpecificIndex> equipmentSpecificIndices = equipmentIndexList.stream().map(index -> {
            EquipmentSpecificIndex equipmentSpecificIndex = new EquipmentSpecificIndex();
            equipmentSpecificIndex.setEquipmentIndexId(index.getId());
            equipmentSpecificIndex.setEquipmentSpecificId(equipmentSpecific.getId());
            equipmentSpecificIndex.setCreateDate(new Date());
            equipmentSpecificIndex.setEquipmentSpecialName(equipmentDetail.getName());
            equipmentSpecificIndex.setEquipmentIndexName(index.getPerfQuotaName());
            equipmentSpecificIndex.setEquipmentIndexKey(index.getPerfQuotaDefinitionId());
            return equipmentSpecificIndex;
        }).collect(Collectors.toList());
        if (!equipmentSpecificIndices.isEmpty()) {
            iEquipmentSpecificIndexSerivce.saveBatch(equipmentSpecificIndices);
        }
        if (equipmentSpecific.getSingle() && StringUtil.isNotEmpty(equipmentSpecific.getIotCode())) {
            EquipmentSpecificSerivceImpl.registerMqttTopic(equipmentSpecific.getIotCode(), equipmentIotMqttReceiveConfig);
        }
    }

    @Override
    public List<EquipmentSpecific> uploadList(List<EquipmentDetailDownloadVO> equipmentDetailDownloadVOS, ReginParams reginParams, AgencyUserModel agencyUserModel) {
        SimpleDateFormat stf = new SimpleDateFormat("yyyy-MM-dd");
        List<EquipmentSpecific> list = new ArrayList<>();
        for (int i = 0; i < equipmentDetailDownloadVOS.size(); i++) {
            //生成单件设备信息
            String qrCode = QRCodeUtil.generateQRCode();
            EquipmentSpecific equipmentSpecific = new EquipmentSpecific();
            equipmentSpecific.setQrCode(qrCode);
            equipmentSpecific.setEquipmentDetailId(equipmentDetailDownloadVOS.get(i).getId());
            equipmentSpecific.setOrgCode(reginParams.getCompany().getOrgCode());
            String iotCode = equipmentDetailDownloadVOS.get(i).getIotCode();
            iotCode = ExcelUtils.replaceAllBlank(iotCode);
            equipmentSpecific.setIotCode(iotCode);
            equipmentSpecific.setCode(equipmentDetailDownloadVOS.get(i).getCode());
            equipmentSpecific.setNum(1);
            equipmentSpecific.setSingle(true);
            //数据检查

//            if (!StringUtils.isEmpty(equipmentDetailDownloadVOS.get(i).getSystemCode())) {
//                throw new RuntimeException("第" + (i + 5) + "行装备编码为必填项，请检查!");
//            }

            if (!StringUtils.isEmpty(equipmentDetailDownloadVOS.get(i).getSystemCode())) {
                //获取系统编码对应的id
                QueryWrapper<EquipmentManageEntity> equipmentManageQueryWrapper = new QueryWrapper<>();
                equipmentManageQueryWrapper.eq("code", equipmentDetailDownloadVOS.get(i).getSystemCode());
                EquipmentManageEntity equipmentManage = equipmentManageService.getOne(equipmentManageQueryWrapper);
                if (equipmentManage == null) {
                    throw new RuntimeException("第" + (i + 6) + "行系统编码有误，请检查!");
                }
//                equipmentSpecific.setSystemId(equipmentManage.getId());
            }
            equipmentSpecificMapper.insert(equipmentSpecific);

            if (!StringUtils.isEmpty(equipmentDetailDownloadVOS.get(i).getSourceId())) {
                if (StringUtils.isEmpty(equipmentDetailDownloadVOS.get(i).getSourceId())) {
                    throw new RuntimeException("第" + (i + 7) + "行数据对应的区域编码不能为空!");
                }
//                QueryWrapper<Warehouse> warehouseQueryWrapper = new QueryWrapper<>();
//                warehouseQueryWrapper.eq("source_code", equipmentDetailDownloadVOS.get(i).getSourceId());
//                Long warehouseId = warehouseService.getOne(warehouseQueryWrapper).getId();
                QueryWrapper<WarehouseStructure> warehouseStructureQueryWrapper = new QueryWrapper<>();
                warehouseStructureQueryWrapper.eq("source_code", equipmentDetailDownloadVOS.get(i).getSourceId());
                WarehouseStructure warehouseStructure = warehouseStructureService.getOne(warehouseStructureQueryWrapper);
                if (warehouseStructure == null) {
                    throw new RuntimeException("第" + (i + 7) + "行数据对应的区域编码无效，请检查!");
                }

                //插入库存
                Stock stock = new Stock();
                stock.setAmount(Double.valueOf(equipmentSpecific.getNum()));
                stock.setCompanyName(reginParams.getCompany().getCompanyName());
                stock.setCompanyName(reginParams.getCompany().getOrgCode());
                stock.setDepartmentOrgcode(reginParams.getDepartment().getOrgCode());
                stock.setCompanyName(reginParams.getDepartment().getDepartmentName());
                stock.setEquipmentDetailId(equipmentSpecific.getEquipmentDetailId());
                stock.setWarehouseId(warehouseStructure.getWarehouseId());
                equipmentSpecific.setStock(stock);
                this.save(stock);

                //库存详情
                StockDetail stockDetail = new StockDetail();
                stockDetail.setCompanyName(reginParams.getCompany().getCompanyName());
                stockDetail.setOrgCode(reginParams.getCompany().getOrgCode());
                stockDetail.setDepartmentName(reginParams.getDepartment().getDepartmentName());
                stockDetail.setDepartmentOrgcode(reginParams.getDepartment().getOrgCode());
                stockDetail.setEquipmentDetailId(equipmentSpecific.getEquipmentDetailId());
                stockDetail.setEquipmentSpecificId(equipmentSpecific.getId());
                stockDetail.setStockId(stock.getId());
                stockDetail.setStatus(StockBillTypeEnum.DBRK.getValue());
                stockDetail.setUpdateDate(new Date());
                stockDetail.setQrCode(qrCode);
                stockDetail.setWarehouseStructureId(warehouseStructure.getId());
                stockDetail.setDescription(equipmentDetailDownloadVOS.get(i).getDescription());
                stockDetail.setWarehouseId(warehouseStructure.getWarehouseId());
                stockDetail.setAmount(1.00);
                equipmentSpecific.setStockDetail(stockDetail);
                stockDetailService.save(stockDetail);

                //生成入库单
                StockBill stockBill = new StockBill();
                stockBill.setCreatorId(Long.valueOf(agencyUserModel.getUserId()));
                stockBill.setCreatorName(agencyUserModel.getRealName());
                stockBill.setCompanyName(reginParams.getCompany().getCompanyName());
                stockBill.setDepartmentName(reginParams.getDepartment().getDepartmentName());
                stockBill.setDepartmentOrgcode(String.valueOf(reginParams.getDepartment().getDeptOrgCode()));
                stockBill.setOrgCode(reginParams.getCompany().getOrgCode());
                stockBill.setWarehouseId(warehouseStructure.getWarehouseId());
                stockBill.setBillCode(stockBillService.generateQrCode("RK"));
                stockBill.setBillType(StockBillTypeEnum.DBRK.getValue());
                stockBillService.save(stockBill);

                StockBillDetail stockBillDetail = new StockBillDetail();
                stockBillDetail.setAmount(stockDetail.getAmount());
                stockBillDetail.setEquipmentDetailId(equipmentDetailDownloadVOS.get(i).getId());
                stockBillDetail.setStockDetailId(stockDetail.getId());
                stockBillDetail.setBatchNum(stf.format(new Date()));
                stockBillDetail.setCreatorId(Long.valueOf(agencyUserModel.getUserId()));
                stockBillDetail.setSingleEquipCode(stockDetail.getQrCode());
                stockBillDetail.setStockBillId(stockBill.getId());
                stockBillDetail.setWarehouseStructureId(warehouseStructure.getId());
                stockBillDetailService.save(stockBillDetail);
            }

            list.add(equipmentSpecific);
        }
        ;
        return list;
    }

    private Stock getStockByEquipDetailId(List<Stock> list, Long equipmentDetailId) {
        for (Stock stock : list) {
            if (stock.getEquipmentDetailId() != null
                    && stock.getEquipmentDetailId().longValue() == equipmentDetailId.longValue()) {
                return stock;
            }
        }
        return null;
    }
}
