package com.awspaas.user.apps.donenow_ctt.event;

import com.actionsoft.bpms.bo.engine.BO;
import com.actionsoft.bpms.bpmn.engine.core.delegate.ProcessExecutionContext;
import com.actionsoft.bpms.bpmn.engine.listener.ExecuteListener;
import com.actionsoft.bpms.bpmn.engine.model.run.delegate.ProcessInstance;
import com.actionsoft.bpms.util.DBSql;
import com.actionsoft.exception.BPMNError;
import com.actionsoft.sdk.local.SDK;
import org.apache.commons.lang3.StringUtils;

import java.sql.Connection;
import java.util.*;

public class costPickFormAfterSave extends ExecuteListener {
    public String getDescription() {
        return "合同产品拣货保存后";
    }

    /**
     *拣货
     * @param processExecutionContext
     * @throws Exception
     */
    @Override
    public void execute(ProcessExecutionContext processExecutionContext) throws Exception {

        BO pickBO = SDK.getBOAPI().getByProcess("BO_EU_DNCTT_CONTRACT_PRODUCT_PICK", processExecutionContext.getProcessInstance().getId());
        String warehouseProductId = pickBO.getString("WAREHOUSE_PRODUCT_ID");
        String contractCostId = pickBO.getString("CONTRACT_COST_ID");

        Set<String> pickSerials = new LinkedHashSet<>();
        String pick_sns = pickBO.getString("SERIAL_NUMBERS");
        String PICKED_SNS = pickBO.getString("PICKED_SNS");

        // 处理PICKED_SNS不为空的情况
        if (StringUtils.isNotBlank(PICKED_SNS)) {
            // 1. 处理originalSerials为null的情况，转为空字符串避免拼接出"null"
            String normalizedOriginals = StringUtils.defaultString(pick_sns, "");

            // 2. 拼接两个字符串，避免在originalSerials为空时产生多余逗号（如"picked,"）
            String combined;
            if (normalizedOriginals.isEmpty()) {
                combined = PICKED_SNS;
            } else {
                combined = PICKED_SNS + "," + normalizedOriginals;
            }

            // 3. 分割并去重，用LinkedHashSet保持插入顺序（首次出现的元素保留）

            for (String serial : combined.split(",")) {
                // 过滤空字符串（避免连续逗号产生的空元素）
                if (StringUtils.isNotBlank(serial)) {
                    pickSerials.add(serial);
                }
            }

            // 4. 拼接去重后的结果，更新回BO
            pick_sns = StringUtils.join(pickSerials, ",");
            pickBO.set("SERIAL_NUMBERS", pick_sns);
        }


        int PICK_QUANTITY = ObjToInt(pickBO.get("PICK_QUANTITY"));//拣货数量
        //验库存
        //可用库存
        int warehouseProductAvailableQuantity = ObjToInt(DBSql.getString("SELECT SUM(AVAILABLE) FROM VIEW_EU_DNINVT_PRODUCT_INVENTORY where ID=?", new Object[]{warehouseProductId}));

        if (warehouseProductAvailableQuantity <= 0) throw new BPMNError("", "库存数量不足");

        if (PICK_QUANTITY > warehouseProductAvailableQuantity) throw new BPMNError("", "库存数量不足");

        int contractCostQuantity = ObjToInt(SDK.getBOAPI().get("BO_EU_DNCTT_CONTRACT_COST", contractCostId, "QUANTITY"));//全部拣货数量
        //已拣货数量
        int contractProductPickQuantity = ObjToInt(DBSql.getString("SELECT SUM(QUANTITY) FROM BO_EU_DNCTT_CONTRACT_COST_PRODUCT WHERE CONTRACT_COST_ID=?  AND CLOSED=0", new Object[]{contractCostId}));

        if (contractProductPickQuantity + PICK_QUANTITY > contractCostQuantity)
            throw new BPMNError("", "拣货数量超出合同数量");

        Connection conn = null;
        try {
            conn = DBSql.open();
            conn.setAutoCommit(false);
            // PICK_TYPE 拣货方式
            String WAREHOUSE_ID = pickBO.getString("WAREHOUSE_ID");

            int STATUS_ID = 2157;//库存转移给我
            if (pickBO.getString("PICK_TYPE").equals("1"))//库存转移给我
            {
                String resWareId = DBSql.getString(conn, "SELECT ID FROM BO_EU_DNIVT_WAREHOUSE WHERE RESOURCE_ID=? AND CLOSED=0 ", new Object[]{processExecutionContext.getUserContext().getUID()});
                if (StringUtils.isNotBlank(resWareId)) {
                    WAREHOUSE_ID = resWareId;
                } else {
                    BO resWare = new BO();
                    resWare.set("NAME", "员工：" + processExecutionContext.getUserContext().getUserName());

                    ProcessInstance processInstance = SDK.getProcessAPI().createBOProcessInstance("obj_e10413dd6e034d22aac787a35917814c", processExecutionContext.getUserContext().getUID(), "创建员工仓库" + resWare.getString("NAME"));
                    resWare.setBindId(processInstance.getId());
                    resWare.set("IS_DEFAULT", 0);
                    resWare.set("IS_ACTIVE", 1);
                    resWare.set("RESOURCE_ID", processExecutionContext.getUserContext().getUID());
                    SDK.getBOAPI().create("BO_EU_DNIVT_WAREHOUSE", resWare, processInstance, processExecutionContext.getUserContext(), conn);
                    WAREHOUSE_ID = resWare.getId();
                }
            } else if (pickBO.getString("PICK_TYPE").equals("2")) {
                STATUS_ID = 2159;//已配送
            }

            BO costProductBO = new BO();

            ProcessInstance processInstance = SDK.getProcessAPI().createBOProcessInstance("obj_6bc913271069455abbd516c556b26d31", processExecutionContext.getUserContext().getUID(), "合同产品物流管理");

            costProductBO.setBindId(processInstance.getId());

            // costProductBO.setBindId(SDK.getBOAPI().get("BO_EU_DNCTT_CONTRACT_COST", contractCostId, "BINDID").toString());
            costProductBO.set("WAREHOUSE_ID", WAREHOUSE_ID);
            costProductBO.set("CONTRACT_COST_ID", contractCostId);
            costProductBO.set("QUANTITY", pickBO.get("PICK_QUANTITY"));
            costProductBO.set("SN", pick_sns);
            costProductBO.set("STATUS_ID", STATUS_ID);
            costProductBO.set("OLD_QUANTITY", costProductBO.get("QUANTITY"));//配送数量
            SDK.getBOAPI().createDataBO("BO_EU_DNCTT_CONTRACT_COST_PRODUCT", costProductBO, processExecutionContext.getUserContext(), conn);


            //修改状态
            int contractCostStatusId = 0;
            contractCostQuantity = ObjToInt(SDK.getBOAPI().query("BO_EU_DNCTT_CONTRACT_COST").connection(conn).detailByField(contractCostId, "QUANTITY"));//全部拣货数量
            //已拣货数量
            contractProductPickQuantity = ObjToInt(DBSql.getString(conn, "SELECT SUM(QUANTITY) FROM BO_EU_DNCTT_CONTRACT_COST_PRODUCT WHERE CONTRACT_COST_ID=? AND CLOSED=0", new Object[]{contractCostId}));

            if (contractCostQuantity == contractProductPickQuantity) {
                // 只要存在采购中
                if (DBSql.getInt(conn, "SELECT COUNT(1) FROM BO_EU_DNCTT_CONTRACT_COST_PRODUCT WHERE CONTRACT_COST_ID=? AND CLOSED=0 AND STATUS_ID=?", new Object[]{contractCostId, 2156}) > 0) {
                    contractCostStatusId = 1235;   // 采购中
                } else if (DBSql.getInt(conn, "SELECT COUNT(1) FROM BO_EU_DNCTT_CONTRACT_COST_PRODUCT WHERE CONTRACT_COST_ID=? AND CLOSED=0 AND STATUS_ID<>? AND STATUS_ID<>?", new Object[]{contractCostId, 2157, 2158}) == 0) {
                    contractCostStatusId = 1236;  // 待配送
                } else if (DBSql.getInt(conn, "SELECT COUNT(1) FROM BO_EU_DNCTT_CONTRACT_COST_PRODUCT WHERE CONTRACT_COST_ID=? AND CLOSED=0 AND STATUS_ID<>? ", new Object[]{contractCostId, 2159}) == 0) {
                    contractCostStatusId = 1237;   // 已配送
                } else {
                    contractCostStatusId = 1236;  // 待配送
                }
            } else {
                if (DBSql.getInt(conn, "SELECT DOES_NOT_REQUIRE_PROCUREMENT FROM BO_EU_DNIVT_PRODUCT WHERE ID=?", new Object[]{pickBO.getString("PRODUCT_ID")}) == 1) {
                    contractCostStatusId = 1234;
                } else {


                }

            }
            if (contractCostStatusId != 0) {
                DBSql.update(conn, "UPDATE BO_EU_DNCTT_CONTRACT_COST SET STATUS_ID=? WHERE ID=?", new Object[]{contractCostStatusId, contractCostId});
            }


            if (pickBO.getString("PICK_TYPE").equals("1"))//库存转移给我
            {
                ProcessInstance transfeProcessIns = SDK.getProcessAPI().createBOProcessInstance("obj_e15a8fedeaeb43dc85aa258a7e1cffcf", processExecutionContext.getUserContext().getUID(), "库存转移");
                BO ivtTransfer = new BO();
                ivtTransfer.setBindId(transfeProcessIns.getId());
                ivtTransfer.set("FROM_WAREHOUSE_ID", pickBO.getString("WAREHOUSE_ID"));
                ivtTransfer.set("TO_WAREHOUSE_ID", WAREHOUSE_ID);
                ivtTransfer.set("PRODUCT_ID", pickBO.getString("PRODUCT_ID"));
                ivtTransfer.set("QUANTITY", pickBO.get("PICK_QUANTITY"));
                ivtTransfer.set("TYPE_ID", 1481);  // 仓库间转移
                if (pickSerials.size() > 0)
                    ivtTransfer.set("SN", StringUtils.join(pickSerials, ","));//产品序列号
                SDK.getBOAPI().create("BO_EU_DNIVT_TRANSFER", ivtTransfer, transfeProcessIns, processExecutionContext.getUserContext(), conn);

                //库存增加
                BO toWarehouseProductBO = SDK.getBOAPI().query("BO_EU_DNIVT_WAREHOUSE_PRODUCT").connection(conn).addQuery("PRODUCT_ID=", pickBO.getString("PRODUCT_ID")).addQuery("WAREHOUSE_ID=", WAREHOUSE_ID).detail();
                if (toWarehouseProductBO != null) {
                    toWarehouseProductBO.set("QUANTITY", ObjToInt(toWarehouseProductBO.get("QUANTITY")) + ObjToInt(pickBO.get("PICK_QUANTITY")));
                    SDK.getBOAPI().update("BO_EU_DNIVT_WAREHOUSE_PRODUCT", toWarehouseProductBO, conn);
                } else {
                    ProcessInstance twpProcessIns = SDK.getProcessAPI().createBOProcessInstance("obj_e15a8fedeaeb43dc85aa258a7e1cffcf", processExecutionContext.getUserContext().getUID(), "库存转移");
                    toWarehouseProductBO = new BO();
                    toWarehouseProductBO.setBindId(twpProcessIns.getId());
                    toWarehouseProductBO.set("WAREHOUSE_ID", WAREHOUSE_ID);
                    toWarehouseProductBO.set("PRODUCT_ID", pickBO.getString("PRODUCT_ID"));
                    toWarehouseProductBO.set("QUANTITY", pickBO.get("PICK_QUANTITY"));
                    SDK.getBOAPI().create("BO_EU_DNIVT_WAREHOUSE_PRODUCT", toWarehouseProductBO, twpProcessIns, processExecutionContext.getUserContext(), conn);
                }

                //库存减少
                BO fromWarehouseProductBO = SDK.getBOAPI().query("BO_EU_DNIVT_WAREHOUSE_PRODUCT").connection(conn).addQuery("PRODUCT_ID=", pickBO.getString("PRODUCT_ID")).addQuery("WAREHOUSE_ID=", pickBO.getString("WAREHOUSE_ID")).detail();
                fromWarehouseProductBO.set("QUANTITY", ObjToInt(fromWarehouseProductBO.get("QUANTITY")) - ObjToInt(pickBO.get("PICK_QUANTITY")));

                SDK.getBOAPI().update("BO_EU_DNIVT_WAREHOUSE_PRODUCT", fromWarehouseProductBO, conn);

                int pickQuantity = ObjToInt(pickBO.get("PICK_QUANTITY"));//拣货数量


                //序列号减少  修改库存批次
                List<BO> lots = SDK.getBOAPI().query("BO_EU_DNIVT_WAREHOUSE_PRODUCT_LOT").addQuery("BINDID=", fromWarehouseProductBO.getBindId()).addQuery("QUANTITY>", 0).orderByCreated().list();
                int cnt = 0;
                for (BO lot : lots) {
                    if (pickSerials.size() > 0) {
                        //序列化产品
                        boolean isIn = false;
                        String lotSN = lot.getString("SN");
                        lotSN = "," + lotSN + ",";
                        List<String> toSN = new ArrayList<>();
                        for (String sn : pickSerials) {
                            if (lotSN.contains("," + sn + ",")) {
                                isIn = true;
                                lotSN = lotSN.replace("," + sn + ",", ",");
                                toSN.add(sn);
                                cnt++;
                            }
                            if (cnt >= pickSerials.size())
                                break;
                        }
                        if (isIn) {
                            if (StringUtils.isNotBlank(lotSN)) {
                                lotSN = lotSN.replaceAll("^,+|,+$", "") // 移除首尾一个或多个逗号
                                        .replaceAll(",+", ",");     // 合并中间连续逗号
                                int count = (int) lotSN.chars().filter(c -> c == ',').count();
                                lot.set("SN", lotSN);
                                lot.set("QUANTITY", count + 1);
                            } else {
                                lot.set("SN", "");
                                lot.set("QUANTITY", 0);
                            }

                            //更新批次上序列号
                            SDK.getBOAPI().update("BO_EU_DNIVT_WAREHOUSE_PRODUCT_LOT", lot, conn);

                            //目标 库存批次 增加
                            BO toLot = SDK.getBOAPI().query("BO_EU_DNIVT_WAREHOUSE_PRODUCT_LOT").addQuery("LOT=", lot.get("LOT")).addQuery("ORDER_PRODUCT_ID=", lot.get("ORDER_PRODUCT_ID")).addQuery("BINDID=", toWarehouseProductBO.getBindId()).detail();
                            if (toLot != null) {
                                toLot.set("QUANTITY", Integer.parseInt(toLot.get("QUANTITY").toString()) + toSN.size());
                                toLot.set("SN", toLot.get("SN") + "," + StringUtils.join(toSN, ","));
                                SDK.getBOAPI().update("BO_EU_DNIVT_WAREHOUSE_PRODUCT_LOT", toLot, conn);
                            } else {
                                //新增 目标库批次
                                toLot = new BO();
                                toLot.setAll(lot.asMap());
                                toLot.setId(null);
                                toLot.setBindId(toWarehouseProductBO.getBindId());
                                toLot.set("SN", StringUtils.join(toSN, ","));
                                toLot.set("QUANTITY", toSN.size());
                                toLot.set("ORDER_PRODUCT_ID", lot.get("ORDER_PRODUCT_ID"));
                                toLot.set("WAREHOUSE_ID", toWarehouseProductBO.get("WAREHOUSE_ID"));
                                toLot.set("PRODUCT_ID", toWarehouseProductBO.get("PRODUCT_ID"));
                                SDK.getBOAPI().createDataBO("BO_EU_DNIVT_WAREHOUSE_PRODUCT_LOT", toLot, processExecutionContext.getUserContext(), conn);
                            }
                        }
                        if (cnt >= pickSerials.size())
                            break;
                    } else {
                        //无序列化产品
                        int lotQuantity = Integer.parseInt(lot.get("QUANTITY").toString());
                        int toQuantity = 0;
                        if (lotQuantity > pickQuantity) {
                            lot.set("QUANTITY", lotQuantity - pickQuantity);
                            toQuantity = pickQuantity;
                            pickQuantity = 0;

                        } else {
                            lot.set("QUANTITY", 0);
                            toQuantity = lotQuantity;
                            pickQuantity -= lotQuantity;
                        }
                        SDK.getBOAPI().update("BO_EU_DNIVT_WAREHOUSE_PRODUCT_LOT", lot, conn);

                        //目标 库存批次 增加
                        BO toLot = SDK.getBOAPI().query("BO_EU_DNIVT_WAREHOUSE_PRODUCT_LOT").addQuery("LOT=", lot.get("LOT")).addQuery("ORDER_PRODUCT_ID=", lot.get("ORDER_PRODUCT_ID")).addQuery("BINDID=", toWarehouseProductBO.getBindId()).detail();
                        if (toLot != null) {
                            toLot.set("QUANTITY", Integer.parseInt(toLot.get("QUANTITY").toString()) + toQuantity);
                            toLot.set("SN", "");
                            SDK.getBOAPI().update("BO_EU_DNIVT_WAREHOUSE_PRODUCT_LOT", toLot, conn);
                        } else {
                            //新增 目标库批次
                            toLot = new BO();
                            toLot.setAll(lot.asMap());
                            toLot.setId(null);
                            toLot.setBindId(toWarehouseProductBO.getBindId());
                            toLot.set("SN", "");
                            toLot.set("QUANTITY", toQuantity);
                            toLot.set("ORDER_PRODUCT_ID", lot.get("ORDER_PRODUCT_ID"));
                            toLot.set("WAREHOUSE_ID", toWarehouseProductBO.get("WAREHOUSE_ID"));
                            toLot.set("PRODUCT_ID", toWarehouseProductBO.get("PRODUCT_ID"));
                            SDK.getBOAPI().createDataBO("BO_EU_DNIVT_WAREHOUSE_PRODUCT_LOT", toLot, processExecutionContext.getUserContext(), conn);
                        }
                        if (pickQuantity <= 0)
                            break;

                    }
                }

            } else if (pickBO.getString("PICK_TYPE").equals("2"))//库存转移给客户
            {

                BO costBO = SDK.getBOAPI().query("BO_EU_DNCTT_CONTRACT_COST").connection(conn).addQuery("ID=", pickBO.getString("CONTRACT_COST_ID")).detail();

                //移库记录
                ProcessInstance transfeProcessIns = SDK.getProcessAPI().createBOProcessInstance("obj_e15a8fedeaeb43dc85aa258a7e1cffcf", processExecutionContext.getUserContext().getUID(), "库存转移");
                BO ivtTransfer = new BO();
                ivtTransfer.setBindId(transfeProcessIns.getId());
                ivtTransfer.set("FROM_WAREHOUSE_ID", pickBO.getString("WAREHOUSE_ID"));

                ivtTransfer.set("TO_ACCOUNT_ID", costBO.get("ACCOUNT_ID"));
                ivtTransfer.set("TO_CONTRACT_ID", costBO.get("CONTRACT_ID"));

                ivtTransfer.set("TO_PROJECT_ID", costBO.get("PROJECT_ID"));
                ivtTransfer.set("TO_TASK_ID", costBO.get("TASK_ID"));

                ivtTransfer.set("TYPE_ID", 1482);
                ivtTransfer.set("PRODUCT_ID", pickBO.getString("PRODUCT_ID"));
                ivtTransfer.set("QUANTITY", pickBO.get("PICK_QUANTITY"));
                ivtTransfer.set("SN", StringUtils.join(pickSerials, ","));//产品序列号
                SDK.getBOAPI().create("BO_EU_DNIVT_TRANSFER", ivtTransfer, transfeProcessIns, processExecutionContext.getUserContext(), conn);


                //减少库存
                BO fromWarehouseProductBO = SDK.getBOAPI().query("BO_EU_DNIVT_WAREHOUSE_PRODUCT").connection(conn).addQuery("PRODUCT_ID=", pickBO.getString("PRODUCT_ID")).addQuery("WAREHOUSE_ID=", pickBO.getString("WAREHOUSE_ID")).detail();
                fromWarehouseProductBO.set("QUANTITY", ObjToInt(fromWarehouseProductBO.get("QUANTITY")) - ObjToInt(pickBO.get("PICK_QUANTITY")));
                SDK.getBOAPI().update("BO_EU_DNIVT_WAREHOUSE_PRODUCT", fromWarehouseProductBO, conn);

                int pickQuantity = ObjToInt(pickBO.get("PICK_QUANTITY"));//拣货数量
                //减少批次
                List<BO> lots = SDK.getBOAPI().query("BO_EU_DNIVT_WAREHOUSE_PRODUCT_LOT").addQuery("BINDID=", fromWarehouseProductBO.getBindId()).addQuery("QUANTITY>", 0).orderByCreated().list();
                int cnt = 0;
                for (BO lot : lots) {
                    if (pickSerials.size() > 0) {
                        //序列化产品
                        boolean isIn = false;
                        String lotSN = lot.getString("SN");
                        lotSN = "," + lotSN + ",";
                        List<String> toSN = new ArrayList<>();
                        for (String sn : pickSerials) {
                            if (lotSN.contains("," + sn + ",")) {
                                isIn = true;
                                lotSN = lotSN.replace("," + sn + ",", ",");
                                toSN.add(sn);
                                cnt++;
                            }
                            if (cnt >= pickSerials.size())
                                break;
                        }
                        if (isIn) {
                            if (StringUtils.isNotBlank(lotSN)) {
                                lotSN = lotSN.replaceAll("^,+|,+$", "") // 移除首尾一个或多个逗号
                                        .replaceAll(",+", ",");     // 合并中间连续逗号
                                int count = (int) lotSN.chars().filter(c -> c == ',').count();
                                lot.set("SN", lotSN);
                                lot.set("QUANTITY", count + 1);
                            } else {
                                lot.set("SN", "");
                                lot.set("QUANTITY", 0);
                            }

                            //更新批次上序列号
                            SDK.getBOAPI().update("BO_EU_DNIVT_WAREHOUSE_PRODUCT_LOT", lot, conn);

                        }
                        if (cnt >= pickSerials.size())
                            break;
                    } else {
                        //无序列号产品
                        int toQuantity = ObjToInt(lot.get("QUANTITY"));
                        if (toQuantity >= pickQuantity) {
                            lot.set("QUANTITY", pickQuantity);
                            pickQuantity = 0;
                        } else {
                            lot.set("QUANTITY", 0);
                            pickQuantity -= toQuantity;
                        }
                        //更新批次上序列号
                        SDK.getBOAPI().update("BO_EU_DNIVT_WAREHOUSE_PRODUCT_LOT", lot, conn);
                        if (pickQuantity <= 0)
                            break;
                    }
                }
            }

            conn.commit();
        } catch (Exception e) {
            conn.rollback();
            throw new BPMNError("550", "库存转移失败");
        } finally {
            DBSql.close(conn);
        }

    }

    /**
     * 将Object转换为int
     * @param obj
     * @return
     */
    private int ObjToInt(Object obj) {
        if (obj == null)
            return 0;

        String objStr = obj.toString();
        if (objStr.equals(""))
            return 0;
        //如果有小数点，只取整数
        if (objStr.contains(".")) {
            objStr = objStr.substring(0, objStr.indexOf("."));
        }
        return Integer.parseInt(objStr);
    }


}
