package com.zt.plat.module.erp.service.erp;

import cn.hutool.core.collection.CollUtil;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.xxl.job.core.handler.annotation.XxlJob;
import com.zt.plat.framework.common.pojo.CommonResult;
import com.zt.plat.framework.common.pojo.PageResult;
import com.zt.plat.framework.common.pojo.vo.BatchDeleteReqVO;
import com.zt.plat.framework.common.util.object.BeanUtils;
import com.zt.plat.framework.mybatis.core.query.LambdaQueryWrapperX;
import com.zt.plat.module.api.BaseApi;
import com.zt.plat.module.api.dto.MaterialOtherDTO;
import com.zt.plat.module.base.api.departmentmaterial.DepartmentMaterialApi;
import com.zt.plat.module.base.api.departmentmaterial.dto.DepartmentMaterialPageReqDTO;
import com.zt.plat.module.base.api.departmentmaterial.dto.DepartmentMaterialRespDTO;
import com.zt.plat.module.base.api.materialinfomation.MaterialInfomationApi;
import com.zt.plat.module.base.api.materialinfomation.dto.MaterialInfomationPageReqDTO;
import com.zt.plat.module.base.api.materialinfomation.dto.MaterialInfomationRespDTO;
import com.zt.plat.module.erp.api.dto.ErpMaterialDTO;
import com.zt.plat.module.erp.controller.admin.erp.vo.*;
import com.zt.plat.module.erp.dal.dataobject.erp.ErpWarehouseDO;
import com.zt.plat.module.erp.utils.ErpConfig;
import com.zt.plat.module.erp.utils.MyRedisConfig;
import com.zt.plat.module.erp.enums.OftenEnum;
import com.zt.plat.module.erp.dal.dataobject.erp.ErpMaterialDO;
import com.zt.plat.module.erp.dal.mysql.erp.ErpMaterialMapper;
import com.zt.plat.module.system.api.dept.DeptApi;
import jakarta.annotation.Resource;
import jakarta.validation.constraints.NotNull;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

import static com.zt.plat.framework.common.exception.util.ServiceExceptionUtil.exception;
import static com.zt.plat.framework.common.pojo.PageParam.PAGE_SIZE_NONE;
import static com.zt.plat.module.erp.enums.ErrorCodeConstants.*;
import static dm.jdbc.util.DriverUtil.log;

/**
 * ERP物料数据 Service 实现类
 *
 * @author 后台管理
 */
@Service
@Validated
public class ErpMaterialServiceImpl implements ErpMaterialService {

    @Resource
    private ErpMaterialMapper erpMaterialMapper;
    @Resource
    private BaseApi baseApi;
    @Resource
    private MyRedisConfig myRedisConfig;
    @Resource
    private ErpConfig erpConfig;
    @Resource
    private ErpErpMaterialCorrService erpMaterialCorrService;
    @Resource
    private MaterialInfomationApi materialInfomationApi;
    @Resource
    private DepartmentMaterialApi departmentMaterialApi;

    @Resource
    private DeptApi deptApi;

    @Override
    public ErpMaterialRespVO createErpMaterial(ErpMaterialSaveReqVO createReqVO) {
        // 校验存在
        validateErpFactoryExistsNumber(createReqVO.getDownCenterNumber());
        // 插入
        ErpMaterialDO erpMaterial = BeanUtils.toBean(createReqVO, ErpMaterialDO.class);
        // 工厂编码自动生成，格式 GC-0001,依次新增
        if (erpMaterial.getDownCenterNumber() == null) {
            String maxCode = erpMaterialMapper.selectMaxCode();
            if (maxCode == null) {
                erpMaterial.setDownCenterNumber("WL-0001");
            } else {
                String prefix = "WL-";
                String numberPart = maxCode.substring(prefix.length());
                int nextNumber = Integer.parseInt(numberPart) + 1;
                String nextCode = prefix + String.format("%04d", nextNumber);
                erpMaterial.setDownCenterNumber(nextCode);
            }
        }
        erpMaterial.setType("SPLY");
        erpMaterialMapper.insert(erpMaterial);
        // 返回
        return BeanUtils.toBean(erpMaterial, ErpMaterialRespVO.class);
    }

