package nccloud.web.mmpac.pickm.query;

import nc.bs.dao.BaseDAO;
import nc.itf.mmpac.pickm.IPickmQueryService;
import nc.jdbc.framework.processor.ColumnProcessor;
import nc.jdbc.framework.processor.MapProcessor;
import nc.util.mmf.framework.base.MMValueCheck;
import nc.vo.bd.material.MaterialVO;
import nc.vo.mmpac.pickm.consts.PickmLangConsts;
import nc.vo.mmpac.pickm.entity.PickmHeadVO;
import nc.vo.mmpac.pickm.entity.PickmItemVO;
import nc.vo.pub.BusinessException;
import nc.vo.pub.lang.UFDouble;
import nccloud.commons.lang.StringUtils;
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 nccloud.framework.web.ui.model.row.Cell;
import nccloud.framework.web.ui.model.row.Row;
import nccloud.framework.web.ui.pattern.grid.Grid;
import nccloud.framework.web.ui.pattern.grid.GridOperator;
import nccloud.web.mmpub.pub.action.NCCTempletQueryAction;

import java.util.*;

/**
 * 备料计划卡片-借料入库弹窗-查询
 *
 * @author mzr
 * @date 2025/7/8
 */
public class PickmItemsQuery implements ICommonAction {
    public Object doAction(IRequest request) {
        String read = request.read();
        IJson json = JsonFactory.create();
        PickmQueryInfoDTO queryInfo = json.fromJson(read, PickmQueryInfoDTO.class);
        try {
            String[] cpickmbids = queryInfo.getCpickmbids();
            List<String> bids = new ArrayList<>();
            Set<String> codeSet = new HashSet<>();
            if (null != cpickmbids && cpickmbids.length != 0) {
                for (String cpickmbid : cpickmbids) {
                    // String countSql = "SELECT count(1) FROM ic_generalin_b"
                    //         + " WHERE dr = 0 and csourcebillbid = '" + cpickmbid + "'";
                    String countSql = "SELECT h.vbillcode" +
                            " FROM ic_generalin_b b" +
                            " LEFT JOIN ic_generalin_h h ON b.cgeneralhid = h.cgeneralhid" +
                            " WHERE b.dr = 0" +
                            " AND b.csourcebillbid = '" + cpickmbid + "'";
                    String vbillcode = (String) new BaseDAO().executeQuery(countSql, new ColumnProcessor());
                    if (StringUtils.isNotEmpty(vbillcode) &&
                            !"~".equals(vbillcode) && !"null".equals(vbillcode)) {
                        codeSet.add(vbillcode);
                    } else {
                        bids.add(cpickmbid);
                    }
                }
                if (MMValueCheck.isEmpty(bids)) {
                    String codeStr = String.join(",", codeSet);
                    ExceptionUtils.wrapBusinessException("存在有关联的其它入库，单号：" + codeStr);
                }
                IPickmQueryService service = ServiceLocator.find(IPickmQueryService.class);
                PickmItemVO[] itemVOS = service.queryItemsByIds(bids.toArray(new String[0]));
                if (MMValueCheck.isEmpty(itemVOS)) {
                    ExceptionUtils.wrapBusinessException(PickmLangConsts.getHIT_BODYNOTNULL());
                }
                GridOperator operator = new GridOperator(queryInfo.getPageid());
                if (MMValueCheck.isNotEmpty(queryInfo.getAppcode())) {
                    String templetid = NCCTempletQueryAction.getTempletIdByAppCode(queryInfo.getAppcode(), queryInfo.getPageid());
                    operator = new GridOperator(templetid, queryInfo.getPageid());
                }
                // HYPubBO hybo = new HYPubBO();
                Grid grid = operator.toGrid(itemVOS);
                Row[] rows = grid.getModel().getRows();

                // 收集所有唯一的cpickmid
                Set<String> pickmIdSet = new HashSet<>();
                for (Row row : rows) {
                    Map<String, Cell> rowValues = row.getValues();
                    String cpickmid = (String) rowValues.get("cpickmid").getValue();
                    if (cpickmid != null && !cpickmid.isEmpty()) {
                        pickmIdSet.add(cpickmid);
                    }
                }

                // 批量查询所有需要的PickmHeadVO
                Map<String, PickmHeadVO> pickmHeadMap = new HashMap<>();
                if (!pickmIdSet.isEmpty()) {
                    String[] pickmIds = pickmIdSet.toArray(new String[0]);
                    PickmHeadVO[] headVOs = service.queryHeadByIds(pickmIds);
                    if (headVOs != null) {
                        for (PickmHeadVO headVO : headVOs) {
                            if (headVO != null && headVO.getCpickmid() != null) {
                                pickmHeadMap.put(headVO.getCpickmid(), headVO);
                            }
                        }
                    }
                }

                for (Row row : rows) {
                    Map<String, Cell> rowValues = row.getValues();
                    String cpickmid = (String) rowValues.get("cpickmid").getValue();
                    PickmHeadVO hvo = pickmHeadMap.get(cpickmid);

                    UFDouble nplanoutastnum = (UFDouble) rowValues.get("nplanoutastnum").getValue();
                    UFDouble naccoutastnum = rowValues.get("naccoutastnum").getValue() != null ? (UFDouble) rowValues.get("naccoutastnum").getValue() : UFDouble.ZERO_DBL;
                    UFDouble nshouldastnum = rowValues.get("nshouldastnum").getValue() != null ? (UFDouble) rowValues.get("nshouldastnum").getValue() : UFDouble.ZERO_DBL;
                    UFDouble npscastnum = rowValues.get("npscastnum").getValue() != null ? (UFDouble) rowValues.get("npscastnum").getValue() : UFDouble.ZERO_DBL;
                    UFDouble borrowedQty = nplanoutastnum.sub(naccoutastnum).sub(nshouldastnum).sub(npscastnum);
                    // 新增备料数量字段，取值为：计划出库数量-累计出库数量-累计发货数量-累计委外数量
                    if (borrowedQty.doubleValue() <= 0) {
                        continue;
                    }

                    // 新增借料数量字段
                    Cell<UFDouble> borrowedQtyCell = new Cell<>();
                    borrowedQtyCell.setValue(borrowedQty);
                    rowValues.put("borrowedQty", borrowedQtyCell);
                    if (hvo != null) {
                        // 产品编码
                        String cmaterialvid = hvo.getCmaterialvid();
                        Cell<String> cmaterialvidCell = new Cell<>();
                        cmaterialvidCell.setValue(cmaterialvid);
                        if (cmaterialvid != null && !cmaterialvid.isEmpty()) {
                            Map<String, Object> materialMap = getMapValByCondition(MaterialVO.getDefaultTableName(), "code,name,def26",
                                    MaterialVO.PK_MATERIAL + " = '" + cmaterialvid + "' ");
                            if (materialMap != null) {
                                cmaterialvidCell.setValue(cmaterialvid);
                                cmaterialvidCell.setDisplay((materialMap.getOrDefault(MaterialVO.CODE, "") + ""));
                                rowValues.put("cmaterialvid", cmaterialvidCell);
                                // 物料名称
                                Cell<String> materialCell = new Cell<>();
                                materialCell.setDisplay(materialMap.getOrDefault(MaterialVO.NAME, "") + "");
                                materialCell.setValue(materialMap.getOrDefault(MaterialVO.NAME, ""));
                                rowValues.put("cmaterialvid.name", materialCell);
                                // 生产序号	取备料计划表头物料档案对应表头自定义项26
                                materialCell = new Cell<>();
                                Object def26 = "";
                                if (materialMap.getOrDefault(MaterialVO.DEF26, "") != null) {
                                    def26 = materialMap.getOrDefault(MaterialVO.DEF26, "");
                                }
                                materialCell.setDisplay(def26 + "");
                                materialCell.setValue(def26);
                                rowValues.put("cmaterialvid.def26", materialCell);
                            }
                        }
                        // 备料计划单号	取备料计划表头
                        Cell vbillcode = new Cell();
                        vbillcode.setValue(hvo.getVbillcode());
                        vbillcode.setDisplay(hvo.getVbillcode());
                        rowValues.put("vbillcode", vbillcode);

                        // 来源计划单号	取备料计划表头
                        Cell vsourcebillcode = new Cell();
                        vsourcebillcode.setValue(hvo.getVsourcebillcode());
                        vsourcebillcode.setDisplay(hvo.getVsourcebillcode());
                        rowValues.put("vsourcebillcode", vsourcebillcode);
                    }
                }
                Map<String, Object> returnMap = new HashMap<>();
                returnMap.put("data", grid);
                returnMap.put("success", true);
                return returnMap;
            } else {
                Map<String, Object> returnMap = new HashMap<>();
                returnMap.put("data", null);
                returnMap.put("success", false);
                return returnMap;
            }
        } catch (Exception ex) {
            ExceptionUtils.wrapBusinessException(ex.getMessage());
            Map<String, Object> returnMap = new HashMap<>();
            returnMap.put("data", null);
            returnMap.put("success", false);
            return returnMap;
        }
    }

    public Map<String, Object> getMapValByCondition(String tableName, String fieldName, String condition) throws BusinessException {
        String sql = " SELECT " + fieldName + "  FROM " + tableName + "  " +
                " WHERE nvl(" + tableName + " .dr,0)= 0  " +
                " and " + condition + " ";
        Map<String, Object> result = (Map<String, Object>) new BaseDAO().executeQuery(sql, new MapProcessor());
        if (result == null || result.isEmpty()) {
            result = new HashMap<>();
        }
        return result;
    }
}
