package nc.bs.mmpac.pmo.pac0002.bp.rule;

import nc.bs.dao.DAOException;
import nc.bs.framework.common.NCLocator;
import nc.bs.trade.business.HYSuperDMO;
import nc.impl.pubapp.pattern.rule.IRule;
import nc.itf.uap.IUAPQueryBS;
import nc.jdbc.framework.processor.ColumnProcessor;
import nc.jdbc.framework.processor.MapProcessor;
import nc.vo.bd.defdoc.DefdocVO;
import nc.vo.mmpac.pmo.pac0002.entity.PMOAggVO;
import nc.vo.mmpac.pmo.pac0002.entity.PMOHeadVO;
import nc.vo.mmpac.pmo.pac0002.entity.PMOItemVO;
import nc.vo.pub.BusinessException;
import nc.vo.so.m30.entity.SaleOrderBVO;
import nccloud.baseapp.core.log.NCCForUAPLogger;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 流程生成订单保存时验证销售订单累计排产状态，并验收首付款比例 zhangxinah 适配2312
 */
public class saveBeforeCheckRule implements IRule<PMOAggVO> {

    @Override
    public void process(PMOAggVO[] vos) {
        // TODO Auto-generated method stub
        try {
            List<SaleOrderBVO> list = new ArrayList<SaleOrderBVO>();
            for (PMOAggVO vo : vos) {
                // 判断是否是需要控制的业务单元
                PMOHeadVO pmoHeadVO = vo.getParentVO();
                String pkstockorgStr = getPk_stockorg(pmoHeadVO.getPk_org());
                if (pkstockorgStr == null || pkstockorgStr.isEmpty()) {
                    return;
                }
                PMOItemVO[] iSuperVOs = vo.getChildrenVO();
                for (int i = 0; i < iSuperVOs.length; i++) {
                    PMOItemVO itemvo = iSuperVOs[i];
                    // 判断是否类型是否为30
                    if (itemvo.getVsrctype() == null || !itemvo.getVsrctype().equals("30")) {
                        return;
                    }

                    Map<String, Object> valMap = getVbdef6(itemvo.getVsrcbid(),itemvo.getCmoid());
                    if (valMap == null || valMap.isEmpty()) {
                        throw new BusinessException("无法关联到销售订单，无法保存！");
                    }
                    String code = valMap.get("code").toString();
                    LocalDateTime dbilldate = LocalDateTime.parse(valMap.get("dbilldate").toString(),
                            DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
                    LocalDateTime targetDate1 = LocalDateTime.parse("2025-06-27 00:00:00",
                            DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
                    List<String> defMap = checkOrgCtrl1();
                    if (!valMap.isEmpty()&& defMap.contains(code) && dbilldate.isBefore(targetDate1)) {
                        return;
                    }
                    // 销售发票表头pk_billtypecode=30-Cxx-12
                    if (valMap.get("pk_billtypecode").equals("30-Cxx-12")
                            || valMap.get("pk_billtypecode").equals("30-Cxx-02")
                            || valMap.get("pk_billtypecode").equals("30-Cxx-08")
                            || valMap.get("pk_billtypecode").equals("30-Cxx-13")
                            || valMap.get("pk_billtypecode").equals("30-Cxx-16")) {
                        return;
                    }
                    // 历史数据不考虑
                    String storedDateStr = (String) valMap.get("creationtime");
                    String targetDateStr = "2024-12-27 00:00:00";
                    DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
                    LocalDateTime storedDate = LocalDateTime.parse(storedDateStr, formatter);
                    LocalDateTime targetDate = LocalDateTime.parse(targetDateStr, formatter);
                    if (storedDate.isBefore(targetDate)) {
                        return;
                    }
                    if (valMap.get("vbdef12") == null) {
                        throw new BusinessException("生产订单明细" + (i + 1) + "，累计排产申请数量为0，无法保存！");
                    } else {
                        try {
                            double sQty = Double.parseDouble((String) valMap.get("vbdef12"));// 累计排产申请数量
                            Object ntotaloutnumsObj = valMap.get("nastnum");
                            String ntotaloutnums = (ntotaloutnumsObj != null) ? ntotaloutnumsObj.toString() : "";
                            double ntotaloutnum = (ntotaloutnums.isEmpty()) ? 0 : Double.parseDouble(ntotaloutnums);// 累计生产数量
                            double bdnum = itemvo.getNastnum().getDouble();
                            if (sQty < (ntotaloutnum + bdnum)) {
                                throw new BusinessException("生产订单明细" + (i + 1) + "，累计生产数量'" + (ntotaloutnum + bdnum)
                                        + "'大于销售订单累计排产申请数量'" + sQty + "'，无法保存！");
                            }
                        } catch (NumberFormatException e) {
                            throw new BusinessException("累计排产申请数量转化数值失败" + e);
                        }
                    }
                }
            }
        } catch (BusinessException e) {
            throw new RuntimeException(e);
        }
    }

    private Map<String, Object> getVbdef6(String vsrcbidStr,String cmoid) throws BusinessException {
        IUAPQueryBS queryBS = NCLocator.getInstance().lookup(IUAPQueryBS.class);
        String sql = " SELECT org_salesorg.CODE ,s.dbilldate, bt.pk_billtypecode,s.creationtime,b.vbdef12,d.nastnum FROM so_saleorder_b b\n"
                + "INNER JOIN so_saleorder s ON s.csaleorderid = b.csaleorderid\n"
                + " LEFT JOIN org_salesorg ON org_salesorg.PK_SALESORG = s.PK_ORG "
                + "left join (select mm_mo.Vsrcbid,sum(nastnum) as nastnum \n" + "from mm_mo\n" + "where mm_mo.dr=0\n"+" and cmoid !='"+cmoid+ "' "
                + "group by mm_mo.Vsrcbid) d on b.csaleorderbid=d.Vsrcbid\n"
                + "INNER JOIN bd_billtype bt on bt.pk_billtypeid=s.ctrantypeid\n" + "where b.csaleorderbid='"
                + vsrcbidStr + "' ";
        Map<String, Object> valList = (Map<String, Object>) queryBS.executeQuery(sql, new MapProcessor());
        return valList;
    }

    private String getPk_stockorg(String pk_stockorg) throws BusinessException {
        Map<String, String> defMap = checkOrgCtrl();
        if (defMap.isEmpty() || "".equals(defMap.getOrDefault("pmo", ""))) {
            return "";
        }
        String orgStr = defMap.getOrDefault("pmo", "");
        // 将数组转换为字符串，并添加单引号
        String newOrgStr = orgStr.replace(",", "','");
        String sql = " select pk_stockorg from org_stockorg where code in ('" + newOrgStr + "') and pk_stockorg='"
                + pk_stockorg + "' ";
        // NCCForUAPLogger.debug("pmo-getPk_stockorg-sql:" + sql);
        String saleorderPK = (String) getQueryService().executeQuery(sql, new ColumnProcessor());
        return saleorderPK;
    }

    private Map<String, String> checkOrgCtrl() {
        Map<String, String> map = new HashMap<String, String>();
        String strWhere = " pk_defdoclist in (select pk_defdoclist from bd_defdoclist where code='org-ctrl' and dr=0 )  and dr=0";
        try {
            DefdocVO[] defdocVOs = (DefdocVO[]) new HYSuperDMO().queryByWhereClause(DefdocVO.class, strWhere);
            if (defdocVOs != null && defdocVOs.length > 0) {
                for (DefdocVO defdocVO : defdocVOs) {
                    map.put(defdocVO.getCode().trim(), defdocVO.getMemo());
                }
            }
        } catch (DAOException e) {
            e.printStackTrace();
        }
        return map;
    }

    public IUAPQueryBS getQueryService() {
        return NCLocator.getInstance().lookup(IUAPQueryBS.class);
    }
    private List<String> checkOrgCtrl1() {
        List<String> list = new ArrayList<>();
        String strWhere = " pk_defdoclist in (select pk_defdoclist from bd_defdoclist where code='org-ctrl' and dr=0 )  and dr=0";
        try {
            DefdocVO[] defdocVOs = (DefdocVO[]) new HYSuperDMO().queryByWhereClause(DefdocVO.class, strWhere);
            if (defdocVOs != null && defdocVOs.length > 0) {
                for (DefdocVO defdocVO : defdocVOs) {
                    if(defdocVO.getCode().equals("pmol")){
                        list= Arrays.stream(defdocVO.getMemo().split(",")).map(String::trim).collect(Collectors.toList());
                    }
                }
            }
        } catch (DAOException e) {
            e.printStackTrace();
        }
        return list;
    }
}