    @Override
    public void updateErpMaterial(ErpMaterialSaveReqVO updateReqVO) {
        // 校验存在
        validateErpMaterialExists(updateReqVO.getId());
        validateErpFactoryExistsNumber(updateReqVO.getDownCenterNumber());
        // 更新
        ErpMaterialDO updateObj = BeanUtils.toBean(updateReqVO, ErpMaterialDO.class);
        if (updateObj.getType().equals("SPLY")) {
            erpMaterialMapper.updateById(updateObj);
        } else {
            throw exception(ERP_MATERIAL_NOT_ALLOW_UPDATE);
        }
    }

    @Override
    public void deleteErpMaterial(Long id) {
        // 校验存在
        validateErpMaterialExists(id);
        // 删除
        erpMaterialMapper.deleteById(id);
    }

    @Override
    public void deleteErpMaterialListByIds(List<Long> ids) {
        // 校验存在
        validateErpMaterialExists(ids);
        // 删除
        erpMaterialMapper.deleteByIds(ids);
    }

    private void validateErpMaterialExists(List<Long> ids) {
        List<ErpMaterialDO> list = erpMaterialMapper.selectByIds(ids);
        if (CollUtil.isEmpty(list) || list.size() != ids.size()) {
            throw exception(ERP_MATERIAL_NOT_EXISTS);
        }
        List<ErpMaterialDO> erpMaterialDOList = list.stream().filter(erpMaterialDO -> erpMaterialDO.getType().equals("ERP")).collect(Collectors.toList());
        if (CollUtil.isEmpty(erpMaterialDOList)) {
            throw exception(ERP_MATERIAL_NOT_ALLOW_DELETE);
        }
        // 优化成批量查询，使用IN语句
        List<String> downCenterNumbers = list.stream().map(ErpMaterialDO::getDownCenterNumber).collect(Collectors.toList());

        // 使用IN语句批量查询所有物料编码的数量
        Integer countMap = erpMaterialMapper.countByErpMNumbers(downCenterNumbers);
        if (countMap > 1) {
            throw exception(ERP_MATERIAL_OTHER_NOT_ALLOW_DELETE);
        }
    }

    private void validateErpMaterialExists(Long id) {
        if (erpMaterialMapper.selectById(id) == null) {
            throw exception(ERP_MATERIAL_NOT_EXISTS);
        }
    }

    private void validateErpFactoryExistsNumber(String number) {
        List<ErpMaterialDO> list = erpMaterialMapper.selectList(new LambdaQueryWrapperX<ErpMaterialDO>()).stream().filter(erpWarehouseDO -> erpWarehouseDO.getDownCenterNumber().equals(number)).toList();
        if (!list.isEmpty()) {
            throw exception(ERP_MATERIAL_EXISTS);
        }
    }

    @Override
    public ErpMaterialDO getErpMaterial(Long id) {
        return erpMaterialMapper.selectById(id);
    }

    @Override
    public PageResult<ErpMaterialDO> getErpMaterialPage(ErpMaterialPageReqVO pageReqVO) {
        return erpMaterialMapper.selectPage(pageReqVO);
    }

    @Override
    public PageResult<ErpMaterialRespVO> getErpMaterialPageAndOther(ErpMaterialPageReqVO pageReqVO) {
        try {
            PageResult<ErpMaterialDO> pageResult = erpMaterialMapper.selectPage(pageReqVO);
            PageResult<ErpMaterialRespVO> pageResultRespVo = BeanUtils.toBean(pageResult, ErpMaterialRespVO.class);
            for (ErpMaterialRespVO respVO : pageResultRespVo.getList()) {
                respVO.setMaterialNumber(respVO.getDownCenterNumber());
                MaterialOtherDTO dto = new MaterialOtherDTO();
                dto.setMaterialNumber(respVO.getDownCenterNumber());
                List<MaterialOtherDTO> dtos = baseApi.getMaterialOtherNoPage(dto);
                if (dtos != null) {
                    respVO.setMaterialOtherDTOS(dtos);
                }
            }
            return pageResultRespVo;
        } catch (Exception e) {
            throw exception(ERP_MATERIAL_NOT_EXISTS);
        }
    }

