package com.awspaas.user.apps.donenow_ivt.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.commons.database.RowMap;
import com.actionsoft.bpms.server.UserContext;
import com.actionsoft.bpms.util.DBSql;
import com.actionsoft.sdk.local.SDK;
import com.actionsoft.sdk.local.api.Logger;
import com.awspaas.user.apps.donenow_ivt.constant.IVTConstant;
import com.awspaas.user.apps.donenow_ivt.service.PaymentPlanService;
import org.apache.commons.lang3.StringUtils;

import java.util.*;

public class ivtOrderProcessAfterComplete extends ExecuteListener {
    public String getDescription() {
        return "流程结束事件：采购订单审批完成后触发";
    }

    private static final Logger logger = SDK.getLogAPI().getLogger(ivtOrderProcessAfterComplete.class);//记录日志
    private final String[] excludesArray = new String[]{"ID", "ORGID", "BINDID", "CREATEDATE", "CREATEUSER", "UPDATEDATE", "UPDATEUSER"};

    /**
     * 采购订单审批完成后触发
     * @param processExecutionContext
     * @throws Exception
     */
    @Override
    public void execute(ProcessExecutionContext processExecutionContext) throws Exception {
        String BINDID = processExecutionContext.getProcessInstance().getId();
        UserContext uc = processExecutionContext.getUserContext();

        BO purchaseOrder = SDK.getBOAPI().getByProcess("BO_EU_DNIVT_ORDER", BINDID);
        purchaseOrder.set("STATUS_ID", "2152");//采购中
        //SDK.getBOAPI().update("BO_EU_DNIVT_ORDER", purchaseOrder);

        String orderId = purchaseOrder.getId(); // 获取订单ID
        System.out.println("采购订单审批完成，开始自动生成付款计划，订单ID：" + orderId);

        List<BO> orderProducts = SDK.getBOAPI().query("BO_EU_DNIVT_ORDER_PRODUCT").bindId(BINDID).list();

        boolean isAllService = true;

        for (BO orderProduct : orderProducts) {

            orderProduct.set("ORDER_ID", purchaseOrder.getId());
            SDK.getBOAPI().update("BO_EU_DNIVT_ORDER_PRODUCT", orderProduct);

            if (orderProduct.get("CONTRACT_SERVICE_ID") == null || StringUtils.isBlank(orderProduct.getString("CONTRACT_SERVICE_ID"))) {
                isAllService = false;
            }

            if (StringUtils.isNotBlank(orderProduct.getString("CONTRACT_COST_ID"))) {
                BO cost = SDK.getBOAPI().get("BO_EU_DNCTT_CONTRACT_COST", orderProduct.getString("CONTRACT_COST_ID"));

                cost.set("STATUS_ID", "1235");//更新状态 采购中
                SDK.getBOAPI().update("BO_EU_DNCTT_CONTRACT_COST", cost);

                //排除重复提交
                /*
                String sql = "SELECT ID FROM BO_EU_DNCTT_CONTRACT_COST_PRODUCT WHERE ORDER_ID=? AND CONTRACT_COST_ID=?";
                String id = DBSql.getString(sql, new Object[]{purchaseOrder.getId(), cost.getId()});
                SDK.getBOAPI().remove("BO_EU_DNCTT_CONTRACT_COST_PRODUCT", id);//删除旧数据
                 */

                String costProductID = DBSql.getString("SELECT ID FROM BO_EU_DNCTT_CONTRACT_COST_PRODUCT WHERE ORDER_ID=? AND CONTRACT_COST_ID=?", new Object[]{purchaseOrder.getId(), cost.getId()});
                if (StringUtils.isBlank(costProductID)) {
                    ProcessInstance processInstance = SDK.getProcessAPI().createBOProcessInstance("obj_6bc913271069455abbd516c556b26d31", processExecutionContext.getUserContext().getUID(), "合同产品物流管理");

                    //提交采购订单添加成本产品
                    BO costProduct = new BO();
                    costProduct.setBindId(processInstance.getId());
                    costProduct.set("ORDER_ID", purchaseOrder.getId());
                    costProduct.set("CONTRACT_COST_ID", cost.getString("ID"));
                    costProduct.set("STATUS_ID", "2156");//采购中
                    costProduct.set("QUANTITY", orderProduct.get("QUANTITY"));
                    costProduct.set("WAREHOUSE_ID", orderProduct.get("WAREHOUSE_ID"));
                    costProduct.set("SN", DBSql.getString("SELECT GROUP_CONCAT(SN) FROM BO_EU_DNIVT_WAREHOUSE_PRODUCT_LOT WHERE ORDER_PRODUCT_ID=?", new Object[]{orderProduct.getId()}));
                    costProduct.set("OLD_QUANTITY", costProduct.get("QUANTITY"));//配送数量

                    costProduct.set("SHIPPING_TYPE_ID", null);

                    costProduct.set("COST_CODE_ID", cost.getString("COST_CODE_ID"));
                    costProduct.set("COST_CODE_NAME", cost.getString("COST_CODE_NAME"));

                    //服务采购审批完成，状态直接改为已配送。
                    if (costProduct.getString("COST_CODE_ID").equals("307")) {
                        costProduct.set("STATUS_ID", "2159");//已配送
                    }
                    costProduct.set("UNIT_COST", orderProduct.get("UNIT_COST"));
                    dn.recordFormChanges.record(uc, costProduct, "采购产品审批后新增");
                    SDK.getBOAPI().create("BO_EU_DNCTT_CONTRACT_COST_PRODUCT", costProduct, processInstance, uc);
                } else {
                    BO costProduct = SDK.getBOAPI().get("BO_EU_DNCTT_CONTRACT_COST_PRODUCT", costProductID);
                    costProduct.set("ORDER_ID", purchaseOrder.getId());
                    costProduct.set("CONTRACT_COST_ID", cost.getString("ID"));
                    costProduct.set("STATUS_ID", "2156");//采购中
                    costProduct.set("QUANTITY", orderProduct.get("QUANTITY"));
                    costProduct.set("WAREHOUSE_ID", orderProduct.get("WAREHOUSE_ID"));
                    costProduct.set("SN", DBSql.getString("SELECT GROUP_CONCAT(SN) FROM BO_EU_DNIVT_WAREHOUSE_PRODUCT_LOT WHERE ORDER_PRODUCT_ID=?", new Object[]{orderProduct.getId()}));
                    costProduct.set("OLD_QUANTITY", costProduct.get("QUANTITY"));//配送数量
                    costProduct.set("SHIPPING_TYPE_ID", null);
                    costProduct.set("COST_CODE_ID", cost.getString("COST_CODE_ID"));
                    costProduct.set("COST_CODE_NAME", cost.getString("COST_CODE_NAME"));

                    costProduct.set("UNIT_COST", orderProduct.get("UNIT_COST"));

                    //服务采购审批完成，状态直接改为已配送。
                    if (costProduct.getString("COST_CODE_ID").equals("307")) {
                        costProduct.set("STATUS_ID", "2159");//已配送
                    }

                    dn.recordFormChanges.record(uc, costProduct, "采购产品审批后新增");
                    SDK.getBOAPI().update("BO_EU_DNCTT_CONTRACT_COST_PRODUCT", costProduct);
                }

                //已完成拣货或者在采购中

                //仍需数量：
                String needsql = "SELECT a.QUANTITY-SUM(ifnull(b.QUANTITY,0)) FROM BO_EU_DNCTT_CONTRACT_COST a LEFT JOIN BO_EU_DNCTT_CONTRACT_COST_PRODUCT b ON a.ID=b.CONTRACT_COST_ID AND b.CLOSED = 0 WHERE a.ID=?";
                if (DBSql.getInt(needsql, new Object[]{cost.getId()}) <= 0) {
                    //更新状态
                    cost.set("STATUS_ID", 1235); //1235 采购中
                    SDK.getBOAPI().update("BO_EU_DNCTT_CONTRACT_COST", cost);
                } else {
                    //1237//已配送
                    needsql = "SELECT a.QUANTITY-SUM(ifnull(b.QUANTITY,0)) FROM BO_EU_DNCTT_CONTRACT_COST a LEFT JOIN BO_EU_DNCTT_CONTRACT_COST_PRODUCT b ON a.ID=b.CONTRACT_COST_ID AND b.CLOSED = 0 WHERE b.STATUS_ID<2159 AND a.ID=?";
                    if (DBSql.getInt(needsql, new Object[]{cost.getId()}) <= 0) {
                        cost.set("STATUS_ID", 1237); //1237 已配送
                        SDK.getBOAPI().update("BO_EU_DNCTT_CONTRACT_COST", cost);
                    }
                }


                //更新采购订单号
                String PURCHASE_ORDER_NO = DBSql.getString("SELECT GROUP_CONCAT(PURCHASE_ORDER_NO) FROM " + IVTConstant.BO_EU_DNIVT_ORDER + " WHERE CLOSED=0 AND ISEND=1 AND ID IN (SELECT ORDER_ID FROM BO_EU_DNIVT_ORDER_PRODUCT WHERE CONTRACT_COST_ID=?) ", new Object[]{cost.getString("ID")});
                DBSql.update("UPDATE BO_EU_DNCTT_CONTRACT_COST SET PURCHASE_ORDER_NO=? WHERE ID=?", new Object[]{PURCHASE_ORDER_NO, cost.getString("ID")});

            }

        }

        if (isAllService) {

            purchaseOrder.set("STATUS_ID", "2150");//已配送

        }
        SDK.getBOAPI().update("BO_EU_DNIVT_ORDER", purchaseOrder);

        String VENDOR_ACCOUNT_ID = purchaseOrder.getString("VENDOR_ACCOUNT_ID");//供应商账户ID

        //生成付款计划-- 胡磊 旧版
        //createPaymentPlan(uc,orderId);

/*****************************************2025年10月24日  张耀 生成付款计划********************************************/
        logger.info("生成付款计划");

        PaymentPlanService.getInstance().createPaymentPlan(uc, orderId);


    }

