package nccloud.web.mmpac.pickm.action;

import nc.bs.dao.BaseDAO;
import nc.bs.dao.DAOException;
import nc.bs.framework.common.InvocationInfoProxy;
import nc.itf.ic.m4a.IGeneralInMaintain;
import nc.itf.mmpac.pickm.IPickmQueryService;
import nc.itf.pu.m20.IPraybillApprove;
import nc.itf.pu.m20.IPraybillMaintain;
import nc.itf.scctpub.reference.uap.pf.PfServiceScmUtil;
import nc.itf.uap.pf.busiflow.PfButtonClickContext;
import nc.jdbc.framework.processor.ColumnProcessor;
import nc.jdbc.framework.processor.MapListProcessor;
import nc.util.mmf.busi.service.PFPubService;
import nc.util.mmf.framework.base.MMValueCheck;
import nc.vo.ic.m4a.entity.GeneralInVO;
import nc.vo.mmpac.pickm.entity.AggPickmVO;
import nc.vo.mmpac.pickm.entity.PickmHeadVO;
import nc.vo.mmpac.pickm.entity.PickmItemVO;
import nc.vo.pu.m20.entity.PraybillHeaderVO;
import nc.vo.pu.m20.entity.PraybillItemVO;
import nc.vo.pu.m20.entity.PraybillVO;
import nc.vo.pub.AggregatedValueObject;
import nc.vo.pub.BusinessException;
import nc.vo.pub.CircularlyAccessibleValueObject;
import nc.vo.pub.ISuperVO;
import nc.vo.pub.compiler.PfParameterVO;
import nc.vo.pub.lang.UFDouble;
import nccloud.api.rest.utils.ResultMessageUtil;
import nccloud.dto.mmpac.pickm.pub.entity.PickmQueryInfoDTO;
import nccloud.framework.core.exception.ExceptionUtils;
import nccloud.framework.core.json.IJson;
import nccloud.framework.service.ServiceLocator;
import nccloud.framework.web.action.itf.ICommonAction;
import nccloud.framework.web.container.IRequest;
import nccloud.framework.web.json.JsonFactory;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 备料计划转请购单
 */