    @Override
    public String getMaterialUnit(String materialNumber) {
        return erpMaterialMapper.getMaterialUnit(materialNumber);
    }

    @Override
    public List<ErpMaterialRespVO> createErpMaterialCorr(ErpMaterialCorrSaveReqVO erpMaterialCorrSaveReqVO) {
        List<ErpMaterialCorrRspVO> erpMaterialCorrRspVOS = erpMaterialCorrService.create(erpMaterialCorrSaveReqVO);
        List<ErpMaterialRespVO> erpMaterialRespVOS = new ArrayList<>();
        Set<Long> parentIds = erpMaterialCorrRspVOS.stream().map(ErpMaterialCorrRspVO::getMaterialParentId).filter(Objects::nonNull).collect(Collectors.toSet());
        Set<Long> materialIds = erpMaterialCorrRspVOS.stream().map(ErpMaterialCorrRspVO::getMaterialId).filter(Objects::nonNull).collect(Collectors.toSet());
        if (parentIds.size() != 1) {
            throw exception(MATERIAL_ERROR);
        }
        ErpMaterialRespVO erpMaterialParent = buildErpMaterialRespDataById(parentIds.iterator().next());
        erpMaterialRespVOS.add(erpMaterialParent);
        if (!materialIds.isEmpty()) {
            for (Long materialId : materialIds) {
                ErpMaterialRespVO erpMaterialRespVO = buildErpMaterialRespDataById(materialId);
                erpMaterialRespVOS.add(erpMaterialRespVO);
            }
        }
        return erpMaterialRespVOS;
    }

    private ErpMaterialRespVO buildErpMaterialRespDataById(Long id) {
        DepartmentMaterialPageReqDTO departmentMaterialPageReqDTO = new DepartmentMaterialPageReqDTO();
        departmentMaterialPageReqDTO.setInfomationId(id);
        departmentMaterialPageReqDTO.setPageSize(10000);
        PageResult<DepartmentMaterialRespDTO> data = departmentMaterialApi.getDepartmentMaterialPage(departmentMaterialPageReqDTO).getData();
        if (data == null || data.getList().isEmpty()) {
            return null;
        }
        return BeanUtils.toBean(buildErpMaterialDOData(CommonResult.success(data.getList().get(0))), ErpMaterialRespVO.class);
    }

    public ErpMaterialDO buildErpMaterialDOData(CommonResult<DepartmentMaterialRespDTO> materialInfomation) {
        if (materialInfomation.getData() == null) {
            return new ErpMaterialDO();
        }
        ErpMaterialDO erpMaterialDO = new ErpMaterialDO();
        DepartmentMaterialRespDTO data = materialInfomation.getData();
        MaterialAttributeUtils.MaterialAttribute materialAttribute = MaterialAttributeUtils.safeExtractAllAttributes(data);
        // 有对应关系的字段赋值
        erpMaterialDO.setMaterialNumber(data.getMaterialNumber());//物料编码
        erpMaterialDO.setId(data.getInfomationId()); // 主键
        erpMaterialDO.setMaterialName(data.getMaterialName()); // 物料名称
        erpMaterialDO.setDownCenterNumber(materialAttribute.mtrlZhongtongCode()); // 中铜物料编码
        erpMaterialDO.setCenterNumber(materialAttribute.mtrlChalcoCode()); // 中铝物料编码
        erpMaterialDO.setUnit(materialAttribute.mtrlBaseUnitCode()); // 计量单位编码
        erpMaterialDO.setUnitDescription(materialAttribute.mtrlBaseUnitName()); // 计量单位描述
        erpMaterialDO.setMaterialLengthDescription(materialAttribute.mtrlLongDesc()); // 物料长描述
        if (materialAttribute.mtrlDecimal() != null) {
            erpMaterialDO.setDecimalValue(materialAttribute.mtrlDecimal().longValue()); // 小数位数
        }
        erpMaterialDO.setAbbreviation(materialAttribute.mtrlElement()); // 金属元素缩写
        erpMaterialDO.setCreateDate(materialAttribute.mtrlRecordTime()); // 创建日期（物料记录时间）
        // 无对应关系的字段（暂未赋值，需根据业务补充映射规则）
        // erpMaterialDO.setMaterialType(null); // 物料类型
        // erpMaterialDO.setMaterialGroupDate(null); // 物料大类组
        // erpMaterialDO.setExternalMaterialGroupDate(null); // 外部物料小类组
        // erpMaterialDO.setMaterialTypeDescription(null); // 物料类型描述
        // erpMaterialDO.setMaterialGroupDescription(null); // 物料组描述
        // erpMaterialDO.setExternalMaterialGroupDescription(null); // 外部物料小类组描述
        // erpMaterialDO.setType(null); // 类型（TP）
        // erpMaterialDO.setName(null); // 金属元素名称（NAME字段，需区分物料名称）
        // erpMaterialDO.setCoding(null); // 金属元素编码
        // erpMaterialDO.setGradeUnit(null); // 品位单位
        return erpMaterialDO;
    }