    /**
     * 生成采购计划
     * @param uc
     * @param orderId
     */
    private void createPaymentPlan(UserContext uc, String orderId) {

        System.out.println("==== 开始执行自动生成付款计划逻辑 ====");
        try {

            List<Map<String, Object>> servicePlanData = queryPaymentPlan(uc, orderId);
            boolean isServiceOrder = !servicePlanData.isEmpty();
            System.out.println("==== 订单类型判断：" + (isServiceOrder ? "服务类" : "非服务类") + "，服务类计划数量：" + servicePlanData.size() + " ====");

            List<Map<String, Object>> payAmounts = queryPayAmount(uc, orderId);
            boolean hasValidPayment = payAmounts.stream().anyMatch(amountMap -> {
                Double amount = (Double) amountMap.get("实际付款金额");
                return amount != null && amount > 0;
            });
            System.out.println("==== 有效付款检查结果：" + (hasValidPayment ? "存在有效付款" : "无有效付款") + " ====");

            if (hasValidPayment) {
                System.out.println("==== 因存在有效付款，终止付款计划生成 ====");
                return;
            }

            int deletedCount = deleteUnpaidPaymentPlan(uc, orderId);
            System.out.println("==== 已删除旧未付款计划数量：" + deletedCount + " ====");

            if (isServiceOrder) {
                int createCount = 0;
                for (Map<String, Object> plan : servicePlanData) {
                    String planDate = (String) plan.get("计划付款时间");
                    Double planAmount = (Double) plan.get("计划付款金额");
                    if (StringUtils.isNotBlank(planDate) && planAmount != null && planAmount > 0) {
                        createPaymentPlan(uc, orderId, planDate, planAmount);
                        createCount++;
                    }
                }
                System.out.println("==== 服务类付款计划创建完成，成功创建：" + createCount + "条 ====");
            } else {
                Map<String, Object> dateInfo = queryNonServiceOrderDate(uc, orderId);
                Map<String, Object> priceInfo = queryNonServiceOrderPrice(uc, orderId);
                System.out.println("==== 非服务类订单 - 日期信息：" + (dateInfo != null ? dateInfo : "无数据") + "，价格信息：" + (priceInfo != null ? priceInfo : "无数据") + " ====");

                if (dateInfo != null && priceInfo != null) {
                    String planDate = (String) dateInfo.get("EXPECTED_SHIP_DATE");
                    Double planAmount = (Double) priceInfo.get("cost_total");

                    if (StringUtils.isNotBlank(planDate)) {
                        createPaymentPlan(uc, orderId, planDate, planAmount);
                        System.out.println("==== 非服务类付款计划创建完成，日期：" + planDate + "，金额：" + planAmount + " ====");
                    } else {
                        throw new Exception("非服务类订单数据不完整：日期=" + planDate + "，金额=" + planAmount);
                    }
                } else {
                    throw new Exception("未查询到非服务类订单的日期或价格信息");
                }
            }

            System.out.println("==== 订单【" + orderId + "】付款计划自动生成流程全部完成 ====");
        } catch (Exception e) {
            System.err.println("==== 自动生成付款计划失败：" + e.getMessage() + " ====");
            e.printStackTrace();
        }

    }

