package com.yem.wm.im.delivernotice.validator;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.yem.wm.utils.DynamicObjectUtil;
import com.yem.wm.utils.RequestEAS;
import com.yem.wm.utils.YEM;
import kd.bos.dataentity.entity.DynamicObject;
import kd.bos.dataentity.entity.DynamicObjectCollection;
import kd.bos.entity.ExtendedDataEntity;
import kd.bos.entity.validate.AbstractValidator;
import kd.bos.orm.query.QCP;
import kd.bos.orm.query.QFilter;
import kd.bos.servicehelper.BusinessDataServiceHelper;

import java.math.BigDecimal;
import java.util.*;

/**
 * @author xwudd
 * @Description
 * @date 17:53
 **/
public class DeliverNoticeSubmitEASValidator extends AbstractValidator {
    @Override
    public void validate() {
        ExtendedDataEntity[] dataEntities = this.getDataEntities();
        for(ExtendedDataEntity dataEntitie : dataEntities){
            callEas(dataEntitie);
        }
    }


    public void callEas(ExtendedDataEntity dataEntities){
        DynamicObject dataEntitie = dataEntities.getDataEntity();
        JSONObject json = new JSONObject();
        json.put("start",0);
        json.put("len",1000);
        long id = dataEntitie.getLong("id");
        DynamicObject org = dataEntitie.getDynamicObject("yem_org");
        if(YEM.isNotEmpty(org)){
            JSONArray storageOrgs = new JSONArray();
            String orgNumber = org.getString("number");
            storageOrgs.add(orgNumber);
            json.put("storageOrgs",storageOrgs);
            DynamicObjectCollection materialInfos = dataEntitie.getDynamicObjectCollection("yem_es_materialinfo");
            Map<Map<String, Object>, BigDecimal> inventoryQty = getInventoryQty(org, id,materialInfos);
            StringBuffer sb = new StringBuffer();
            for (int i = 0; i < materialInfos.size(); i++) {
                Map<String, Object> map = new HashMap();
                DynamicObject materialInfo = materialInfos.get(i);
                DynamicObject materiel = materialInfo.getDynamicObject("yem_materiel");
                DynamicObject warehouse = materialInfo.getDynamicObject("yem_warehouse");
                if(YEM.isNotEmpty(materiel) && YEM.isNotEmpty(warehouse)){
                    DynamicObject location = materialInfo.getDynamicObject("yem_location");
                    String lotNumber = materialInfo.getString("yem_lotnumber");
                    JSONArray warehouses = new JSONArray();
                    String warehouseNumber = warehouse.getString("number");
                    warehouses.add(warehouseNumber);
                    String materialNumber = materiel.getString("number");
                    json.put("warehouses",warehouses);
                    json.put("materialNumFrom",materialNumber );//物料起--必填
                    json.put("materialNumTo", materialNumber);//物料止--必填
                    DynamicObject group = materiel.getDynamicObject("group");

                    map.put("materiel",materiel.getLong("id"));
                    map.put("warehouse",warehouse.getLong("id"));
//                    if(YEM.isNotEmpty(group)){
//                        json.put("groupStandard",group.getString("number"));//物料分类标准--必填
//                    }
                    if(YEM.isNotEmpty(location)){
                        JSONArray locations = new JSONArray();
                        locations.add(location.getString("number"));
                        json.put("locations",locations);
                        map.put("location",location.getLong("id"));
                    }
                    if(YEM.isNotEmpty(lotNumber)){
                        json.put("batchFrom",lotNumber);
                        json.put("batchTo",lotNumber);
                        map.put("lotNumber",lotNumber);
                    }
                    JSONArray easDatas = eas(json);
                    if(YEM.isNotEmpty(easDatas) && easDatas.size() > 0){
                        JSONObject easData = (JSONObject)easDatas.get(0);
                        BigDecimal fRealQty = easData.getBigDecimal("FRealQty");
                        BigDecimal qty = materialInfo.getBigDecimal("yem_qty");
                        BigDecimal deliverLibraQty = getDeliverLibraQty(inventoryQty, map);
                        if(qty.add(deliverLibraQty).compareTo(fRealQty) > 0){
                            this.addErrorMessage(dataEntities,String.format("明细信息第%s行，物料编码【%s】对应发货数量{%s}大于当前库存数量{%s}，请调整数据后重试！\n",i + 1,materialNumber,qty,fRealQty.subtract(deliverLibraQty)));
                        }
                    }else{
                        this.addErrorMessage(dataEntities,String.format("明细信息第%s行，未在EAS中查询到库存编码为%s，仓库编码为%s，物料编码为%s的库存数量！\n",i + 1,orgNumber,warehouseNumber,materialNumber));
                    }
                }
            }
        }
    }