public class PickmToBuyingreqAction implements ICommonAction {
    @Override
    public Object doAction(IRequest iRequest) {
        String read = iRequest.read();
        IJson json = JsonFactory.create();
        try {
            // 获取请求查询信息
            PickmQueryInfoDTO paramDTO = json.fromJson(read, PickmQueryInfoDTO.class);
            // 获取主键
            String[] cpickmids = paramDTO.getCpickmids();
//            String[] cpickmbids = paramDTO.getCpickmbids();
//            if (MMValueCheck.isEmpty(cpickmids) && (null == cpickmbids || cpickmbids.length == 0)) {
//                return null;
//            }
            AggPickmVO[] aggVOs = null;
            IPickmQueryService service = ServiceLocator.find(IPickmQueryService.class);
            if (MMValueCheck.isNotEmpty(cpickmids)) {
                aggVOs = service.queryBillsByPks(cpickmids);
            }
            if (MMValueCheck.isEmpty(aggVOs)) {
                /*@res "单据已被修改或删除，请刷新界面重新操作！"*/
                ExceptionUtils.wrapBusinessException(nc.vo.ml.NCLangRes4VoTransl.getNCLangRes().getStrByID("5008100_0", "05008100-0009"));
            }
//            AggPickmVO[] aggPickmVOS=processAggVOs(aggVOs);
            // 转换数据
            AggPickmVO[] vos =  processAggVOs(aggVOs);
            if(vos.length == 0){
                throw new BusinessException("未检测到符合生成请购单数据，不能生成！");
            }
            PraybillVO[] prayVOs = convertToGeneralInVO(vos, null);
            List<Map<String,Object>> updateList = new ArrayList<>();
            for (PraybillVO prayVO : prayVOs) {
                for (int j=0;j<prayVO.getChildrenVO().length;j++) {
                    Map<String,Object> map = new HashMap<>();
                    PraybillItemVO praybillItemVO=(PraybillItemVO)  prayVO.getChildrenVO()[j];
                    ((PraybillItemVO) prayVO.getChildrenVO()[j]).setCrowno(String.valueOf(j*10+10));
                    map.put("num",praybillItemVO.getNastnum());
                    map.put("pk",praybillItemVO.getCfirstbid());
                    updateList.add(map);
                }

            }

            List<String> pk =new ArrayList<>();
            for (AggPickmVO prayVO : vos) {
                PickmItemVO[] items = (PickmItemVO[]) prayVO.getChildren(PickmItemVO.class);
                for (int j=0;j<items.length;j++) {
//                    items[j].getNnum();
                    pk.add(items[j].getCpickm_bid());
                }
            }

            IPraybillMaintain maintain= ServiceLocator.find(IPraybillMaintain.class);
            PraybillVO[] insertVos = maintain.insert(prayVOs);
            IPraybillApprove approve= ServiceLocator.find(IPraybillApprove.class);
            Object res= PfServiceScmUtil.processBatch("APPROVE", "20", insertVos, null, null);
//            approve.approve(insertVos,null,null);
//            maintain.
            Map<String, Object> returnMap = new HashMap<>();
            returnMap.put("data", res);
            returnMap.put("success", true);
            if(!pk.isEmpty()){
                updetaPmo(pk);
            }
            if(!updateList.isEmpty()){
//                回写已经下达数量
                updetaPmoNum(updateList);
            }
            return returnMap;
        } catch (BusinessException e) {
            try {
                throw new BusinessException(e.getMessage());
            } catch (BusinessException ex) {
                throw new RuntimeException(ex);
            }
        }

    }
    private void updetaPmoNum(List<Map<String, Object>> updateList) throws DAOException {
        BaseDAO dao = new BaseDAO();
        for (Map<String, Object> updateMap : updateList) {
            String sql = " update  mm_pickm_b set vbdef16 = '"+((UFDouble)updateMap.get("num")).toString()+"'  where mm_pickm_b.cpickm_bid ='" + updateMap.get("pk") + "'";

            dao.executeUpdate(sql);
        }


    }
    private PraybillVO[] convertToGeneralInVO(AggregatedValueObject[] sourceBillVOs, PfParameterVO srcParaVo)
            throws BusinessException {
        // 来源交易类型或单据类型，需要在单据类型中注册
        String srcBillOrTranstype = "55A3";
        // 目标交易类型或单据类型，需要在单据类型中注册
        String destBillOrTranstype = "20";
        // classifyMode int型参数，调用模式，参照PfButtonClickContext中定义，代码中调用为接口方式 ClassifyByItfdef
        int classifyMode = PfButtonClickContext.ClassifyByItfdef;
        PraybillVO[] inVOS = (PraybillVO[]) PFPubService.runChangeData(srcBillOrTranstype, destBillOrTranstype, sourceBillVOs, srcParaVo, classifyMode);
        if (MMValueCheck.isEmpty(inVOS)) {
            ExceptionUtils.wrapBusinessException("备料计划转换请购单失败");
        }
        for (PraybillVO inVO : inVOS) {
            // 其它入库单的仓库、交易类型取自【业务参数设置】的默认值
            PraybillHeaderVO head = inVO.getHVO();
            String ctrantypeid = getValueByCondtion("bd_billtype", "  pk_billtypeid ", "  istransaction = 'Y'  and nvl ( islock, 'N' ) = 'N' and parentbilltype = '20' and pk_group = '"
                    + InvocationInfoProxy.getInstance().getGroupId() + "' and  pk_billtypecode = '" + "20-01" + "' ");
            head.setCtrantypeid(ctrantypeid);
            // head.setCwarehouseid("");
        }


        List<PraybillVO> resultList = new ArrayList<>();
        Map<Object, List<PraybillVO>> groupMap = new HashMap<>();

        for (PraybillVO vo : inVOS) {
            Object pk_org = vo.getHVO().getPk_org();
            groupMap.computeIfAbsent(pk_org, k -> new ArrayList<>()).add(vo);
        }
        for (Map.Entry<Object, List<PraybillVO>> entry : groupMap.entrySet()) {
            List<PraybillVO> group = entry.getValue();

            // 修改1：使用ISuperVO列表收集子对象
            List<PraybillItemVO> mergedChildren = new ArrayList<PraybillItemVO>();
            for (PraybillVO vo : group) {
                for (PraybillItemVO child : vo.getBVO()) {
                    mergedChildren.add(child);
                }
            }
            if(mergedChildren.isEmpty()){
                continue;
            }
            PraybillVO newVO = new PraybillVO();
            newVO.setParent(group.get(0).getHVO());
            // 修改2：转换为ISuperVO数组
            newVO.setChildren(PickmItemVO.class, mergedChildren.toArray(new PraybillItemVO[0]));

            resultList.add(newVO);
        }
        return resultList.toArray(new PraybillVO[0]);
//        return inVOS;
    }
    private String getValueByCondtion(String tablename, String fieldname, String contion) throws BusinessException {
        BaseDAO dao = new BaseDAO();

        String result = "";
        StringBuffer sb = new StringBuffer();
        sb.append(" SELECT " + fieldname + "  FROM " + tablename + "  ");
        sb.append(" WHERE nvl(" + tablename + " .dr,0)= 0  ");
        sb.append(" and " + contion + " ");
        result = (String) dao.executeQuery(sb.toString(), new ColumnProcessor());
        return result;
    }