    private List<Map<String, Object>> queryPaymentPlan(UserContext uc, String orderId) {
        if (StringUtils.isBlank(orderId)) {
            return Collections.emptyList();
        }

        String mainSql = "SELECT " + "a.order_id 采购订单id, " + "a.CONTRACT_SERVICE_ID 合同服务ID, " + "b.PERIOD_END_DATE 计划付款时间, " + "b.PERIOD_COST 计划付款金额 " + "FROM `BO_EU_DNIVT_ORDER_PRODUCT` a " + "JOIN `BO_EU_DNCTT_CONTRACT_SERVICE_PERIOD` b " + "ON a.CONTRACT_SERVICE_ID = b.CONTRACT_SERVICE_ID " + "WHERE a.ORDER_ID = ?";
        List<RowMap> mainRowMaps = DBSql.getMaps(mainSql, new Object[]{orderId});

        List<Map<String, Object>> resultList = new ArrayList<>();
        Set<String> processedServiceIds = new HashSet<>();

        if (mainRowMaps != null && !mainRowMaps.isEmpty()) {
            for (RowMap mainRow : mainRowMaps) {
                Map<String, Object> plan = new HashMap<>();
                plan.put("order_id", mainRow.getString("采购订单id"));
                plan.put("计划付款时间", mainRow.getString("计划付款时间"));
                plan.put("计划付款金额", mainRow.getDouble("计划付款金额"));
                resultList.add(plan);

                String contractServiceId = mainRow.getString("合同服务ID");
                if (StringUtils.isNotBlank(contractServiceId) && !processedServiceIds.contains(contractServiceId)) {
                    processedServiceIds.add(contractServiceId);

                    String adjustSql = "SELECT " + "effective_date 计划付款时间, " + "prorated_cost_change 计划付款金额 " + "FROM `BO_EU_DNCTT_CONTRACT_SERVICE_ADJUST` " + "WHERE CAST(CONTRACT_SERVICE_ID AS CHAR) = ?";
                    List<RowMap> adjustRowMaps = DBSql.getMaps(adjustSql, new Object[]{contractServiceId});

                    if (adjustRowMaps != null && !adjustRowMaps.isEmpty()) {
                        for (RowMap adjustRow : adjustRowMaps) {
                            Map<String, Object> adjustPlan = new HashMap<>();
                            adjustPlan.put("order_id", orderId);
                            adjustPlan.put("计划付款时间", adjustRow.getString("计划付款时间"));
                            adjustPlan.put("计划付款金额", adjustRow.getDouble("计划付款金额"));
                            resultList.add(adjustPlan);
                        }
                    }
                }
            }
        }
        return resultList;
    }

