package com.jwipc.supplier.logic.impl;


import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.read.listener.ReadListener;
import com.alibaba.excel.util.ListUtils;
import com.alibaba.fastjson2.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.enums.SqlLike;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.sql.SqlUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.google.common.base.Strings;
import com.google.common.collect.Lists;
import com.jwipc.api.dto.ApiResponse;
import com.jwipc.constant.DictCode;
import com.jwipc.exception.DaoException;
import com.jwipc.page.PageUtil;
import com.jwipc.page.PageView;
import com.jwipc.security.LoginUtil;
import com.jwipc.supplier.constant.SupplierMesClient;
import com.jwipc.supplier.convert.SupplierAvlConvert;
import com.jwipc.supplier.dto.*;
import com.jwipc.supplier.entity.AvlItem;
import com.jwipc.supplier.entity.Supplier;
import com.jwipc.supplier.entity.SupplierAvl;
import com.jwipc.supplier.logic.SupplierAvlLogic;
import com.jwipc.supplier.model.po.SupplierAvlSelectPO;
import com.jwipc.supplier.model.query.SupplierAvlQuery;
import com.jwipc.supplier.service.IAvlItemService;
import com.jwipc.supplier.service.ISupplierAvlService;
import com.jwipc.supplier.service.ISupplierService;
import com.jwipc.sys.client.DictClient;
import com.jwipc.sys.client.ProductClient;
import com.jwipc.sys.client.SequenceClient;
import com.jwipc.sys.client.dto.DictDTO;
import com.jwipc.sys.client.dto.MaterialOriginDTO;
import com.jwipc.sys.client.dto.ProductInfoDTO;
import com.jwipc.sys.entity.MaterialOrigin;
import com.jwipc.sys.service.impl.MaterialOriginServiceImpl;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

import static com.jwipc.supplier.constant.SequenceConst.SUPPLIER_AVL_CODE;


/**
 * <p> </p>
 *
 * @author dengjsh
 * @version 1.0
 * @since JDK 1.8
 */
@Service
@RequiredArgsConstructor
@Slf4j
public class SupplierAvlLogicImpl implements SupplierAvlLogic {

    private final SupplierAvlConvert supplierAvlConvert;
    private final ISupplierAvlService supplierAvlService;
    private final IAvlItemService aAvlItemService;
    private final SequenceClient sequenceClient;
    private final SupplierMesClient supplierMesClient;
    private final ProductClient productClient;
    private final DictClient dictClient;
    private final ISupplierService supplierService;
    private final MaterialOriginServiceImpl materialOriginServiceImpl;

    private List<MaterialOrigin> materialOriginList;

    private static final String SPECIAL_CHARS_mpn = "[`~!@$^|{};<>！@￥……|{}【】；”“。、]";
    private static final String SPECIAL_CHARS_en = "[`!@#$%^&*()+=|{}':;',\\[\\]<>?！@#￥%……&*（）+|{}【】‘；：”“’。，、？]";
    Pattern pattern = Pattern.compile(SPECIAL_CHARS_en);
    Pattern patternmpn = Pattern.compile(SPECIAL_CHARS_mpn);
    String regex = "/";

    @Override
    public PageView getList(SupplierAvlQuery query) {

        final Page<SupplierAvlSelectPO> page = PageUtil.toPage(query);
        if (LoginUtil.isSupplier()) {
            query.setSupplierId(LoginUtil.getSupplierId());
        }
        //判断当前的供应商是否有特殊角色编码
        final List<String> roleCodes = LoginUtil.getRoleCodes();
        if (roleCodes.contains(DictCode.SUPPLIER_SPECIAL_ROLE)) {
            if (StrUtil.isEmpty(query.getMaterialNameOrCode())) {
                return PageUtil.getPV(new ArrayList<>(), page.getTotal());
            }
        }
        query.setFactoryCode("1000");
        initOrderQuery(query);
        if (StringUtils.isNotEmpty(query.getMaterialNameOrCode())) {
            query.setMaterialNameOrCode(query.getMaterialNameOrCode().trim());
        }
        if (StringUtils.isNotEmpty(query.getMaterialNameOrCode()) && query.getMaterialNameOrCode().indexOf(" ") > 0) {
            query.setMaterialNameOrCode(query.getMaterialNameOrCode().replaceAll(" ", "|"));
        }
        if (StringUtils.isNotEmpty(query.getMaterialNameOrCode()) && query.getMaterialNameOrCode().indexOf(",") > 0) {
            query.setMaterialNameOrCode(query.getMaterialNameOrCode().replace(",", "|"));
        }

        List<SupplierAvlSelectPO> selecctList = supplierAvlService.getListForSelect(page, query);
        List<SupplierAvlBaseDTO> supplierMaterialDemoBaseDTOS = supplierAvlConvert.entities2SelectDtos(
                selecctList);
        supplierMaterialDemoBaseDTOS.stream().forEach(item ->{
            item.setSynToMes(item.getSynToMes().equals("0")?"否":"是");
        });
        return PageUtil.getPV(supplierMaterialDemoBaseDTOS, page.getTotal());
    }