    @Override
    public void deleteErpMaterialCorr(DeleteErpMaterialCorrVO reqVO) {
        erpMaterialCorrService.deleteBatch(reqVO);
    }

    @Override
    public ErpMaterialDO getErpMaterialById(Long id) {
        DepartmentMaterialPageReqDTO departmentMaterialPageReqDTO = new DepartmentMaterialPageReqDTO();
        departmentMaterialPageReqDTO.setInfomationId(id);
        departmentMaterialPageReqDTO.setPageSize(10000);
        PageResult<DepartmentMaterialRespDTO> data = departmentMaterialApi.getDepartmentMaterialPage(departmentMaterialPageReqDTO).getData();
        if (data == null || data.getList() == null || data.getList().isEmpty()) {
            return null;
        }
        return buildErpMaterialDOData(CommonResult.success(data.getList().get(0)));
    }

    @Override
    public List<ErpMaterialRespVO> getErpMaterialByMainMaterial(Long mainMaterial, String companyCode) {
        List<ErpMaterialCorrRspVO> erpMaterialByMainMaterial = erpMaterialCorrService.getErpMaterialByMainMaterial(List.of(mainMaterial), companyCode);
        List<ErpMaterialDO> erpMaterialDOList = new ArrayList<>();
        List<ErpMaterialRespVO> erpMaterialRespVOS = new ArrayList<>();
        if (erpMaterialByMainMaterial.isEmpty()) {
            return erpMaterialRespVOS;
        }
        List<Long> mIds = erpMaterialByMainMaterial.stream().map(ErpMaterialCorrRspVO::getMaterialId).toList();
        //构造查询条件
        DepartmentMaterialPageReqDTO departmentMaterialPageReqDTO = new DepartmentMaterialPageReqDTO();
        departmentMaterialPageReqDTO.setInfomationIds(mIds);
        departmentMaterialPageReqDTO.setPageSize(10000);
        departmentMaterialPageReqDTO.setDeptId(erpMaterialByMainMaterial.get(0).getDeptId());
        PageResult<DepartmentMaterialRespDTO> departmentMaterialPage = departmentMaterialApi.getDepartmentMaterialPage(departmentMaterialPageReqDTO).getData();
        if (departmentMaterialPage == null || departmentMaterialPage.getList() == null || departmentMaterialPage.getList().isEmpty()) {
            return erpMaterialRespVOS;
        }

        departmentMaterialPage.getList().forEach(item -> {
            ErpMaterialDO erpMaterialDO = buildErpMaterialDOData(CommonResult.success(item));
            erpMaterialDOList.add(erpMaterialDO);
        });
        erpMaterialRespVOS = BeanUtils.toBean(erpMaterialDOList, ErpMaterialRespVO.class);
        return erpMaterialRespVOS;
    }

