package com.sw.mes.plan.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import com.sw.mes.base.system.service.DictionaryItemService;
import com.sw.mes.core.annotation.ServiceLogs;
import com.sw.mes.core.base.BaseServiceImpl;
import com.sw.mes.core.dto.erp.ErpOrderDto;
import com.sw.mes.core.entity.FbCheckOutData;
import com.sw.mes.core.enums.SectionIndexRangeEnum;
import com.sw.mes.core.response.Result;
import com.sw.mes.core.response.ResultGenerator;
import com.sw.mes.core.utils.DateUtil;
import com.sw.mes.core.utils.StringUtils;
import com.sw.mes.base.factory.product.entity.FbProductModel;
import com.sw.mes.base.factory.product.service.FbProductModelService;
import com.sw.mes.fb.checkout.service.FbCheckOutDataService;
import com.sw.mes.fb.turnstore.service.RecheckInspectReceiveDetailService;
import com.sw.mes.plan.dao.FbProductionOrderDao;
import com.sw.mes.plan.dto.MatchOrderInfo;
import com.sw.mes.plan.entity.FbProductionOrder;
import com.sw.mes.plan.service.FbProductionOrderService;
import com.sw.mes.third.entity.RequestLog;
import com.sw.mes.third.service.RequestLogService;
import com.sw.mes.third.service.SendWebService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import javax.transaction.Transactional;
import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @Author
 * @Description：
 * @Date: Create in
 * @Modified By:
 */
@Service
@Slf4j
@Transactional
public class FbProductionOrderServiceImpl extends BaseServiceImpl<FbProductionOrder> implements FbProductionOrderService {
    @Autowired
    private SendWebService sendWebService;

    @Autowired
    private FbProductModelService fbProductModelService;

    @Autowired
    private ApplicationContext applicationContext;

    @Autowired
    private RecheckInspectReceiveDetailService recheckInspectReceiveDetailService;

    @Autowired
    private FbCheckOutDataService fbCheckOutDataService;

    @Autowired
    private RequestLogService requestLogService;

    @Autowired
    private DictionaryItemService dictionaryItemService;

    FbProductionOrderDao dao;

    @Autowired
    public void setDao(FbProductionOrderDao dao) {
        super.setBaseDao(dao);
        this.dao = dao;
    }

    @Override
    public void close(FbProductionOrder sapProductionOrder) {
        dao.save(sapProductionOrder);
        //下发关闭订单至wms
//        SendFinshOrderDto sendFinshOrderDto = new SendFinshOrderDto();
//        sendFinshOrderDto.setOrderNo(sapProductionOrder.getAufnr());
//        sendFinshOrderDto.setTime(new Date());
//        applicationContext.publishEvent(new FinshOrderEvent(this, sendFinshOrderDto));
        //向SAP发送订单关闭信息
//        try {
//            List<Teco> list = new ArrayList<>();
//            Teco teco = new Teco();
//            teco.setZMESID(UUID.randomUUID().toString());
//            teco.setWERKS("1011");
//            teco.setSTATUS("1");
//            teco.setCOMMENT("");
//            teco.setAUART(sapProductionOrder.getAuart());
//            teco.setAUFNR(sapProductionOrder.getAufnr());
//            teco.setMATNR(sapProductionOrder.getMatnr());
//            teco.setISSUEDATE(WbServiceUtils.getSapDate(new Date()));//日期 yyyymmdd
//            teco.setISSUETIME(WbServiceUtils.getSapTime(new Date()));//时间 HHmmss
//            list.add(teco);
//            Map map = sendWebService.mesToSap(list, WebServiceUri.WSDL_URL, WebServiceApiName.TECO, 4000);
//            String sapResult = map.get(new QName("ZTYPE")).toString();
//            if (!sapResult.equals("S")) {
//                String sapError = map.get(new QName("ZMESSAGE")).toString();
//                throw new RuntimeException("向SAP发送订单关闭信息异常:" + sapError);
//            }
//        } catch (Exception e) {
//            log.error("向SAP发送订单关闭信息异常:" + e.getMessage());
//            throw new RuntimeException("向SAP发送订单关闭信息异常:" + e.getMessage());
//        }
    }

    @Override
    public FbProductionOrder findByAufnr(String code) {
        return dao.findByAufnr(code);
    }

