package com.aucma.api.service.impl;

import com.aucma.api.domain.vo.SAPResultBomVo;
import com.aucma.api.domain.vo.SAPResultOrderInfoVo;
import com.aucma.api.domain.vo.SAPResultVo;
import com.aucma.api.service.ISAPPutStorageService;
import com.aucma.api.utils.SAPConstants;
import com.aucma.base.domain.BaseDeviceLedger;
import com.aucma.base.domain.BaseMaterialInfo;
import com.aucma.base.domain.BaseOrderInfo;
import com.aucma.base.domain.OrderBomInfo;
import com.aucma.base.service.IBaseDeviceLedgerService;
import com.aucma.base.service.IBaseMaterialInfoService;
import com.aucma.base.service.IBaseOrderInfoService;
import com.aucma.base.service.IOrderBomInfoService;
import com.aucma.base.utils.MaterialConstants;
import com.aucma.common.exception.ServiceException;
import com.aucma.common.utils.DateUtils;
import com.aucma.common.utils.StringUtils;
import com.aucma.production.domain.CalendarInfo;
import com.aucma.production.domain.ProductPlanInfo;
import com.aucma.production.service.ICalendarInfoService;
import com.aucma.production.service.IProductPlanInfoService;
import com.aucma.system.utils.PortLogUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

/**
 * SAP接口存入数据业务层
 *
 * @Author YinQ
 * @create 2023-09-27 15:07
 */
@Service
public class SAPPutStorageServiceImpl implements ISAPPutStorageService {

    @Autowired
    private IBaseMaterialInfoService baseMaterialInfoService;

    @Autowired
    private IBaseDeviceLedgerService baseDeviceLedgerService;

    @Autowired
    private IBaseOrderInfoService baseOrderInfoService;

    @Autowired
    private IOrderBomInfoService orderBomInfoService;

    @Autowired
    private ICalendarInfoService calendarInfoService;

    @Autowired
    private IProductPlanInfoService productPlanInfoService;

    /**
     * 转物料实体类 保存数据
     *
     * @param resultVo
     * @return
     */
    public ArrayList<BaseMaterialInfo> insertSAPMaterialInfo(SAPResultVo resultVo) {
        ArrayList<BaseMaterialInfo> baseMaterialInfoArrayList = new ArrayList<>();
        List<HashMap<String, String>> itemList = resultVo.getO_TAB().get("item");
        for (HashMap<String, String> map : itemList) {
            if (StringUtils.isEmpty(map.get("WERKS")) || !map.get("WERKS").equals(SAPConstants.FACTORY_CODE)) {
                continue;
            }
            BaseMaterialInfo baseMaterialInfo = new BaseMaterialInfo();
            baseMaterialInfo.setPlantCode(map.get("WERKS"));
            baseMaterialInfo.setMaterialCode(map.get("MATNR"));
            List<BaseMaterialInfo> baseMaterialInfoList = baseMaterialInfoService.selectBaseMaterialInfoList(baseMaterialInfo);
            // 插入物料数据
            if (baseMaterialInfoList.isEmpty()) {
                BaseMaterialInfo materialInfo = new BaseMaterialInfo();
                materialInfo.setMaterialCode(map.get("MATNR"));
                materialInfo.setMaterialName(map.get("MAKTX"));
                materialInfo.setMaterialType(map.get("MTART"));
                materialInfo.setPlantCode(map.get("WERKS"));
                materialInfo.setMaterialUnit(map.get("MEINS"));
                materialInfo.setMaterialMatkl(map.get("MATKL"));
                materialInfo.setDISPO(map.get("DISPO"));
                this.getMaterialType(materialInfo);
                materialInfo.setMaterialCategories("100");
                materialInfo.setIncrementDate(DateUtils.dateTime(DateUtils.YYYY_MM_DD, map.get("UDATE")));
                baseMaterialInfoService.insertBaseMaterialInfo(materialInfo);
                baseMaterialInfoArrayList.add(materialInfo);
            } else {
                //修改物料数据
                BaseMaterialInfo materialInfo = baseMaterialInfoList.get(0);
                materialInfo.setMaterialName(map.get("MAKTX"));
                materialInfo.setMaterialType(map.get("MTART"));
                materialInfo.setMaterialUnit(map.get("MEINS"));
                materialInfo.setMaterialMatkl(map.get("MATKL"));
                String dispo = map.get("DISPO");
                materialInfo.setDISPO(dispo);
                this.getMaterialType(materialInfo);
                materialInfo.setMaterialCategories("100");
                materialInfo.setIncrementDate(DateUtils.dateTime(DateUtils.YYYY_MM_DD, map.get("UDATE")));
                baseMaterialInfoService.updateBaseMaterialInfo(materialInfo);
                baseMaterialInfoArrayList.add(materialInfo);
            }
        }
        return baseMaterialInfoArrayList;
    }