    public JSONArray eas(JSONObject json){
        String s = RequestEAS.InventoryListServiceFacadeGetData(json.toString());
        JSONObject result = JSONObject.parseObject(s);
        JSONArray list = result.getJSONArray("list");
        if(list.size() == 1000){
            json.put("start",(json.getIntValue("start") + 1) * json.getIntValue("len"));
            s = RequestEAS.InventoryListServiceFacadeGetData(json.toString());
            result = JSONObject.parseObject(s);
            list.addAll(result.getJSONArray("list"));
        }
        return list;
    }


    public Map<Map<String,Object>, BigDecimal>  getInventoryQty(DynamicObject org,Long id,DynamicObjectCollection materialInfos){
        List<Long> materialIds = new ArrayList();
        List<Long> warehouseIds = new ArrayList();
        List<Long> locationIds = new ArrayList();
        List<String> lotNumbers = new ArrayList();
        for(DynamicObject materialInfo : materialInfos){
            DynamicObject material = materialInfo.getDynamicObject("yem_materiel");
            if(YEM.isNotEmpty(material)){
                materialIds.add(material.getLong("id"));
            }
            DynamicObject warehouse = materialInfo.getDynamicObject("yem_warehouse");
            if(YEM.isNotEmpty(warehouse)){
                warehouseIds.add(warehouse.getLong("id"));
            }
            DynamicObject location = materialInfo.getDynamicObject("yem_location");
            if(YEM.isNotEmpty(location)){
                locationIds.add(location.getLong("id"));
            }
            String lotNumber = materialInfo.getString("yem_lotnumber");
            if(YEM.isNotEmpty(lotNumber)){
                lotNumbers.add(lotNumber);
            }
        }
        QFilter qFilter = new QFilter("yem_org", QCP.equals, org.getPkValue());
        qFilter.and(new QFilter("id", QCP.not_equals, id));
        if(materialIds.size() > 0){
            qFilter.and(new QFilter("yem_es_materialinfo.yem_materiel", QCP.in, materialIds));
        }
        if(warehouseIds.size() > 0){
            qFilter.and(new QFilter("yem_es_materialinfo.yem_warehouse", QCP.in, warehouseIds));
        }
        if(locationIds.size() > 0){
            qFilter.and(new QFilter("yem_es_materialinfo.yem_location", QCP.in, locationIds));
        }
        if(lotNumbers.size() > 0){
            qFilter.and(new QFilter("yem_es_materialinfo.yem_lotnumber", QCP.in, lotNumbers));
        }
        qFilter.and(new QFilter("billstatus", QCP.in, new String[]{"B","A"}));
        String selectfields = DynamicObjectUtil.getSelectfields("yem_es_delivernotice", false);
        selectfields = DynamicObjectUtil.getEntrySelectfields(selectfields,"yem_es_delivernotice","yem_es_materialinfo",false);
        DynamicObject[] deliverNotices = BusinessDataServiceHelper.load("yem_es_delivernotice", selectfields, qFilter.toArray());
        Map<Map<String,Object>, BigDecimal> map = new HashMap();
        for (DynamicObject deliverNotice : deliverNotices){
            DynamicObjectCollection queryMaterialInfos = deliverNotice.getDynamicObjectCollection("yem_es_materialinfo");
            for(DynamicObject queryMaterialInfo : queryMaterialInfos){
                Map<String, Object> keyMap = new HashMap<>();
                DynamicObject material = queryMaterialInfo.getDynamicObject("yem_materiel");
                if(YEM.isNotEmpty(material)){
                    keyMap.put("materiel",material.getLong("id"));
                }
                DynamicObject warehouse = queryMaterialInfo.getDynamicObject("yem_warehouse");
                if(YEM.isNotEmpty(warehouse)){
                    keyMap.put("warehouse",warehouse.getLong("id"));
                }
                DynamicObject location = queryMaterialInfo.getDynamicObject("yem_location");
                if(YEM.isNotEmpty(location)){
                    keyMap.put("location",location.getLong("id"));
                }
                String lotNumber = queryMaterialInfo.getString("yem_lotnumber");
                if(YEM.isNotEmpty(lotNumber)){
                    keyMap.put("lotNumber",lotNumber);
                }
                BigDecimal qty = queryMaterialInfo.getBigDecimal("yem_qty");
                if(map.containsKey(keyMap)){
                    map.put(keyMap,qty.add(map.get(keyMap)));
                }else{
                    map.put(keyMap,qty);
                }
            }
        }
        return map;
    }