    @Override
    public PageResult<ErpMaterialDO> getErpMaterialByApi(MaterialInfomationApiVO vo) {
        //通过部门编码查询数据库，获取到部门ID
        List<ErpMaterialCorrRspVO> erpMaterialByCompanyCode = erpMaterialCorrService.getErpMaterialByMainMaterialByCode(vo.getMaterialNumber(), vo.getDeptId());
        if (erpMaterialByCompanyCode.isEmpty()) {
            return new PageResult<>();
        }
        Set<Long> collect = erpMaterialByCompanyCode.stream().map(ErpMaterialCorrRspVO::getDeptId).collect(Collectors.toSet());
        DepartmentMaterialPageReqDTO material = new DepartmentMaterialPageReqDTO();
        material.setMaterialNumber(vo.getMaterialNumber());
        material.setMaterialName(vo.getMaterialName());
        material.setPageSize(vo.getPageSize());
        material.setPageNo(vo.getPageNo());
        material.setDeptId(collect.iterator().next());
        CommonResult<PageResult<DepartmentMaterialRespDTO>> departmentMaterialPage = departmentMaterialApi.getDepartmentMaterialPage(material);
        List<ErpMaterialDO> erpMaterialDOList = new ArrayList<>();
        //开始时间
        if (departmentMaterialPage.getData() != null && departmentMaterialPage.getData().getList() != null && !departmentMaterialPage.getData().getList().isEmpty()) {
            departmentMaterialPage.getData().getList().forEach(materialInfomation -> {
                ErpMaterialDO erpMaterialDO = buildErpMaterialDOData(CommonResult.success(materialInfomation));
                erpMaterialDOList.add(erpMaterialDO);
            });
        }
        return new PageResult<>(erpMaterialDOList, departmentMaterialPage.getData().getTotal());
    }

    @Override
    public List<ErpMaterialDO> getErpMaterialByMainMaterialByCode(String code, String companyCode) {
        List<ErpMaterialDO> erpMaterialDOList = new ArrayList<>();
        DepartmentMaterialPageReqDTO material = new DepartmentMaterialPageReqDTO();
        material.setMaterialNumber(code);
        material.setPageSize(10000);
        List<ErpMaterialCorrRspVO> erpMaterialByCompanyCode = erpMaterialCorrService.getErpMaterialByCompanyCode(companyCode);
        if (erpMaterialByCompanyCode.isEmpty()) {
            return erpMaterialDOList;
        }
        Set<Long> collect = erpMaterialByCompanyCode.stream().map(ErpMaterialCorrRspVO::getDeptId).collect(Collectors.toSet());
        if (collect.size() != 1) {
            throw exception(CUSTOM_ERROR, "部门编码不唯一或部门编码不存在");
        }
        material.setDeptId(collect.iterator().next());
        CommonResult<PageResult<DepartmentMaterialRespDTO>> departmentMaterialPage = departmentMaterialApi.getDepartmentMaterialPage(material);

        if (departmentMaterialPage.isSuccess() && departmentMaterialPage.getData() != null && !departmentMaterialPage.getData().getList().isEmpty()) {
            departmentMaterialPage.getData().getList().forEach(materialInfomation -> {
                ErpMaterialDO erpMaterialDO = buildErpMaterialDOData(CommonResult.success(materialInfomation));
                erpMaterialDOList.add(erpMaterialDO);
            });
            return erpMaterialDOList;
        }
        return null;
    }