    /**
     * 获取物料类型
     *
     * @param materialInfo
     * @return
     */
    private BaseMaterialInfo getMaterialType(BaseMaterialInfo materialInfo) {
        String dispo = materialInfo.getDISPO();
        if (StringUtils.isNotEmpty(dispo)) {
            //（100=成品;200=箱体;300=门体）
            if (dispo.equals(MaterialConstants.FP_MATERIAL_TYPE)) {
                materialInfo.setMaterialSubclass(dispo);
                return materialInfo;
            }
            if (dispo.equals(MaterialConstants.BOX_MATERIAL_TYPE)) {
                materialInfo.setMaterialSubclass(dispo);
                return materialInfo;
            }
            if (dispo.equals(MaterialConstants.DOOR_MATERIAL_TYPE) && materialInfo.getMaterialName().contains("门体")) {
                materialInfo.setMaterialSubclass(dispo);
                return materialInfo;
            }
        }
        //400=围板;500=内胆;600=前板;700=后板
        if (materialInfo.getMaterialType().equals(MaterialConstants.SAP_BCP_MATERIAL) && materialInfo.getMaterialName().contains("预装箱体")) {
            materialInfo.setMaterialSubclass(MaterialConstants.COAMING_MATERIAL_TYPE);
            return materialInfo;
        }
        if (materialInfo.getMaterialType().equals(MaterialConstants.SAP_BCP_MATERIAL) && materialInfo.getMaterialName().contains("箱壳部件")) {
            materialInfo.setMaterialSubclass(MaterialConstants.COAMING_MATERIAL_TYPE);
            return materialInfo;
        }
        if (materialInfo.getMaterialType().equals(MaterialConstants.SAP_BCP_MATERIAL) && materialInfo.getMaterialName().contains("内胆部件")) {
            materialInfo.setMaterialSubclass(MaterialConstants.LINER_MATERIAL_TYPE);
            return materialInfo;
        }
        if (materialInfo.getMaterialType().equals(MaterialConstants.SAP_BCP_MATERIAL) && materialInfo.getMaterialName().contains("箱体前板")) {
            materialInfo.setMaterialSubclass(MaterialConstants.FORMER_MATERIAL_TYPE);
            return materialInfo;
        }
        if (materialInfo.getMaterialType().equals(MaterialConstants.SAP_BCP_MATERIAL) && materialInfo.getMaterialName().contains("箱体后板")) {
            materialInfo.setMaterialSubclass(MaterialConstants.AFTER_MATERIAL_TYPE);
            return materialInfo;
        }
        //其他
        if (StringUtils.isEmpty(materialInfo.getMaterialSubclass())) {
            materialInfo.setMaterialSubclass(MaterialConstants.OTHER_MATERIAL_TYPE);
        }
        return materialInfo;
    }