    @Override
    public MatchOrderInfo matchOrder(String sn, String grade, String specifications, String conductiveType, String dopant, Integer sticksCount,
                                     BigDecimal wareHouseLength, String orderType, String checkoutName, String productLevelFb, String sectionType, String sideLengthRange) {
        FbProductModel fbProductModel = matchOrderProductModel(sn, grade, specifications, conductiveType, dopant, productLevelFb, sectionType, null);
        return getMatchOrderInfo(checkoutName, orderType, fbProductModel, sideLengthRange);
    }

    @Override
    @ServiceLogs(description = "方棒匹配报工料号")
    public FbProductModel matchOrderProductModel(String sn, String grade, String specifications, String conductiveType, String dopant, String productLevelFb, String sectionType, String sideLengthRange) {
//        String[] specificationsArr = specifications.split("\\*");
//        String specifications1 = null;
//        BigDecimal specifications2 = null;
//        if (specificationsArr.length > 0) {
//            specifications1 = specificationsArr[0];
//        }
//        if (specificationsArr.length > 1) {
//            specifications2 = NumberUtil.Object2BigDecimal(specificationsArr[1]);
//        }
        FbProductModel fbProductModel;
        /**
         *@param grade 等级
         *@param conductiveType 导电类型
         *@param dopant 掺杂剂
         *@param specifications 规格
         *@param sideLength 边长
         */
        FbCheckOutData dataByFbSectionNo = fbCheckOutDataService.findDataByFbSectionNo(sn);
        String productType = "%" + dataByFbSectionNo.getProductType() + "%";
        String productTypeName = "%" + "代加工" + "%";
        List<FbProductModel> fbProductModels = null;
        if (sn.startsWith("B")) {
            //代工
            fbProductModels = fbProductModelService.findByFbProductModelLikeNameNotRemark(grade, specifications, conductiveType, dopant, productType, productTypeName, sideLengthRange);
        } else {
            fbProductModels = fbProductModelService.findByFbProductModelNotLikeNameNotRemark(grade, specifications, conductiveType, dopant, productType, productTypeName, sideLengthRange);
        }
        // List<FbProductModel> fbProductModels = fbProductModelService.findByFbProductModelNotRemark(grade, specifications, conductiveType, dopant, productType);
        if (CollectionUtils.isEmpty(fbProductModels)) {
            throw new RuntimeException("未查询到符合条件的方棒产品模型：规格：" + specifications + "，导电型号：" + conductiveType + "，掺杂剂：" + dopant + "，产品类别：" + productType + "，评级：" + grade);
        }
        fbProductModel = fbProductModels.get(0);
        for (FbProductModel productModel : fbProductModels) {
            if (productModel.getProductType().equals(dataByFbSectionNo.getProductType())) {
                fbProductModel = productModel;
                break;
            }
        }
//        String fbProductModelRemark = "方-修%";
//        if (isFxFbProductMode(productLevelFb)) {
//            fbProductModel = fbProductModelService.findByFbProductModel(grade, specifications1, conductiveType, dopant, specifications2, fbProductModelRemark);
//        } else {
//            if (fbProductModel == null && !"标棒".equals(sectionType)) {
//                fbProductModel = fbProductModelService.findByFbProductModelNotRemark(grade, specifications1, conductiveType, dopant,  specifications2, fbProductModelRemark);
//            }
//        }
        return fbProductModel;
    }

    @Override
    @ServiceLogs(description = "方棒根据料号匹配报工订单")
    public MatchOrderInfo matchOrder(String sn, String productNo, String orderType) {
        if (StringUtils.isBlank(productNo)) {
            return new MatchOrderInfo();
        }
//        FbProductModel fbProductModel = fbProductModelService.findByProductNo(productNo);
        List<FbProductModel> fbProductModels = fbProductModelService.findByProductNo1(productNo);
        FbCheckOutData fbCheckOutData = fbCheckOutDataService.findDataByFbSectionNo(sn);
        String sideLengthRange = fbCheckOutData.getSideLengthRange();
        for (FbProductModel fbProductModel : fbProductModels) {
            MatchOrderInfo matchOrderInfo = getMatchOrderInfo(sn, orderType, fbProductModel, sideLengthRange);
            if (!StringUtils.isEmpty(matchOrderInfo.getOrderNo())) {
                return matchOrderInfo;
            }
        }
        return null;
    }