    private void initOrderQuery(SupplierAvlQuery query) {
        //排序
        if (StringUtils.isEmpty(query.getSort())) {
            query.setAsc("DESC");
            query.setOrderByName("create_time");
        } else {
            query.setAsc("DESC");
            if (query.getOrder().equals("asc")) {
                query.setAsc("asc");
            }
            if (query.getSort().equals("supplierCode")) {
                query.setOrderByName("supplier_code");
            } else if (query.getSort().equals("materialCode")) {
                query.setOrderByName("material_code");
            } else if (query.getSort().equals("supplierName")) {
                query.setOrderByName("supplier_name");
            } else if (query.getSort().equals("materialName")) {
                query.setOrderByName("material_name");
            } else if (query.getSort().equals("productName")) {
                query.setOrderByName("product_name");
            } else if (query.getSort().equals("productNameEn")) {
                query.setOrderByName("product_name_en");
            } else if (query.getSort().equals("countryName")) {
                query.setOrderByName("country_name");
            } else if (query.getSort().equals("mpn")) {
                query.setOrderByName("mpn");
            } else if (query.getSort().equals("msl")) {
                query.setOrderByName("msl");
            } else if (query.getSort().equals("mslName")) {
                query.setOrderByName("msl_name");
            } else if (query.getSort().equals("eccn")) {
                query.setOrderByName("eccn");
            } else if (query.getSort().equals("moq")) {
                query.setOrderByName("moq");
            } else if (query.getSort().equals("mpq")) {
                query.setOrderByName("mpq");
            } else if (query.getSort().equals("cif")) {
                query.setOrderByName("cif");
            } else if (query.getSort().equals("synToMes")) {
                query.setOrderByName("syn_to_mes");
            } else if (query.getSort().equals("createTime")) {
                query.setOrderByName("create_time");
            } else if (query.getSort().equals("materialPurchaseGroup")) {
                query.setOrderByName("material_purchase_group");
            } else {
                query.setAsc("DESC");
                query.setOrderByName("create_time");
            }
        }
    }