    private void updetaPmo(List<String> arrayList) throws DAOException {
        String result = "";
        StringBuilder sb = new StringBuilder();
        if (arrayList.size() > 1) {
            for (int i = 0; i < arrayList.size(); i++) {


                sb.append("'").append(arrayList.get(i)).append("'");
                if (i < arrayList.size() - 1) {
                    sb.append(",");
                }
            }

            result = sb.toString();
        } else {
            result = "'" + (String) arrayList.get(0) + "'";
        }
        String sql = " update  mm_pickm_b set vbdef30='Y'  where mm_pickm_b.cpickm_bid in(" + result + ")";

        BaseDAO dao = new BaseDAO();
        dao.executeUpdate(sql);
    }


    public AggPickmVO[] processAggVOs(AggPickmVO[] aggVOs) throws DAOException {
//        Map<Object, List<AggPickmVO>> groupMap = new HashMap<>();
//
//        for (AggPickmVO vo : aggVOs) {
//            Object pk_org = vo.getParentVO().getPk_org();
//            groupMap.computeIfAbsent(pk_org, k -> new ArrayList<>()).add(vo);
//        }

        List<AggPickmVO> resultList = new ArrayList<>();

//        for (Map.Entry<Object, List<AggPickmVO>> entry : groupMap.entrySet()) {
//            List<AggPickmVO> group = entry.getValue();

            // 修改1：使用ISuperVO列表收集子对象
            List<PickmItemVO> mergedChildren = new ArrayList<PickmItemVO>();
            for (AggPickmVO vo : aggVOs) {
                PickmItemVO[] items = (PickmItemVO[]) vo.getChildren(PickmItemVO.class);
                if (items != null) {
                    for (PickmItemVO child : items) {
                        //                     未下达子表 切   若物料类型为“采购件”，则备料计划中所有采购件生成一张请购单
                        if(null != child.getAttributeValue("vbdef30") && child.getAttributeValue("vbdef30").equals("Y") ){
//                            如果已经下达数量 大于等于 需要下达数量 则不可继续下达
                            if(null==child.getVbdef16() || (new UFDouble(child.getVbdef16()).compareTo(child.getNplanoutnum().sub(null!=child.getNaccoutastnum() ?child.getNaccoutastnum():UFDouble.ZERO_DBL)) >=0)){
                                continue;
                            }else{

                            }
//                            if(new UFDouble(child.getVbdef16()).compareTo(child.getNplanoutnum().add(child.getNaccoutastnum())) >0){
//
//                            }else{
//
//                            }
                        }
                        String materalType = child.getVbdef14();
                        if(null == materalType){
//                            MR=制造件;
//                            PR=采购件;
//                            1=制造件;
//                            2=采购件;
                            String sql = " select cmaterialvid from mm_pickm  where cpickmid='" + child.getCpickmid() + "'  and dr=0";

                            BaseDAO dao = new BaseDAO();
                            String hmateral = (String) dao.executeQuery(sql, new ColumnProcessor());


                            sql="SELECT\n" +
                                    "\n" +
                                    "  bd_defdoc.code \n" +
                                    "FROM\n" +
                                    "  bd_bom_b \n" +
                                    "  LEFT JOIN bd_defdoc ON bd_bom_b.vdef1 = bd_defdoc.pk_defdoc\n" +
                                    "WHERE\n" +
                                    "  bd_bom_b.cbomid in (select distinct bd_bom.cbomid from bd_bom bd_bom where ( bd_bom.pk_org = '"+child.getPk_org()+"' AND bd_bom.hcmaterialid = '"+hmateral+"' AND bd_bom.hfbomcategory = 1 AND bd_bom.hbcustomized = 'N' ) and bd_bom.dr = 0 and bd_bom.hbcustomized = 'N' and bd_bom.fbomtype != 3 ) \n" +
                                    "  AND bd_bom_b.dr = 0 and bd_bom_b.cmaterialvid='" + child.getCbmaterialvid() + "'";
                            String bomcode = (String) dao.executeQuery(sql, new ColumnProcessor());


                            //                            MR=制造件;
                            //                            PR=采购件;
                            if(null==bomcode){
                                String secondsql=" SELECT\n" +
                                        "\n" +
                                        "  bd_defdoc.code\n" +
                                        "FROM\n" +
                                        "  bd_bom_b \n" +
                                        "  LEFT JOIN bd_defdoc ON bd_bom_b.vdef1 = bd_defdoc.pk_defdoc\n" +
                                        "WHERE\n" +
                                        "  bd_bom_b.cbomid in (select  bd_bom.cbomid from bd_bom bd_bom WHERE  bd_bom.pk_org = '"+child.getPk_org()+"' and bd_bom.hcmaterialid in (SELECT\n" +
                                        "   bd_bom_b.cmaterialvid \n" +
                                        "FROM\n" +
                                        "  bd_bom_b \n" +
                                        "  LEFT JOIN bd_defdoc ON bd_bom_b.vdef1 = bd_defdoc.pk_defdoc\n" +
                                        "WHERE\n" +
                                        "  bd_bom_b.cbomid in (select distinct bd_bom.cbomid from bd_bom bd_bom where ( bd_bom.pk_org = '"+child.getPk_org()+"' AND bd_bom.hcmaterialid = '"+hmateral+"' AND bd_bom.hfbomcategory = 1 AND bd_bom.hbcustomized = 'N' ) and bd_bom.dr = 0 and bd_bom.hbcustomized = 'N' and bd_bom.fbomtype != 3 ) \n" +
                                        "AND bisvirtual='Y')  AND bd_bom.hfbomcategory = 1 AND bd_bom.hbcustomized = 'N'  and bd_bom.dr = 0 and bd_bom.hbcustomized = 'N' and bd_bom.fbomtype != 3 ) \n" +
                                        "  AND \n" +
                                        "  bd_bom_b.dr = 0 and bd_bom_b.cmaterialvid='"+child.getCbmaterialvid()+"'";
                                bomcode = (String) dao.executeQuery(secondsql, new ColumnProcessor());
                            }
                            if(null != bomcode  && "2".equals(bomcode) ){
//                                sql = " select martype from bd_materialstock  where pk_material='" + child.getCbmaterialvid() + "' and pk_org='"+child.getPk_org()+"' and dr=0";
//                                String matType = (String) dao.executeQuery(sql, new ColumnProcessor());
//                                if(null == matType || "MR".equals(matType) || "".equals(matType)){
//                                    continue;
//                                }
                            }else if(null != bomcode  && "1".equals(bomcode)){
                                continue;
                            }else{
                                sql = " select martype from bd_materialstock  where pk_material='" + child.getCbmaterialvid() + "' and pk_org='"+child.getPk_org()+"' and dr=0";
                                String matType = (String) dao.executeQuery(sql, new ColumnProcessor());
                                if(null == matType || "MR".equals(matType) || "".equals(matType)){
                                    continue;
                                }
                            }
                        }else {
                            String sql="SELECT\n" +
                                    "\n" +
                                    "  bd_defdoc.code \n" +
                                    "FROM\n" +
                                    "  bd_defdoc where bd_defdoc.bd_defdoc.pk_defdoc='" + materalType + "'";
                            BaseDAO dao = new BaseDAO();
                            String bomcode = (String) dao.executeQuery(sql, new ColumnProcessor());
                            if(null == bomcode || "1".equals(bomcode) || "".equals(bomcode) ){
                                continue;
                            }
                        }
                        //只合并项目专用料数据
                        if(child.getBprojectmaterial().booleanValue()){
//                            mergedChildren.add(child);
                            List<PickmItemVO> pickmItemVOList = new ArrayList<PickmItemVO>();
                            pickmItemVOList.add(child);
                            AggPickmVO newVO = new AggPickmVO();
                            newVO.setParent(vo.getParent());
                            // 修改2：转换为ISuperVO数组
                            newVO.setChildren(PickmItemVO.class, pickmItemVOList.toArray(new PickmItemVO[0]));
                            resultList.add(newVO);
                        }
                        // CircularlyAccessibleValueObject 实现了 ISuperVO
                    }
                }
            }
//            if(mergedChildren.size() == 0){
//                continue;
//            }

//            AggPickmVO newVO = new AggPickmVO();
//            newVO.setParent(group.get(0).getParentVO());
//            // 修改2：转换为ISuperVO数组
//            newVO.setChildren(PickmItemVO.class, mergedChildren.toArray(new PickmItemVO[0]));
//
//            resultList.add(newVO);
//        }

        return resultList.toArray(new AggPickmVO[0]);
    }

}