    @Override
    public List<ErpMaterialDO> getErpMaterialByApiByCode(String code, String companyCode) {
        List<ErpMaterialDO> erpMaterialDOList = new ArrayList<>();
        //获取该物料编码下的所有物料id,并根据这个ID查询子物料
        List<ErpMaterialCorrRspVO> erpMaterialByMainMaterialByCode = erpMaterialCorrService.getErpMaterialByMainMaterialByCode(code, companyCode);
        if (erpMaterialByMainMaterialByCode.isEmpty()) {
            return erpMaterialDOList;
        }
        List<Long> mIds = erpMaterialByMainMaterialByCode.stream().map(ErpMaterialCorrRspVO::getMaterialId).toList();
        CommonResult<List<MaterialInfomationRespDTO>> materialInfomationListByIds = materialInfomationApi.getMaterialInfomationListByIds(mIds);
        if (materialInfomationListByIds == null || materialInfomationListByIds.getData() == null || materialInfomationListByIds.getData().isEmpty()) {
            return erpMaterialDOList;
        }
        List<MaterialInfomationRespDTO> data = materialInfomationListByIds.getData();
        PageResult<DepartmentMaterialRespDTO> departmentMaterialPage =new PageResult<>();
        List<DepartmentMaterialRespDTO> dtos=new ArrayList<>();
        data.forEach(item->{
            DepartmentMaterialRespDTO departmentMaterialRespDTO = new DepartmentMaterialRespDTO();
            departmentMaterialRespDTO.setId(item.getId());
            departmentMaterialRespDTO.setMaterialNumber(item.getCode());
            departmentMaterialRespDTO.setMaterialName(item.getName());
            departmentMaterialRespDTO.setClassesId(item.getClassesId());
            departmentMaterialRespDTO.setRemark(item.getRemark());
            departmentMaterialRespDTO.setCreateTime(item.getCreateTime());
            departmentMaterialRespDTO.setFlatAttributes(item.getFlatAttributes());
            dtos.add(departmentMaterialRespDTO);
        });
        departmentMaterialPage.setList(dtos);
        departmentMaterialPage.setTotal((long) data.size());
        departmentMaterialPage.getList().forEach(item -> {
            ErpMaterialDO erpMaterialDO = buildErpMaterialDOData(CommonResult.success(item));
            erpMaterialDOList.add(erpMaterialDO);
        });
        return erpMaterialDOList;
    }

    @Override
    public  PageResult<ErpMaterialDO>  getErpProdMaterialByApi(MaterialInfomationApiVO vo) {
        DepartmentMaterialPageReqDTO pageReqDTO = new DepartmentMaterialPageReqDTO();
        pageReqDTO.setMaterialNumber(vo.getMaterialNumber());
        pageReqDTO.setMaterialName(vo.getMaterialName());
        pageReqDTO.setDeptId(Long.valueOf(vo.getDeptId()));
        pageReqDTO.setPageSize(vo.getPageSize());
        pageReqDTO.setPageNo(vo.getPageNo());
        CommonResult<PageResult<DepartmentMaterialRespDTO>> departmentMaterialPage = departmentMaterialApi.getDepartmentMaterialPage(pageReqDTO);
        PageResult<DepartmentMaterialRespDTO> data = departmentMaterialPage.getData();
        if (data == null || data.getList() == null || data.getList().isEmpty()) {
            return new PageResult<>();
        }
        List<ErpMaterialDO> erpMaterialDOList = new ArrayList<>();
        data.getList().forEach(item -> {
            ErpMaterialDO erpMaterialDO = buildErpMaterialDOData(CommonResult.success(item));
            erpMaterialDOList.add(erpMaterialDO);
        });
        return new PageResult<>(erpMaterialDOList, departmentMaterialPage.getData().getTotal());
    }

    @Override
    @Transactional
    @XxlJob("getErpMaterialTask")
    public void callErpRfcInterface() {
        OftenEnum.FuncnrEnum funcnrEnum = OftenEnum.FuncnrEnum.物料数据;
        String funcnr = funcnrEnum.getFuncnr();
        //防止缓存数据丢失
        String key = "erp" + funcnrEnum.getFuncnr();
        if (myRedisConfig.getRedisCache(key) == null) {
            initialize(key);
        }

        // 构建req参数
        Map<String, Object> req = new HashMap<>();
        List<Map<String, String>> datumList = new ArrayList<>();
        Map<String, String> datumEntry = new HashMap<>();
        datumEntry.put("sign", "I");
        datumEntry.put("option", "EQ");
//            datumEntry.put("low", "2021-05-20");
        datumEntry.put("low", LocalDate.now().toString());
        datumList.add(datumEntry);
        req.put(funcnrEnum.getDatekey(), datumList);

        // 1. 调用ERP接口获取数据
        Map<String, Object> dataFromERP = erpConfig.fetchDataFromERP(funcnr, req);
        JSONArray dataArray = (JSONArray) dataFromERP.get("E_RESP");
        if (dataArray == null || dataArray.isEmpty()) {
            return;
        }

        // 2. 处理公司数据，区分新增和更新
        ProcessingResult result = processData(dataArray, funcnrEnum);

        // 3. 批量保存数据
        saveData(result);
    }