    private List<Map<String, Object>> queryPayAmount(UserContext uc, String orderId) {
        if (StringUtils.isBlank(orderId)) {
            return Collections.emptyList();
        }

        String sql = "select " + "ORDER_ID 采购订单id, " + "PAY_AMOUNT 实际付款金额 " + "from `BO_EU_DNIVT_ORDER_PAYMENT_PLAN` " + "where ORDER_ID = ?";
        List<RowMap> rowMaps = DBSql.getMaps(sql, new Object[]{orderId});

        List<Map<String, Object>> resultList = new ArrayList<>();
        if (rowMaps != null && !rowMaps.isEmpty()) {
            for (RowMap row : rowMaps) {
                Map<String, Object> amountInfo = new HashMap<>();
                amountInfo.put("order_id", orderId);
                amountInfo.put("实际付款金额", row.getDouble("实际付款金额"));
                resultList.add(amountInfo);
            }
        }
        return resultList;
    }


    private int deleteUnpaidPaymentPlan(UserContext uc, String orderId) {
        if (StringUtils.isBlank(orderId)) {
            return 0;
        }

        String sql = "delete from BO_EU_DNIVT_ORDER_PAYMENT_PLAN where ORDER_ID = ? and (PAY_AMOUNT is null or PAY_AMOUNT = 0)";
        return DBSql.update(sql, new Object[]{orderId});
    }