    /**
     * 转换生产工单实体类 保存数据
     */
    @Override
    public ArrayList<BaseOrderInfo> insertSAPBaseOrderInfo(SAPResultOrderInfoVo resultVo) throws ParseException {
        ArrayList<BaseOrderInfo> baseOrderInfoList = new ArrayList<>();
        List<HashMap<String, String>> itemList = resultVo.getO_TAB().get("item");
        for (HashMap<String, String> map : itemList) {
            if (StringUtils.isEmpty(map.get("WERKS")) || !map.get("WERKS").equals(SAPConstants.FACTORY_CODE)
            || StringUtils.isEmpty(map.get("MATNR")) || !map.get("MATNR").startsWith("90")) {
                continue;
            }
            BaseOrderInfo boInfo = new BaseOrderInfo();
            boInfo.setOrderCode(map.get("AUFNR"));
            boInfo.setMaterialCode(map.get("MATNR"));
            boInfo.setFactoryCode(map.get("WERKS"));
            List<BaseOrderInfo> baseOrderInfos = baseOrderInfoService.selectBaseOrderInfoList(boInfo);
            //首次存SAP计划
            if (baseOrderInfos.isEmpty()) {
                BaseOrderInfo baseOrderInfo = new BaseOrderInfo();
                baseOrderInfo.setOrderCode(map.get("AUFNR"));
                baseOrderInfo.setOrderStatus(map.get("STTXT"));
                baseOrderInfo.setSaleOrderCode(map.get("KDAUF"));
                baseOrderInfo.setMaterialCode(map.get("MATNR"));
                baseOrderInfo.setMaterialName(map.get("MAKTX"));
                if (!map.get("GAMNG").equals(null)) {
                    baseOrderInfo.setOrderAmount(new BigDecimal(map.get("GAMNG")));
                }
                baseOrderInfo.setFactoryCode(map.get("WERKS"));
                baseOrderInfo.setOrderType(map.get("AUART"));
                baseOrderInfo.setWorkCenterCode(map.get("ARBPL"));
                baseOrderInfo.setRoutingCode(map.get("AUFPL"));
                baseOrderInfo.setBeginDate(new SimpleDateFormat("yyyy-MM-dd").parse(map.get("GSTRP")));
                baseOrderInfo.setEndDate(new SimpleDateFormat("yyyy-MM-dd").parse(map.get("GLTRP")));

                // 同步生产日历
                CalendarInfo calendarInfo = new CalendarInfo();
                calendarInfo.setSapPlanCode(baseOrderInfo.getOrderCode());
                calendarInfo.setMaterialCode(baseOrderInfo.getMaterialCode());
                calendarInfo.setMaterialName(baseOrderInfo.getMaterialName());
                calendarInfo.setPlanStartDate(baseOrderInfo.getBeginDate());
                calendarInfo.setPlanEndDate(baseOrderInfo.getEndDate());
                calendarInfo.setSchedulingDate(baseOrderInfo.getBeginDate());
                calendarInfo.setPlanAmount(baseOrderInfo.getOrderAmount());
                calendarInfoService.insertCalendarInfo(calendarInfo);
                baseOrderInfoService.insertBaseOrderInfo(baseOrderInfo);
                baseOrderInfoList.add(baseOrderInfo);
            } else {
                //更新SAP计划
                BaseOrderInfo baseOrderInfoOld = baseOrderInfos.get(0);
                if (baseOrderInfoOld.getManualUpdateFlag().equals("1")){
                    continue;
                }
                BaseOrderInfo baseOrderInfo = new BaseOrderInfo();
                baseOrderInfo.setObjId(baseOrderInfoOld.getObjId());
                baseOrderInfo.setMaterialCode(baseOrderInfoOld.getMaterialCode());
                baseOrderInfo.setOrderCode(baseOrderInfoOld.getOrderCode());
                baseOrderInfo.setSaleOrderCode(map.get("KDAUF"));
                baseOrderInfo.setMaterialName(map.get("MAKTX"));
                baseOrderInfo.setOrderStatus(map.get("STTXT"));
                baseOrderInfo.setOrderType(map.get("AUART"));
                BigDecimal newOrderAmount = new BigDecimal(map.get("GAMNG"));
                baseOrderInfo.setOrderAmount(newOrderAmount);
                if (!newOrderAmount.equals(baseOrderInfo.getOrderAmount())){
                    baseOrderInfo.setUpdatedBy("SAP");
                    //同步生产计划数量
                    ProductPlanInfo planInfo = new ProductPlanInfo();
                    planInfo.setOrderCode(baseOrderInfo.getOrderCode());
                    List<ProductPlanInfo> productPlanInfos = productPlanInfoService.selectProductPlanInfoList(planInfo);
                    for (ProductPlanInfo info : productPlanInfos) {
                        ProductPlanInfo planInfoIn = new ProductPlanInfo();
                        planInfoIn.setObjId(info.getObjId());
                        planInfoIn.setUpdatedBy("SAP");
                        planInfoIn.setPlanAmount(baseOrderInfo.getOrderAmount().longValue());
                        productPlanInfoService.updateProductPlanInfo(planInfoIn);
                    }
                }
                baseOrderInfo.setRoutingCode(map.get("AUFPL"));
                baseOrderInfo.setBeginDate(new SimpleDateFormat("yyyy-MM-dd").parse(map.get("GSTRP")));
                baseOrderInfo.setEndDate(new SimpleDateFormat("yyyy-MM-dd").parse(map.get("GLTRP")));
                baseOrderInfoService.updateBaseOrderInfo(baseOrderInfo);
                //产线变动 重新生成生成计划
                if (StringUtils.isNotEmpty(map.get("ARBPL")) &&
                        StringUtils.isNotEmpty(baseOrderInfos.get(0).getWorkCenterCode()) &&
                        !map.get("ARBPL").equals(baseOrderInfos.get(0).getWorkCenterCode())){
                    baseOrderInfo.setIsRelease(1L);
                    baseOrderInfo.setWorkCenterCode(map.get("ARBPL"));
                    productPlanInfoService.releaseOrderPlan(baseOrderInfo);
                }
                baseOrderInfoList.add(baseOrderInfo);
                // 同步生产日历
                CalendarInfo calendar = new CalendarInfo();
                calendar.setSapPlanCode(baseOrderInfo.getOrderCode());
                calendar.setMaterialCode(baseOrderInfo.getMaterialCode());
                List<CalendarInfo> calendarInfos = calendarInfoService.selectCalendarInfoList(calendar);
                if (calendarInfos.size() == 1) {
                    CalendarInfo calendarInfo = calendarInfos.get(0);
                    calendarInfo.setMaterialName(baseOrderInfo.getMaterialName());
                    calendarInfo.setPlanStartDate(baseOrderInfo.getBeginDate());
                    calendarInfo.setPlanEndDate(baseOrderInfo.getEndDate());
                    calendarInfo.setSchedulingDate(baseOrderInfo.getBeginDate());
                    calendarInfo.setPlanAmount(baseOrderInfo.getOrderAmount());
                    baseOrderInfoService.updateBaseOrderInfo(baseOrderInfo);
                }
            }
        }

        return baseOrderInfoList;
    }