    /**
     * @description 获取苍穹历史库存占用
     * @author xwudd
     * @param[1] libraMap
     * @param[2] map
     * return
     * @time 2023/11/17 9:30
     */

    public BigDecimal getDeliverLibraQty(Map<Map<String,Object>, BigDecimal> libraMap,Map<String, Object> map){
        BigDecimal deliverLibraQty = BigDecimal.ZERO;
        Set<String> keys = map.keySet();
        if(keys.size() == 4){
            deliverLibraQty = libraMap.get(map);
        }else{
            Set<Map<String, Object>> libraMapKeys = libraMap.keySet();
            Long materiel = (Long)map.get("materiel");
            Long warehouse = (Long)map.get("warehouse");
            Long location = (Long)map.get("location");
            String lotNumber = (String)map.get("lotNumber");
            if(YEM.isEmpty(location) && YEM.isEmpty(lotNumber)){
                for(Map<String, Object> libraMapKey : libraMapKeys){
                    if(libraMapKey.containsKey("materiel") && libraMapKey.containsKey("warehouse")){
                        Long libraMateriel = (Long)libraMapKey.get("materiel");
                        Long libraWarehouse = (Long)libraMapKey.get("warehouse");
                        if(materiel.equals(libraMateriel) && warehouse.equals(libraWarehouse)){
                            deliverLibraQty = deliverLibraQty.add(libraMap.get(libraMapKey));
                        }
                    }
                }
            }else if(YEM.isEmpty(location)){
                for(Map<String, Object> libraMapKey : libraMapKeys){
                    if(libraMapKey.containsKey("materiel") && libraMapKey.containsKey("warehouse") && libraMapKey.containsKey("lotNumber")){
                        Long libraMateriel = (Long)libraMapKey.get("materiel");
                        Long libraWarehouse = (Long)libraMapKey.get("warehouse");
                        String libraLotNumber = (String)libraMapKey.get("lotNumber");
                        if(materiel.equals(libraMateriel) && warehouse.equals(libraWarehouse) && lotNumber.equals(libraLotNumber)){
                            deliverLibraQty = deliverLibraQty.add(libraMap.get(libraMapKey));
                        }
                    }
                }

            }else if(YEM.isEmpty(lotNumber)){
                for(Map<String, Object> libraMapKey : libraMapKeys){
                    if(libraMapKey.containsKey("materiel") && libraMapKey.containsKey("warehouse") && libraMapKey.containsKey("location")){
                        Long libraMateriel = (Long)libraMapKey.get("materiel");
                        Long libraWarehouse = (Long)libraMapKey.get("warehouse");
                        Long libraLocation = (Long)libraMapKey.get("location");
                        if(materiel.equals(libraMateriel) && warehouse.equals(libraWarehouse) && location.equals(libraLocation)){
                            deliverLibraQty = deliverLibraQty.add(libraMap.get(libraMapKey));
                        }
                    }

                }
            }
        }
        return deliverLibraQty;
    }
}