    /**
     * 根据方棒模型匹配订单
     *
     * @param sectionNo      检验类型
     * @param orderType      订单类型
     * @param fbProductModel 方棒模型
     * @return
     */
    @Override
    public MatchOrderInfo getMatchOrderInfo(String sectionNo, String orderType, FbProductModel fbProductModel, String sideLengthRange) {
        MatchOrderInfo matchOrderInfo = new MatchOrderInfo();
        if (fbProductModel != null && fbProductModel.getMaterialType() != null && fbProductModel.getMaterialType().getId() != null) {
            matchOrderInfo.setMaterialCode(fbProductModel.getProductNo());
            List<FbProductionOrder> productionOrders;
            String field2 = "SPREWORK";
            //是否要匹配带复检标识的订单
            boolean isSprework = recheckInspectReceiveDetailService.isSprework(sectionNo) > 0;

            String productType = sectionNo.substring(1, 2);
            String fromMark = sectionNo.substring(SectionIndexRangeEnum.基地追溯产品类型.getBeginIndex(), SectionIndexRangeEnum.基地追溯产品类型.getEndIndex());
            if (fromMark.matches("[A-Z]+")) {
                productType = sectionNo.substring(SectionIndexRangeEnum.产品类型.getBeginIndex(), SectionIndexRangeEnum.产品类型.getEndIndex());
            }
            //匹配复检订单
            if (isSprework) {
                productionOrders = dao.findByFbProductModelMaterialTypeId(fbProductModel.getMaterialType().getId(), productType, DateUtil.toDate(new Date(), DateUtil.longFormat));
            }
            //匹配非复检订单
            else {
                productionOrders = dao.findByFbProductModelMaterialTypeIdV2(fbProductModel.getMaterialType().getId(), productType, DateUtil.toDate(new Date(), DateUtil.longFormat));
            }
            if (productionOrders.size() > 0) {
                // 增加边长匹配方棒订单条件过滤
                productionOrders = productionOrders.stream().filter(oder -> oder.getSideLengthRange() != null && oder.getSideLengthRange().equals(sideLengthRange)).collect(Collectors.toList());
                if (CollectionUtil.isNotEmpty(productionOrders)) {
                    String aufnr = null;
                    String resistanceType = null;
                    for (FbProductionOrder fbProductionOrder : productionOrders) {
                        if (fbProductionOrder.getFbProductModel() != null && fbProductModel.getProductLevel().equals(fbProductionOrder.getFbProductModel().getProductLevel()) &&
                                fbProductModel.getProductNo().equals(fbProductionOrder.getMatnr())) {
                            aufnr = fbProductionOrder.getAufnr();
                            resistanceType = productionOrders.get(0).getResistanceType();
                        }
                    }
                    if (StringUtils.isBlank(aufnr)) {
                        aufnr = productionOrders.get(0).getAufnr();
                        resistanceType = productionOrders.get(0).getResistanceType();
                    }
                    matchOrderInfo.setOrderNo(aufnr);
                    matchOrderInfo.setResistanceType(resistanceType);
                }
            }
        }
        return matchOrderInfo;
    }

    @Override
    public List<FbProductionOrder> findByProductCodeAndTime(String matnr, Date gstrp, Date gltrp) {
        return dao.findByStatusAndProductCodeAndTime(true, matnr, gstrp, gltrp);
    }

    @Override
    public Result handleErpOrder(List<ErpOrderDto> fbErpOrderDto) {
        StringBuilder sb = new StringBuilder();
        List<String> fbOderNos = dictionaryItemService.findItemValueByThemeValue("ybToFbOderList", true);
        for (ErpOrderDto dto : fbErpOrderDto) {
            if (CollectionUtil.isNotEmpty(fbOderNos) && fbOderNos.contains(dto.getMocode())) {
                Integer status = dto.getStatus();
                FbProductionOrder oldOder = this.findByAufnr(dto.getMocode());
                if (3 == status) {
                    //新增
                    if (oldOder == null) {
                        StringBuilder sb1 = new StringBuilder();
                        FbProductionOrder order;
                        try {
                            order = packageOrder(dto, sb1);
                            if (sb1.length() == 0 && order != null) {
                                saveOrUpdate(order);
                            } else {
                                sb.append(sb1);
                                continue;
                            }
                        } catch (Exception e) {
                            sb.append("订单" + dto.getMocode() + "异常:" + e.getMessage() + "; ");
                            e.printStackTrace();
                            continue;
                        }
                    }
                } else if (4 == status) {
                    if (oldOder != null) {
                        oldOder.setStatus("CLOSE");
                        saveOrUpdate(oldOder);
                    }
                }
            }
        }
        //记录异常日志
        if (sb.length() > 0) {
            RequestLog log = new RequestLog();
            log.setContent("方棒订单异常信息:" + sb.toString());
            log.setCreateTime(new Date());
            requestLogService.saveOrUpdate(log);
        }
        return ResultGenerator.success();
    }