    private LambdaQueryWrapper<SupplierAvl> getQueryWrapper(SupplierAvlQuery query) {

//        LambdaQueryWrapper<SupplierAvl> userWrapper = Wrappers.<SupplierAvl>lambdaQuery();
//
//
//        LambdaQueryWrapper<Order> orderWrapper = Wrappers.<Order>lambdaQuery();


        final LambdaQueryWrapper<SupplierAvl> queryWrapper =
                new LambdaQueryWrapper<SupplierAvl>().like(
                                StrUtil.isNotEmpty(query.getCode()), SupplierAvl::getCode,
                                SqlUtils.concatLike(query.getCode(), SqlLike.DEFAULT))
                        .and(StrUtil.isNotEmpty(query.getSupplierlNameOrCode()),
                                a -> a.like(SupplierAvl::getSupplierCode,
                                                SqlUtils.concatLike(query.getSupplierlNameOrCode(), SqlLike.DEFAULT)).or()
                                        .like(SupplierAvl::getSupplierName,
                                                SqlUtils.concatLike(query.getSupplierlNameOrCode(), SqlLike.DEFAULT)))
                        .and(StrUtil.isNotEmpty(query.getMaterialNameOrCode()),
                                a -> a.like(SupplierAvl::getMaterialName,
                                                SqlUtils.concatLike(query.getMaterialNameOrCode(), SqlLike.DEFAULT)).or()
                                        .like(SupplierAvl::getMaterialCode,
                                                SqlUtils.concatLike(query.getMaterialNameOrCode(), SqlLike.DEFAULT)))
                        .like(StrUtil.isNotEmpty(query.getProductName()), SupplierAvl::getProductName, query.getProductName())
                        .like(StrUtil.isNotEmpty(query.getProductNameEn()), SupplierAvl::getProductNameEn, query.getProductNameEn())
                        .eq(StrUtil.isNotEmpty(query.getCountryCode()), SupplierAvl::getCountryCode, query.getCountryCode())
                        .ge(StrUtil.isNotEmpty(query.getStartTime()), SupplierAvl::getCreateTime, query.getStartTime())
                        .le(StrUtil.isNotEmpty(query.getEndTime()), SupplierAvl::getCreateTime, query.getEndTime())
                        .eq(Objects.nonNull(query.getSupplierId()), SupplierAvl::getSupplierId, query.getSupplierId())
                        .like(Objects.nonNull(query.getMpn()), SupplierAvl::getMpn, query.getMpn());

        //排序
        if (StringUtils.isEmpty(query.getSort())) {
            queryWrapper.orderBy(true, false, SupplierAvl::getCreateTime);
        } else {
            if (query.getSort().equals("supplierCode")) {
                queryWrapper.orderBy(true, query.getOrder().equals("asc"), SupplierAvl::getSupplierCode);
            } else if (query.getSort().equals("materialCode")) {
                queryWrapper.orderBy(true, query.getOrder().equals("asc"), SupplierAvl::getMaterialCode);
            } else if (query.getSort().equals("supplierName")) {
                queryWrapper.orderBy(true, query.getOrder().equals("asc"), SupplierAvl::getSupplierName);
            } else if (query.getSort().equals("materialName")) {
                queryWrapper.orderBy(true, query.getOrder().equals("asc"), SupplierAvl::getMaterialName);
            } else if (query.getSort().equals("productName")) {
                queryWrapper.orderBy(true, query.getOrder().equals("asc"), SupplierAvl::getProductName);
            } else if (query.getSort().equals("productNameEn")) {
                queryWrapper.orderBy(true, query.getOrder().equals("asc"), SupplierAvl::getProductNameEn);
            } else if (query.getSort().equals("countryName")) {
                queryWrapper.orderBy(true, query.getOrder().equals("asc"), SupplierAvl::getCountryName);
            } else if (query.getSort().equals("mpn")) {
                queryWrapper.orderBy(true, query.getOrder().equals("asc"), SupplierAvl::getMpn);
            } else if (query.getSort().equals("msl")) {
                queryWrapper.orderBy(true, query.getOrder().equals("asc"), SupplierAvl::getMsl);
            } else if (query.getSort().equals("mslName")) {
                queryWrapper.orderBy(true, query.getOrder().equals("asc"), SupplierAvl::getMslName);
            } else if (query.getSort().equals("eccn")) {
                queryWrapper.orderBy(true, query.getOrder().equals("asc"), SupplierAvl::getEccn);
            } else if (query.getSort().equals("moq")) {
                queryWrapper.orderBy(true, query.getOrder().equals("asc"), SupplierAvl::getMoq);
            } else if (query.getSort().equals("mpq")) {
                queryWrapper.orderBy(true, query.getOrder().equals("asc"), SupplierAvl::getMpq);
            } else if (query.getSort().equals("cif")) {
                queryWrapper.orderBy(true, query.getOrder().equals("asc"), SupplierAvl::getCif);
            } else if (query.getSort().equals("synToMes")) {
                queryWrapper.orderBy(true, query.getOrder().equals("asc"), SupplierAvl::getSynToMes);
            } else if (query.getSort().equals("createTime")) {
                queryWrapper.orderBy(true, query.getOrder().equals("asc"), SupplierAvl::getCreateTime);
            }
        }
        return queryWrapper;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void saveOrUpdate(SupplierAvlSaveDTO saveDTO) {
        SupplierAvl supplierAvl = supplierAvlConvert.dto2Entity(saveDTO);
        if(StringUtils.isNotEmpty(saveDTO.getMpn())){//mpn
            supplierAvl.setMpn(saveDTO.getMpn().toUpperCase());
            supplierAvl.setMpn(supplierAvl.getMpn().replace("/", " "));
        }
        if(StringUtils.isNotEmpty(saveDTO.getProductNameEn())){//制造商英文
            supplierAvl.setProductNameEn(saveDTO.getProductNameEn().toUpperCase());
            supplierAvl.setProductNameEn(supplierAvl.getProductNameEn().replace("/", " "));
        }
        //如果avl清单id不存在，则生成清单号
        if (ObjectUtil.isNull(supplierAvl.getId())) {
            final String code = sequenceClient.getCodeSequenceNo(SUPPLIER_AVL_CODE.getCode(), 6);
            supplierAvl.setCode(code);
            supplierAvl.setCreateId(LoginUtil.getUserId());
            supplierAvl.setCreateTime(LocalDateTime.now());
        } else {
            supplierAvl.setUpdateId(LoginUtil.getUserId());
            supplierAvl.setUpdateTime(LocalDateTime.now());
        }
        supplierAvl.setDeleteFlag(0);
        //如果MSL(湿敏等级) 不为空
        if (StringUtils.isNotEmpty(saveDTO.getMsl())) {
            List<DictDTO> dictList = dictClient.getDicByType(DictCode.MSL_LEVEL.getCode());
            dictList.stream().forEach(item -> {
                if (item.getCode().equals(supplierAvl.getMsl())) {
                    supplierAvl.setMslName(item.getName());
                }
            });
        }
        //如果国系不为空
        if (StringUtils.isNotEmpty(saveDTO.getCountryCode())) {
            List<DictDTO> dictList = dictClient.getDicByType(DictCode.COUNTRY_SERIES.getCode());
            dictList.stream().forEach(item -> {
                if (item.getCode().equals(supplierAvl.getCountryCode())) {
                    supplierAvl.setCountryName(item.getName());
                }
            });
        }

        Matcher matcher = pattern.matcher(saveDTO.getProductNameEn());
        boolean containsSpecialChar = matcher.find();
        //制造商英文名不能包含特殊字符
        if (containsSpecialChar) {
            throw new DaoException("制造商英文简称不能包含特殊字符!");
        }

        Matcher matcher1 = patternmpn.matcher(saveDTO.getMpn());
        boolean containsSpecialChar1 = matcher1.find();
        //MPN不能包含特殊字符
        if (containsSpecialChar1) {
            throw new DaoException("制造商MPN(厂家型号)不能包含特殊字符!");
        }



        List<SupplierAvlBaseDTO> supplierAvlBaseDTOS = Lists.newArrayList();
        SupplierAvlBaseDTO supplierAvlBaseDTO = supplierAvlConvert.entity2Dto(supplierAvl);
        supplierAvlBaseDTOS.add(supplierAvlBaseDTO);
        //增加相同条件过滤检查 重复性检查，物料编码，供应商编码，生产商中英文
        if (checkSameAvl(supplierAvl)) {
            throw new DaoException("该供应商已经存在类似AVL清单");
        }
        //“物料编码+ MPN型号”这两栏相同时，MSL 只能 显示一种
//        if (checkMslAvl(supplierAvl)) {
//            throw new DaoException("物料编码+MPN型号相同的AVL，已存在一样的MSL");
//        }
        //实时推送至MES系统
        if (pushToMes(supplierAvlBaseDTOS)) {
            supplierAvl.setSynToMes(1);
        } else {
            supplierAvl.setSynToMes(0);
        }
        supplierAvlService.saveOrUpdate(supplierAvl);
    }

    /**
     * 调用MES接口，实时推送供应商AVL清单数据
     *
     * @param supplierAvlBaseDTOS
     * @throws DaoException
     */
    private boolean pushToMes(List<SupplierAvlBaseDTO> supplierAvlBaseDTOS) throws DaoException {
        //需要对分组的数据处理
        final SupplierAvlToMesDTO supplierAvlToMesDTO = new SupplierAvlToMesDTO();
        final SupplierAvlToMesDTO.ItData itData = new SupplierAvlToMesDTO.ItData();
        itData.item = Lists.newArrayList();
        //循环avl清单对象
        for (SupplierAvlBaseDTO saveDTO : supplierAvlBaseDTOS) {
            final SupplierAvlToMesDTO.Item item = new SupplierAvlToMesDTO.Item();
            item.PartNo = saveDTO.getMaterialCode();
            item.State = saveDTO.getDeleteFlag() == 1 ? "X" : "";
            item.Vcode = saveDTO.getSupplierCode();
            //查物料类型和物料描述
            ProductInfoDTO productInfoDTO = productClient.getByMaterialCodeAndFactoryCode(saveDTO.getMaterialCode(),
                    "1000");
            if (Objects.nonNull(productInfoDTO)) {
                item.Description = productInfoDTO.getMaterialDesc();
                if (StringUtils.isNotEmpty(productInfoDTO.getMaterialCode())) {
                    DictDTO dictByTypePO = dictClient.getDictByTypeAndCode(DictCode.MATERIAL_TYPE.getCode(),
                            productInfoDTO.getMaterialCode());
                    if (Objects.nonNull(dictByTypePO)) {
                        item.MaterialType = dictByTypePO.getName();
                    }
                }
            }
            item.Vname = saveDTO.getSupplierName();
            item.MANU = saveDTO.getProductNameEn();
            item.MPN = saveDTO.getMpn();
            item.MSL = saveDTO.getMslName();
            item.id = String.valueOf(saveDTO.getId());
            itData.item.add(item);
        }
        supplierAvlToMesDTO.setIT_DATA(itData);
        log.info("{}", JSON.toJSONString(supplierAvlToMesDTO));
        final ApiResponse o = supplierMesClient.updateSupplierAVL(supplierAvlToMesDTO);
        if (!o.getCode().equals("200")) {
            throw new DaoException(o.getMsg());
        }
        return true;
    }

    /**
     *
     * @param supplierAvl
     * @return
     */
    private boolean checkSameAvl (SupplierAvl supplierAvl) {
        List<SupplierAvl> supplierAvls = supplierAvlService.list(
                new LambdaQueryWrapper<SupplierAvl>().eq(SupplierAvl::getSupplierCode, supplierAvl.getSupplierCode())
                        .eq(SupplierAvl::getMaterialCode, supplierAvl.getMaterialCode())
                        .eq(SupplierAvl::getProductNameEn, supplierAvl.getProductNameEn())
                        .eq(SupplierAvl::getMpn, supplierAvl.getMpn()));
//                        .eq(SupplierAvl::getProductName, supplierAvl.getProductName()));
        //如果根据以上参数没有查出对应的alv清单
        if (CollectionUtils.isEmpty(supplierAvls) || supplierAvls.size() == 0) {
            return false;
        //如果查出两个以上的avl清单
        } else if (supplierAvls.size() >= 2) {
            return true;
        //如果是新增，证明数据库已经存在该avl清单
        } else if (null == supplierAvl.getId()) {
            return true;
        } else {
            //如果数据库查出该avl清单，且id相同，证明是修改。
            if (supplierAvl.getId().equals(supplierAvls.get(0).getId())) {
                return false;
            //否则不是同一个avl清单，查出的avl清单，是另外一个不相同的avl清单，不允许修改
            } else {
                return true;
            }
        }
    }

    private boolean checkMslAvl (SupplierAvl supplierAvl) {
        List<SupplierAvl> supplierAvls = supplierAvlService.list(
                new LambdaQueryWrapper<SupplierAvl>()
                        .eq(SupplierAvl::getMaterialCode, supplierAvl.getMaterialCode())
                        .eq(SupplierAvl::getMpn, supplierAvl.getMpn())
                        .eq(SupplierAvl::getMsl, supplierAvl.getMsl()));
        //如果根据以上参数没有查出对应的alv清单
        if (CollectionUtils.isEmpty(supplierAvls) || supplierAvls.size() == 0) {
            return false;
            //如果查出两个以上的avl清单
        } else if (supplierAvls.size() >= 2) {
            return true;
            //如果是新增，证明数据库已经存在该avl清单
        } else if (null == supplierAvl.getId()) {
            return true;
        } else {
            //如果数据库查出该avl清单，且id相同，证明是修改。
            if (supplierAvl.getId().equals(supplierAvls.get(0).getId())) {
                return false;
                //否则不是同一个avl清单，查出的avl清单，是另外一个不相同的avl清单，不允许修改
            } else {
                return true;
            }
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void remove(List<String> idList) {
        List<SupplierAvlBaseDTO> supplierAvlBaseDTOS = Lists.newArrayList();
        for (String id : idList) {
            SupplierAvl supplierAvl = supplierAvlService.getById(id);
            SupplierAvlBaseDTO supplierAvlBaseDTO = supplierAvlConvert.entity2Dto(supplierAvl);
            supplierAvlBaseDTO.setDeleteFlag(1);
            supplierAvlBaseDTOS.add(supplierAvlBaseDTO);
        }
        supplierAvlService.removeBatchByIds(idList);
        //实时同步到MES系统
        pushToMes(supplierAvlBaseDTOS);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void pushAvlToMes(List<String> idList) {
        List<SupplierAvlBaseDTO> supplierAvlBaseDTOS = Lists.newArrayList();
        List<SupplierAvl> supplierAvlList =  new ArrayList<>();
        int i = 0;
        for (String id : idList) {
            i ++;
            SupplierAvl supplierAvl = supplierAvlService.getById(id);
            //如果已经同步，可以在次同步。
            if (null != supplierAvl.getSynToMes() && supplierAvl.getSynToMes() == 1) {
//                continue;
                //throw new DaoException("第" + i + "条AVL清单记录已经同步成功");
            }
            supplierAvl.setSynToMes(1);
            supplierAvlList.add(supplierAvl);
            SupplierAvlBaseDTO supplierAvlBaseDTO = supplierAvlConvert.entity2Dto(supplierAvl);
            supplierAvlBaseDTOS.add(supplierAvlBaseDTO);
        }
        //同步到MES系统
        pushToMes(supplierAvlBaseDTOS);
        supplierAvlService.saveOrUpdateBatch(supplierAvlList);
    }

    @Override
    public SupplierAvlBaseDTO getDetail(Long id) {
        final SupplierAvl supplierAvl = supplierAvlService.getById(id);
        if (Objects.nonNull(supplierAvl)) {
            return supplierAvlConvert.entity2Dto(supplierAvl);
        }
        SupplierAvlBaseDTO supplierAvlBaseDTO = new SupplierAvlBaseDTO();
        return supplierAvlBaseDTO;
    }

    @Override
    public List<SupplierAvlBaseDTO> listAll(SupplierAvlQuery supplierAvlQuery) {
        if (LoginUtil.isSupplier()) {
            supplierAvlQuery.setSupplierId(LoginUtil.getSupplierId());
        }
        //判断当前的供应商是否有特殊角色编码
        final List<String> roleCodes = LoginUtil.getRoleCodes();
        if (roleCodes.contains(DictCode.SUPPLIER_SPECIAL_ROLE)) {
            if (StrUtil.isEmpty(supplierAvlQuery.getMaterialNameOrCode())) {
                return new ArrayList<>();
            }
        }
        supplierAvlQuery.setFactoryCode("1000");
        initOrderQuery(supplierAvlQuery);
        List<SupplierAvlSelectPO> selecctList = supplierAvlService.getExportList(supplierAvlQuery);
        List<SupplierAvlBaseDTO> supplierMaterialDemoBaseDTOS = supplierAvlConvert.entities2SelectDtos(
                selecctList);
        return supplierMaterialDemoBaseDTOS;
    }

    /**
     * excel导入供应商AVL清单数据
     *
     * @param fileId
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void avlImportData(MultipartFile fileId) {
        List<SupplierAvlExportDTO> supplierAvlExportDTOS = ListUtils.newArrayList();
        List<DictDTO> dictList = dictClient.getDicByType(DictCode.MSL_LEVEL.getCode());
        List<DictDTO> countriesList = dictClient.getDicByType(DictCode.COUNTRY_SERIES.getCode());

        List<SupplierAvlBaseDTO> supplierAvlBaseDTOS = Lists.newArrayList();

        List<Supplier> supplierList = supplierService.list();
        String code = sequenceClient.getCodeSequenceNo(SUPPLIER_AVL_CODE.getCode(), 6);

        if(CollectionUtils.isEmpty(materialOriginList)){
            materialOriginList = materialOriginServiceImpl.list();
        }
        List<String> materiaList = materialOriginList.stream().map(MaterialOrigin::getMaterialCode).collect(Collectors.toList());


//        List<SupplierAvl> supplierAvls = supplierAvlService.list();

        StringBuilder errMsgSb = new StringBuilder();
        try {
            final int[] i = {0};

            EasyExcel.read(fileId.getInputStream(), SupplierAvlExportDTO.class,
                    new ReadListener<SupplierAvlExportDTO>() {
                        @Override
                        public void invoke(SupplierAvlExportDTO data, AnalysisContext context) {
                            i[0] = i[0] + 1;
                            //供应商名称判断
                            if (Strings.isNullOrEmpty(data.getSupplierName())) {
                                errMsgSb.append("第").append(i[0]).append("行").append("供应商名称不能为空!\r\n");
                            }
                            //供应商编码判断
                            if (Strings.isNullOrEmpty(data.getSupplierCode())) {
                                errMsgSb.append("第").append(i[0]).append("行").append("供应商代码不能为空!\r\n");
                            }
                            //物料编码判断
                            if (Strings.isNullOrEmpty(data.getMaterialCode())) {
                                errMsgSb.append("第").append(i[0]).append("行").append("物料编码不能为空!\r\n");
                            }
                            //物料名称判断
                            if (Strings.isNullOrEmpty(data.getMaterialName())) {
                                errMsgSb.append("第").append(i[0]).append("行").append("物料名称不能为空!\r\n");
                            }
                            //制造商中文名称判断
//                            if (Strings.isNullOrEmpty(data.getProductName())) {
//                                errMsgSb.append("第").append(i[0]).append("行").append("制造商名称不能为空!\r\n");
//                            }
                            //制造商英文名判断
                            if (Strings.isNullOrEmpty(data.getProductNameEn())) {
                                errMsgSb.append("第").append(i[0]).append("行").append("制造商英文简称不能为空!\r\n");
                            } else {
                                Boolean flag = containsChineseUsingRegex(data.getProductNameEn());
                                //制造商英文名不能包含中文
                                if (flag) {
                                    errMsgSb.append("第").append(i[0]).append("行").append("制造商英文简称不能包含中文!\r\n");
                                }

                                Matcher matcher = pattern.matcher(data.getProductNameEn());
                                boolean containsSpecialChar = matcher.find();
                                //制造商英文名不能包含特殊字符
                                if (containsSpecialChar) {
                                    errMsgSb.append("第").append(i[0]).append("行").append("制造商英文简称不能包含特殊字符!\r\n");
                                }
                            }
                            //MPN不能为空
                            if (Strings.isNullOrEmpty(data.getMpn())) {
                                errMsgSb.append("第").append(i[0]).append("行")
                                        .append("制造商MPN(厂家型号)不能为空!\r\n");
                            } else {
                                boolean flag = containsChineseUsingRegex(data.getMpn());
                                //MPN不能包含中文
                                if (flag) {
                                    errMsgSb.append("第").append(i[0]).append("行").append("制造商MPN(厂家型号)不能包含中文!\r\n");
                                }

                                Matcher matcher1 = patternmpn.matcher(data.getMpn());
                                boolean containsSpecialChar = matcher1.find();
                                //MPN不能包含特殊字符
                                if (containsSpecialChar) {
                                    errMsgSb.append("第").append(i[0]).append("行").append("制造商MPN(厂家型号)不能包含特殊字符!\r\n");
                                }
                                if(materiaList.contains(data.getMaterialCode())){
                                    //检验料号
                                    Pattern pattern = Pattern.compile(regex);

                                    // 创建匹配器对象
                                    Matcher matcher = pattern.matcher(data.getMpn());

                                    // 检查是否匹配
                                    if (matcher.find()) {
                                        errMsgSb.append("第").append(i[0]).append("行").append("制造商MPN(厂家型号)不能填写/字符!\r\n");
                                    }
                                }
                            }
                            //国系不能为空
                            if (Strings.isNullOrEmpty(data.getCountryName())) {
//                                errMsgSb.append("第").append(i[0]).append("行").append("请选择国系!\r\n");
                            } else {
                                if (data.getCountryName().equals("美国")) {
                                    //如果为美男 ，则Eccn不能为空
                                    if (Strings.isNullOrEmpty(data.getEccn())) {
//                                        errMsgSb.append("第").append(i[0]).append("行").append("请输入ECCN!\r\n");
                                    }
                                }
                            }
                            //msl湿敏等级不能为空
                            if (Strings.isNullOrEmpty(data.getMsl())) {
                                errMsgSb.append("第").append(i[0]).append("行").append("请选择湿敏等级!\r\n");
                            }

                            //MOQ为空判断
                            if (Strings.isNullOrEmpty(data.getMoq())) {
//                                errMsgSb.append("第").append(i[0]).append("行").append("请输入MOQ!\r\n");
                            } else {
                                boolean hasDigit = data.getMoq().matches("\\d+");
                                //MOQ不能为空且只能为数字
                                if (!hasDigit) {
//                                    errMsgSb.append("第").append(i[0]).append("行").append("MOQ只能输入数字，请重新输入!\r\n");
                                }
                            }

                            if (Strings.isNullOrEmpty(data.getMpq())) {
//                                errMsgSb.append("第").append(i[0]).append("行").append("请输入MPQ!\r\n");
                            } else {
                                //MPQ不能为空且只能为数字
                                boolean hasDigit = data.getMpq().matches("\\d+");
                                if (!hasDigit) {
//                                    errMsgSb.append("第").append(i[0]).append("行").append("MPQ只能输入数字，请重新输入!\r\n");
                                }
                            }
                            if (Strings.isNullOrEmpty(data.getCif())) {
//                                errMsgSb.append("第").append(i[0]).append("行").append("请输入货期(P/L)!\r\n");
                            } else {
                                //货期(P/L)不能为空，且只能为数字
                                boolean hasDigit = data.getCif().matches("\\d+");
                                if (!hasDigit) {
//                                    errMsgSb.append("第").append(i[0]).append("行").append("货期(P/L)只能输入数字，请重新输入!\r\n");
                                }
                            }

                            //excel表本身重复性校验，物料，供应商，制造商中文，制造商英文不能同时相同。
                            if (i[0] > 1) {
                                for (int j = 0; j < supplierAvlExportDTOS.size(); j++) {
                                    SupplierAvlExportDTO tempDTO = supplierAvlExportDTOS.get(j);
                                    if (tempDTO.getSupplierCode().equals(data.getSupplierCode()) &&
                                            tempDTO.getMaterialCode().equals(data.getMaterialCode()) &&
//                                            tempDTO.getProductName().equals(data.getProductName()) &&
                                            tempDTO.getMpn().equals(data.getMpn()) &&
                                            tempDTO.getProductNameEn().equals(data.getProductNameEn())
                                    ) {
                                        errMsgSb.append("第").append(j + 1).append("行与第").append(i[0])
                                                .append("行数据重复,请检查!\r\n");
                                        break;
                                    }
                                }
                            }
//                            String code = sequenceClient.createSequenceNo(SUPPLIER_AVL_CODE.getCode());
                            data.setCode(code);
                            supplierAvlExportDTOS.add(data);
                        }

                        @Override
                        public void doAfterAllAnalysed(AnalysisContext analysisContext) {
                        }
                    }).sheet().doRead();
            //判断导入的错误信息是否为空
            if (StringUtils.isNotEmpty(errMsgSb.toString())) {
                throw new DaoException(errMsgSb.toString());
            }
            //重复性校验, 数据库校验, 供应商code + 物料code +  制度商中文名 + mpn编号 数据库不能重复
            supplierAvlExportDTOS.stream().forEach(item -> {
                //数据库查询
                final List<SupplierAvl> supplierAvls = supplierAvlService.list(
                        new LambdaQueryWrapper<SupplierAvl>().eq(SupplierAvl::getSupplierCode, item.getSupplierCode())
                                .eq(SupplierAvl::getMaterialCode, item.getMaterialCode())
                                .eq(SupplierAvl::getProductNameEn, item.getProductNameEn())
//                                .eq(SupplierAvl::getProductName, item.getProductName()));
                                .eq(SupplierAvl::getMpn, item.getMpn()));
                if (CollectionUtils.isNotEmpty(supplierAvls)) {//作覆盖处理
//                    errMsgSb.append("供应商：").append(item.getSupplierName()).append(",物料号：").append(item.getMaterialName())
//                            .append(", 制造商:").append(item.getProductName())
//                            .append(",制造商简称：").append(item.getProductNameEn()).append(" AVL清单已存在,请检查!\r\n");
                    item.setId(supplierAvls.get(0).getId());
                }
                //相同性校验
//                for (SupplierAvl supplierAvl : supplierAvls) {
//                    if (item.getMaterialCode().equals(supplierAvl.getMaterialCode()) && item.getSupplierCode().equals(supplierAvl.getSupplierCode()) &&
//                     item.getProductNameEn().equals(supplierAvl.getProductNameEn()) && item.getMpn().equals(supplierAvl.getMpn())) {
//                        item.setId(supplierAvl.getId());
//                        break;
//                    }
//                }

            });
            //判断导入的错误信息是否为空
            if (StringUtils.isNotEmpty(errMsgSb.toString())) {
                throw new DaoException(errMsgSb.toString());
            }
        } catch (IOException e) {
            throw new RuntimeException(e.getMessage());
        }
        List<SupplierAvl> supplierAvlList = supplierAvlConvert.importDTOs2Entites(supplierAvlExportDTOS);
        supplierAvlList.stream().forEach(item -> {
            //设置供应商ID,并检查供应商是否存在
//            final Supplier supplier = supplierService.getOne(
//                    new LambdaQueryWrapper<Supplier>().eq(Supplier::getSupplierCode, item.getSupplierCode()));
//            if (Objects.nonNull(supplier)) {
//                item.setSupplierId(supplier.getId());
//            } else {
//                errMsgSb.append("供应商:").append(item.getSupplierName()).append("数据库不存在,请检查!\n\r");
//            }
            boolean ff = false;
            for (Supplier supplier : supplierList) {
                if (supplier.getSupplierCode().equals(item.getSupplierCode())) {
                    item.setSupplierId(supplier.getId());
                    ff = true;
                    break;
                }
            }
            if (!ff) {
                errMsgSb.append("供应商:").append(item.getSupplierName()).append("数据库不存在,请检查!\n\r");
            }
            //判断导入的错误信息是否为空
            if (StringUtils.isNotEmpty(errMsgSb.toString())) {
                throw new DaoException(errMsgSb.toString());
            }

            if (StringUtils.isNotEmpty(item.getMsl())) {
                dictList.stream().forEach(o -> {
                    if (o.getName().equals(item.getMsl())) {
                        item.setMsl(o.getCode());
                        item.setMslName(o.getName());
                    }
                });
            }

            if (StringUtils.isNotEmpty(item.getCountryName())) {
                countriesList.stream().forEach(o -> {
                    if (o.getName().equals(item.getCountryName())) {
                        item.setCountryCode(o.getCode());
                        item.setCountryName(o.getName());
                    }
                });
            }
            if (null != item.getId() && item.getId() > 0) {
                item.setUpdateId(LoginUtil.getUserId());
                item.setUpdateTime(LocalDateTime.now());
            } else {
                item.setCreateId(LoginUtil.getUserId());
                item.setCreateTime(LocalDateTime.now());
            }
            item.setSynToMes(1);
            item.setDeleteFlag(0);
            if(StringUtils.isNotEmpty(item.getMpn())){
                item.setMpn(item.getMpn().toUpperCase());
                item.setMpn(item.getMpn().replace("/", " "));
            }
            if(StringUtils.isNotEmpty(item.getProductNameEn())){
                item.setProductNameEn(item.getProductNameEn().toUpperCase());
                item.setProductNameEn(item.getProductNameEn().replace("/", " "));
            }
            SupplierAvlBaseDTO supplierAvlBaseDTO = supplierAvlConvert.entity2Dto(item);
            supplierAvlBaseDTOS.add(supplierAvlBaseDTO);

        });
        //判断导入的错误信息是否为空
        if (StringUtils.isNotEmpty(errMsgSb.toString())) {
            throw new DaoException(errMsgSb.toString());
        }
        //同步至MES
        boolean flag = pushToMes(supplierAvlBaseDTOS);
        if (flag) {
            supplierAvlService.saveOrUpdateBatch(supplierAvlList);
        }

    }

    @Override
    public List<SupplierAvlBaseDTO> getMPN(String supplierCode, String materialCode, String manufacturer) {
        final LambdaQueryWrapper<SupplierAvl> queryWrapper = new LambdaQueryWrapper<SupplierAvl>()
                .eq(SupplierAvl::getSupplierCode, supplierCode)
                .eq(StrUtil.isNotEmpty(manufacturer), SupplierAvl::getProductNameEn, manufacturer)
                .eq(SupplierAvl::getMaterialCode, materialCode);
        final List<SupplierAvl> list = supplierAvlService.list(queryWrapper);
        return supplierAvlConvert.entities2Dtos(list);
    }

    @Override
    public SupplierAvlItemBaseDTO getAvlItems(String materialCode) {
        final LambdaQueryWrapper<AvlItem> queryWrapper = new LambdaQueryWrapper<AvlItem>()
                .eq(AvlItem::getItemNumber, materialCode);
        final List<AvlItem> list = aAvlItemService.list(queryWrapper);
        SupplierAvlItemBaseDTO supplierAvlItemBaseDTO = new SupplierAvlItemBaseDTO();
        if (CollectionUtils.isNotEmpty(list)) {
            try {
                BeanUtils.copyProperties(supplierAvlItemBaseDTO, list.get(0));
                supplierAvlItemBaseDTO.setCif(String.valueOf(list.get(0).getLt()));
            } catch (IllegalAccessException e) {
            } catch (InvocationTargetException e) {
            }
        }
        return supplierAvlItemBaseDTO;
    }

    private static boolean containsChineseUsingRegex(String str) {
        String regex = "[\u4e00-\u9fa5]";
        Pattern pattern = Pattern.compile(regex);
        Matcher matcher = pattern.matcher(str);
        return matcher.find();
    }

}