    /**
     * 转设备台账实体类 保存数据
     *
     * @param resultVo
     * @return
     */
    @Override
    public ArrayList<BaseDeviceLedger> insertSAPDeviceLedger(SAPResultOrderInfoVo resultVo) throws ParseException {
        ArrayList<BaseDeviceLedger> baseDeviceLedgerArrayList = new ArrayList<>();
        List<HashMap<String, String>> itemList = resultVo.getO_TAB().get("item");
        for (HashMap<String, String> map : itemList) {
            if (StringUtils.isEmpty(map.get("WERKS")) || !map.get("WERKS").equals(SAPConstants.FACTORY_CODE)) {
                continue;
            }
            BaseDeviceLedger device = new BaseDeviceLedger();
            device.setCostCenter(map.get("KOSTL"));
            ;
            device.setDeviceCode(map.get("EQUNR"));
            device.setFactoryCode(map.get("IWERK"));
            List<BaseDeviceLedger> baseDeviceLedgers = baseDeviceLedgerService.selectBaseDeviceLedgerList(device);
            if (!baseDeviceLedgers.isEmpty()) {
                BaseDeviceLedger deviceLedger = new BaseDeviceLedger();
                deviceLedger.setCostCenter(map.get("KOSTL"));//
                deviceLedger.setFactoryCode(map.get("IWERK"));
                deviceLedger.setDeviceName(map.get("EQKTX"));
                deviceLedger.setEnableDate(new SimpleDateFormat("yyyy-MM-dd").parse(map.get("INBDT")));
                deviceLedger.setManufacturer(map.get("ELIEF"));
                deviceLedger.setDeviceType(map.get("EQTYP"));
                deviceLedger.setDeviceCode(map.get("EQUNR"));//
                deviceLedger.setUsedDepartment(map.get("NAME1"));
                deviceLedger.setCreatedTime(DateUtils.getNowDate());
                baseDeviceLedgerService.insertBaseDeviceLedger(deviceLedger);
                baseDeviceLedgerArrayList.add(deviceLedger);
            }
        }
        return baseDeviceLedgerArrayList;
    }