    private void createPaymentPlan(UserContext uc, String orderId, String planDate, Double planAmount) throws Exception {
        // 1. 原有参数校验（保持不变）
        if (StringUtils.isBlank(orderId) || StringUtils.isBlank(planDate) || planAmount == null) {
            throw new Exception("创建付款计划参数不完整：orderId=" + orderId + "，planDate=" + planDate + "，planAmount=" + planAmount);
        }

        // 2. 新增：通过orderId查询订单表，获取VENDOR_ACCOUNT_ID（遵循当前类SQL风格）
        String queryVendorSql = "select VENDOR_ACCOUNT_ID from BO_EU_DNIVT_ORDER where id = ?";
        String vendorAccountId = DBSql.getString(queryVendorSql, new Object[]{orderId});
        // 处理查询结果（空值/无数据时抛异常，与现有异常风格一致）
        if (StringUtils.isBlank(vendorAccountId)) {
            throw new Exception("创建付款计划失败：订单不存在或VENDOR_ACCOUNT_ID为空，orderId=" + orderId);
        }
        System.out.println("==== 查询订单表成功，VENDOR_ACCOUNT_ID=" + vendorAccountId + " ====");

        // 3. 原有流程实例创建（保持不变）
        ProcessInstance processInstance = SDK.getProcessAPI().createProcessInstance("obj_5cb4ae4a42944fd0a9a284ff4c64c65d", uc.getUID(), "付款计划");
        System.out.println("==== 付款计划流程实例创建成功，bindId=" + processInstance.getId() + " ====");

        // 4. 构建BO对象（新增：设置ACCOUNT_PAYEE=查询到的VENDOR_ACCOUNT_ID）
        BO bo = new BO();
        bo.setBindId(processInstance.getId());
        bo.set("ORDER_ID", orderId);
        bo.set("PLAN_DATE", planDate);
        bo.set("PLAN_AMOUNT", planAmount);
        bo.set("ACCOUNT_PAYEE", vendorAccountId); // 关键新增：赋值ACCOUNT_PAYEE
        System.out.println("==== BO对象构建完成，ACCOUNT_PAYEE=" + vendorAccountId + " ====");

        // 5. 原有业务数据创建（保持不变）
        SDK.getBOAPI().createDataBO("BO_EU_DNIVT_ORDER_PAYMENT_PLAN", bo, uc);
        System.out.println("==== 付款计划数据创建成功，orderId=" + orderId + " ====");
    }


    private Map<String, Object> queryNonServiceOrderDate(UserContext uc, String orderId) {
        if (StringUtils.isBlank(orderId)) {
            return null;
        }

        String sql = "select EXPECTED_SHIP_DATE " + "from `BO_EU_DNIVT_ORDER` " + "where id = ? ";
        String expectedShipDate = DBSql.getString(sql, new Object[]{orderId});

        if (StringUtils.isBlank(expectedShipDate)) {
            return null;
        }

        Map<String, Object> dateInfo = new HashMap<>();
        dateInfo.put("order_id", orderId);
        dateInfo.put("EXPECTED_SHIP_DATE", expectedShipDate);
        return dateInfo;
    }


    private Map<String, Object> queryNonServiceOrderPrice(UserContext uc, String orderId) {
        // 入参校验：订单ID为空返回null（与日期方法风格一致）
        if (StringUtils.isBlank(orderId)) {
            return null;
        }

        // SQL查询：求和 cost_total 字段（数据库字段正确，无需修改）
        String sql = "select sum(`cost_total`) " + "from `BO_EU_DNIVT_ORDER_PRODUCT` " + "where order_id = ? ";
        String totalCostStr = DBSql.getString(sql, new Object[]{orderId});

        // 空值处理：查询结果为空返回null（与日期方法风格一致）
        if (StringUtils.isBlank(totalCostStr)) {
            return null;
        }

        // 数值转换：字符串转Double（异常时返回null）
        Double totalCost;
        try {
            totalCost = Double.parseDouble(totalCostStr);
        } catch (NumberFormatException e) {
            return null;
        }

        // 结果封装：返回字段名改为 cost_total（小写+下划线，与前端完全对齐）
        Map<String, Object> priceInfo = new HashMap<>();
        priceInfo.put("order_id", orderId);
        priceInfo.put("cost_total", totalCost); // 关键修改：字段名从 TOTAL_COST 改为 cost_total
        return priceInfo;
    }




}