    @Override
    public List<FbProductionOrder> findByGstrpAndGltrpAndStatusAndAuart(List<String> list, String status) {
        return dao.findByGstrpAndGltrpAndStatusAndAuart(list, status);
    }

    private FbProductionOrder packageOrder(ErpOrderDto dto, StringBuilder sb) {
        FbProductionOrder order = new FbProductionOrder();
        order.setTid(dto.getMoid() == null ? null : dto.getMoid().toString());
        order.setAufnr(dto.getMocode());
        String cdepname = dto.getCdepname();
        if (StringUtils.isNotBlank(cdepname) && cdepname.length() > SectionIndexRangeEnum.车间.getEndIndex()) {
            String workShop = cdepname.substring(SectionIndexRangeEnum.车间.getBeginIndex(), SectionIndexRangeEnum.车间.getEndIndex());
            //车间
            //order.setDeptName(workShop);
        }
        order.setDeptCode(dto.getMdeptcode());
        String type = dto.getMocode().substring(SectionIndexRangeEnum.订单类型.getBeginIndex(), SectionIndexRangeEnum.订单类型.getEndIndex());

        if ("A".equals(type)) {
            order.setAuart("研发");
        } else if ("B".equals(type)) {
            order.setAuart("实验");
        } else if ("C".equals(type)) {
            order.setAuart("常规");
        }
        order.setMatnr(dto.getInvcode());
        order.setMenge(dto.getQty());
        order.setAprio("1");
        order.setModid(dto.getModid() == null ? null : dto.getModid().toString());
        order.setGltrp(dto.getDuedate());
        order.setGstrp(dto.getStartdate());
        order.setCreateDate(new Date());
        order.setStatus("REL");
        order.setRdNum(dto.getCitemcode());
        order.setProductionStatus(true);
        //产品信息
        FbProductModel productModel = fbProductModelService.findByProductNo(dto.getInvcode());
        if (productModel != null) {
            order.setFbProductModel(productModel);
        } else {
            sb.append("订单" + dto.getMocode() + "的" + dto.getInvcode() + "未匹配到产品模型; ");
            return null;
        }
        //如果溯源标识为 D、J，则型号为D、J；其他：则从工单中规格型号（cinvstd），截取第一位 - 转换规则：P转成T，N转成H
//        String productType = null;
//        String fromMark = dto.getMocode().substring(SectionIndexRangeEnum.订单溯源标识.getBeginIndex(),SectionIndexRangeEnum.订单溯源标识.getEndIndex());
//        String cinvstd = dto.getCinvstd();
//        if(org.apache.commons.lang3.StringUtils.isNotBlank(fromMark)) {
//            if ("D".equals(fromMark) || "J".equals(fromMark)) {
//                productType = fromMark + fromMark;
//            } else if(org.apache.commons.lang3.StringUtils.isNotBlank(cinvstd)){
//                String type1 = cinvstd.substring(SectionIndexRangeEnum.规格型号截取类型.getBeginIndex(),SectionIndexRangeEnum.规格型号截取类型.getEndIndex());
//                if("P".equals(type1)){
//                    type1 = "T";
//                }else if("N".equals(type1)){
//                    type1 = "H";
//                }
//                productType = fromMark + type1;
//            }
//        }
//        order.setProductType(productType);
//        String [] parts = cinvstd.split(",|，");
//        if(parts.length>1) {
//            order.setResistanceType(parts[1]);
//        }
        String bc = dto.getMocode().substring(SectionIndexRangeEnum.方棒订单号截取边长.getBeginIndex(), SectionIndexRangeEnum.方棒订单号截取边长.getEndIndex());
        order.setSideLengthRange(bc);
        order.setProductionStatus(false);

        return order;
    }


    /**
     * 是否匹配包含 方-修% 料号
     *
     * @param productLevelFb 方棒评级
     * @return 是否
     */
    private boolean isFxFbProductMode(String productLevelFb) {
        return productLevelFb.contains("切") || productLevelFb.contains("修");
    }
}