    /**
     * 转换产品bom信息实体类 保存数据
     */
    @Override
    public ArrayList<OrderBomInfo> insertSAPOrderBomInfo(SAPResultBomVo resultVo) throws ParseException {
        ArrayList<OrderBomInfo> orderBomInfoList = new ArrayList<>();
        List<HashMap<String, String>> itemList = resultVo.getO_TAB().get("item");
        for (HashMap<String, String> map : itemList) {
            if (StringUtils.isEmpty(map.get("WERKS")) || !map.get("WERKS").equals(SAPConstants.FACTORY_CODE)) {
                continue;
            }
            OrderBomInfo bomInfo = new OrderBomInfo();
            bomInfo.setMaterialCode(map.get("IDNRK"));
            bomInfo.setParentId(map.get("MATNR"));
            bomInfo.setFactoryCode(map.get("WERKS"));
            List<OrderBomInfo> orderBomInfos = orderBomInfoService.selectOrderBomInfoList(bomInfo);
            // 添加产品BOM
            if (orderBomInfos.isEmpty()) {
                OrderBomInfo orderBomInfo = new OrderBomInfo();
                orderBomInfo.setFactoryCode(map.get("WERKS"));
                orderBomInfo.setParentId(map.get("MATNR"));
                orderBomInfo.setMaterialCode(map.get("IDNRK"));
                if (!map.get("MENGE").isEmpty()) {
                    orderBomInfo.setStandardAmount(new BigDecimal(map.get("MENGE")));
                }
                orderBomInfo.setSort(map.get("SORTF"));
                orderBomInfo.setVbeln(map.get("VBELN"));
                orderBomInfo.setVbpos(map.get("VBPOS"));
                try {
                    orderBomInfoService.insertOrderBomInfo(orderBomInfo);
                } catch (Exception e) {
                    e.printStackTrace();
                }
                orderBomInfoList.add(orderBomInfo);
            }else {
                //修改产品BOM
                OrderBomInfo bom = orderBomInfos.get(0);
                if (!map.get("MENGE").isEmpty()) {
                    bom.setStandardAmount(new BigDecimal(map.get("MENGE")));
                }
                bom.setSort(map.get("SORTF"));
                bom.setVbeln(map.get("VBELN"));
                bom.setVbpos(map.get("VBPOS"));
                try {
                    orderBomInfoService.updateOrderBomInfo(bom);
                } catch (Exception e) {
                    e.printStackTrace();
                }
                orderBomInfoList.add(bom);
            }
        }
        return orderBomInfoList;
    }