    /**
     * 处理数据，区分新增和更新
     */
    private ProcessingResult processData(JSONArray dataArray, OftenEnum.FuncnrEnum funcnr) {
        String key = "erp" + funcnr.getFuncnr();
        Map<String, List<String>> numbers = myRedisConfig.numbers(dataArray, key, funcnr.getDatakey());
        List<String> allnumbers = numbers.get("all");
        List<String> comnumbers = numbers.get("com");
        List<ErpMaterialDO> toUpdate = new ArrayList<>();
        List<ErpMaterialDO> toInsert = new ArrayList<>();

        for (int i = 0; i < dataArray.size(); i++) {
            JSONObject dataJson = dataArray.getJSONObject(i);
            if (dataJson != null) {
                String number = dataJson.getString("MATNR").trim();
                ErpMaterialDO DO = new ErpMaterialDO();
                DO.setDownCenterNumber(number);
                DO.setCenterNumber(dataJson.getString("BISMT"));
                if (!dataJson.getString("ERSDA").equals("0000-00-00")) {
                    DO.setCreateDate(LocalDateTime.parse(dataJson.getString("ERSDA") + "T00:00:00"));
                }
                DO.setMaterialType(dataJson.getString("MTART"));
                DO.setMaterialGroupDate(dataJson.getString("MATKL"));
                DO.setExternalMaterialGroupDate(dataJson.getString("EXTWG"));
                DO.setUnit(dataJson.getString("MEINS"));
                DO.setUnitDescription(dataJson.getString("MSEHT"));
                DO.setMaterialTypeDescription(dataJson.getString("MTBEZ"));
                DO.setMaterialGroupDescription(dataJson.getString("WGBEZ"));
                DO.setExternalMaterialGroupDescription(dataJson.getString("EWBEZ"));
                DO.setMaterialName(dataJson.getString("MAKTX"));
                DO.setMaterialLengthDescription(dataJson.getString("LDESC"));
                DO.setType("ERP");

                if (comnumbers.contains(number)) {
                    // 更新
                    toUpdate.add(DO);
                } else {
                    // 新增
                    toInsert.add(DO);
                }
            }
        }

        return new ProcessingResult(toUpdate, toInsert, key, allnumbers);
    }

    /**
     * 批量保存数据
     */
    private void saveData(ProcessingResult result) {
        // 批量新增和更新
        if (!result.toInsert.isEmpty()) {
            erpMaterialMapper.insertBatch(result.toInsert);
        }
        if (!result.toUpdate.isEmpty()) {
            erpMaterialMapper.updateBatchByNumber(result.toUpdate);
        }
        myRedisConfig.updateRedisCache(result.key, result.allnumbers);
    }

    /**
     * 数据处理结果封装类
     */
    private static class ProcessingResult {
        private final List<ErpMaterialDO> toUpdate;
        private final List<ErpMaterialDO> toInsert;
        private final String key;
        private final List<String> allnumbers;

        public ProcessingResult(List<ErpMaterialDO> toUpdate, List<ErpMaterialDO> toInsert, String key, List<String> allnumbers) {
            this.toUpdate = toUpdate;
            this.toInsert = toInsert;
            this.key = key;
            this.allnumbers = allnumbers;
        }
    }

    private void initialize(String key) {
        List<String> existingNumbers = erpMaterialMapper.selectList(new LambdaQueryWrapperX<ErpMaterialDO>()).stream().filter(ErpMaterialDO -> ErpMaterialDO.getType().equals("ERP")).map(ErpMaterialDO::getDownCenterNumber).collect(Collectors.toList());
        myRedisConfig.updateRedisCache(key, existingNumbers);
    }
}