    /**
     * 手动更换订单产线
     * @param baseOrderInfo
     * @return
     */
    @Override
    public int replaceProductionLine(BaseOrderInfo baseOrderInfo) {
        BaseOrderInfo orderInfo = baseOrderInfoService.selectBaseOrderInfoByObjId(baseOrderInfo.getObjId());
        // 订单数量==切换数量 => 修改工作中心
        if (baseOrderInfo.getReplaceAmount() == baseOrderInfo.getOrderAmount().longValue()){
            orderInfo.setManualUpdateFlag("1");
            orderInfo.setWorkCenterCode(baseOrderInfo.getWorkCenterCode());
            int i = baseOrderInfoService.updateBaseOrderInfo(orderInfo);
            if (i > 0){
                ProductPlanInfo productPlanInfo = new ProductPlanInfo();
                productPlanInfo.setOrderCode(orderInfo.getOrderCode());
                //删除旧计划
                List<ProductPlanInfo> productPlanInfoList = productPlanInfoService.selectProductPlanInfoList(productPlanInfo);
                for (ProductPlanInfo planInfo : productPlanInfoList) {
                    productPlanInfoService.deleteProductPlanInfoByObjId(planInfo.getObjId());
                }
                productPlanInfoService.releaseOrderPlan(orderInfo);
            }
            return 1;
        }
        // 订单数量 < 切换数量 => 添加一条并且修改工作中心
        try {
            //更新历史SAP订单订单数量
            BaseOrderInfo info = new BaseOrderInfo();
            info.setObjId(orderInfo.getObjId());
            info.setOrderAmount(new BigDecimal(baseOrderInfo.getOrderAmount().longValue() - baseOrderInfo.getReplaceAmount()));
            info.setManualUpdateFlag("1");
            baseOrderInfoService.updateBaseOrderInfo(info);
            //更新历史生产计划订单数量
            ProductPlanInfo productPlanInfo = new ProductPlanInfo();
            productPlanInfo.setOrderCode(orderInfo.getOrderCode());
            List<ProductPlanInfo> productPlanInfoList = productPlanInfoService.selectProductPlanInfoList(productPlanInfo);
            for (ProductPlanInfo planInfo : productPlanInfoList) {
                ProductPlanInfo plan = new ProductPlanInfo();
                plan.setObjId(planInfo.getObjId());
                planInfo.setPlanAmount(baseOrderInfo.getOrderAmount().longValue() - baseOrderInfo.getReplaceAmount());
                productPlanInfoService.updateProductPlanInfo(plan);
            }
            //插入新SAP订单 更换后工作中心
            BaseOrderInfo orderOldInfo = baseOrderInfoService.selectBaseOrderInfoByObjId(orderInfo.getObjId());
            orderOldInfo.setObjId(null);
            orderOldInfo.setCompleteAmount(0L);
            orderOldInfo.setOrderAmount(new BigDecimal(baseOrderInfo.getReplaceAmount()));
            orderOldInfo.setWorkCenterCode(baseOrderInfo.getWorkCenterCode());
            orderOldInfo.setCompleteDate(null);
            baseOrderInfoService.insertBaseOrderInfo(orderOldInfo);
            //新订单下计划
            productPlanInfoService.releaseOrderPlan(orderOldInfo);
            PortLogUtils.savePortLog("1301", "手动更换订单产线" + baseOrderInfo.getOrderCode(),
                    "replaceProductionLine", baseOrderInfo.toString(), null, null);
        } catch (Exception e) {
            PortLogUtils.savePortLog("1301", "手动更换订单产线" + baseOrderInfo.getOrderCode(),
                    "replaceProductionLine", baseOrderInfo.toString(), null, e.toString());
        }
        return 1;
    }
}
