package nccloud.openapi.ic.util;

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

import nc.bs.framework.common.NCLocator;
import nc.itf.urmex.pub.IRMGlobalCache;
import nc.pubitf.sn.doc.param.SnDocQueryParam;
import nc.vo.bd.rack.RackVO;
import nc.vo.ic.general.define.ICBillBodyVO;
import nc.vo.ic.general.define.ICBillVO;
import nc.vo.ic.location.ICLocationVO;
import nc.vo.ic.pub.define.ICBillTableInfo;
import nc.vo.ic.pub.iadapter.sn.SnInterfaceAdapter;
import nc.vo.ic.pub.util.ValueCheckUtil;
import nc.vo.ml.NCLangRes4VoTransl;
import nc.vo.pub.BusinessException;
import nc.vo.pub.VOStatus;
import nc.vo.pub.lang.UFDouble;
import nc.vo.pubapp.pattern.pub.MathTool;
import nc.vo.pubapp.pattern.pub.PubAppTool;
import nc.vo.scmpub.res.billtype.ICBillType;
import nc.vo.sn.doc.entity.SerialNoVO;

/**
 * @@description
 * @author lanli6
 * @date 2023年2月15日
 * @version ncc1.0
 */
public class ICAPILocationVOUtils {

    /*
     * json格式实例：
     * [{"ic_material_h":{"pk_org":"001","cwarehouseid":"ck03","cdptvid":"bm002",
     * "vtrantypecode":"4D-01"},
     * "ic_material_b":[{"cmaterialvid":"物料001","castunitid":"BOX",
     * "nshouldassistnum":2,"vchangerate":"1/1",
     * "ic_loc":[{"clocationid":"00","vserialcode":"122001","csnunitid": "BOX"
     * ,"nnum":"1","nassistnum":"1"},
     * {"clocationid":"00","vserialcode":"122001","csnunitid":"BOX","nnum":"1",
     * "nassistnum":"1"}]}]}]
     */

    /**
     * 货位明细表数据,json标识
     */
    public static String ic_loc = "ic_loc";

    /**
     * 把json转换为货位VO
     *
     * @param billtype 单据类型
     * @param bodyvo 表体VO
     * @param bodyInfo 表体json数据
     */
    public static void setLocationVO(String billtype, ICBillVO[] aggVOList) {
        for (ICBillVO aggvo : aggVOList) {
            ICBillBodyVO[] bodys = aggvo.getBodys();
            for (ICBillBodyVO body : bodys) {
                setbodyLocationVO(billtype, body);
            }
        }
    }

    @SuppressWarnings("unchecked")
    private static void setbodyLocationVO(String billtype, ICBillBodyVO body) {
        // 获取货位明细map
        List<Map<String, String>> locationMap = (List<Map<String, String>>) body
                .getAttributeValue(ICAPILocationVOUtils.ic_loc);
        if (locationMap == null) {
            return;
        }
        ICBillType type = ICBillType.getICBillType(billtype);
        // 创建货位VO数组
        ICLocationVO[] loc = new ICLocationVO[locationMap.size()];

        // 一个map表示一行货位，遍历每一行货位
        int i = 0;
        for (Map<String, String> row : locationMap) {
            if (row == null) {
                continue;
            }
            // 获取相应单据类型对应的货位VO
            loc[i] = ICBillTableInfo.getICBillTableInfo(type).createLocationVO();
            // 给货位VO的字段赋值
            for (Map.Entry<String, String> location : row.entrySet()) {
                if (location.getKey() != null) {
                    loc[i].setAttributeValue(location.getKey().trim(),
                            location.getValue());
                }
            }
            i++;
        }
        // 给表体设置货位VO
        body.setLocationVOs(loc);

    }

    /**
     * 翻译货位和序列号
     * @throws BusinessException
     */
    public static void translate(ICBillVO[] billvos) throws BusinessException {
        Set<String> wareSet = new HashSet<String>();
        Set<String> locSet = new HashSet<String>();
        List<SnDocQueryParam> paramlist = new ArrayList<SnDocQueryParam>();
        // 获取单据的组织、仓库、物料、货位号、序列号
        for (ICBillVO billvo : billvos) {
            String pk_stordoc = billvo.getHead().getCwarehouseid();
            if (!PubAppTool.isNull(pk_stordoc)) {
                wareSet.add(pk_stordoc);
            }
            for (ICBillBodyVO bodyvo : billvo.getChildrenVO()) {
                ICLocationVO[] locs = bodyvo.getLocationVOs();
                if (ValueCheckUtil.isNullORZeroLength(locs)) {
                    continue;
                }

                for (ICLocationVO lvo : locs) {
                    if(VOStatus.DELETED == lvo.getStatus()) {
                        continue;
                    }
                    SnDocQueryParam param = new SnDocQueryParam();
                    param.setCmaterialvid(bodyvo.getCmaterialvid());
                    if (!PubAppTool.isNull(lvo.getClocationid())) {
                        locSet.add(lvo.getClocationid());
                    }
                    if (!PubAppTool.isNull(lvo.getVserialcode())) {
                        param.setSncode(lvo.getVserialcode());
                        paramlist.add(param);
                    }
                }
            }
        }
        // 如果没有传序列号不处理孙表转换
//        if (ValueCheckUtil.isNullORZeroLength(paramlist)) {
//            return;
//        }
        // 查询货位
        Map<String, RackVO> rackMap = getRack(wareSet, locSet);
        // 查询序列号
        Map<String, SerialNoVO> snMap =new HashMap<>();
        if (!ValueCheckUtil.isNullORZeroLength(paramlist)) {
            snMap =getSerialNoVO(paramlist.toArray(new SnDocQueryParam[paramlist.size()]));
        }

        // 设置翻译好的货位和序列号主键
        for (ICBillVO billvo : billvos) {
            String pk_stordoc = billvo.getHead().getCwarehouseid();

            for (ICBillBodyVO bodyvo : billvo.getChildrenVO()) {
                String cmaterialvid = bodyvo.getCmaterialvid();

                ICLocationVO[] locs = bodyvo.getLocationVOs();
                if (locs == null || locs.length == 0) {
                    continue;
                }
                for (ICLocationVO lvo : locs) {
                    if(VOStatus.DELETED == lvo.getStatus()) {
                        continue;
                    }
                    // 设置货位主键
                    String clcode = lvo.getClocationid();
                    if (!PubAppTool.isNull(clcode)) {
                        RackVO rackvo = rackMap.get(clcode + pk_stordoc);
                        if (null == rackvo) {
                            throw new BusinessException(
                                    nc.vo.ml.NCLangRes4VoTransl.getNCLangRes().getStrByID(
                                            "4008003_0", "04008001-0961", null, new String[] {
                                                    clcode
                                            })/* @res "货位[{0}]不存在！" */);
                        }

                        lvo.setClocationid(rackvo.getPk_rack());
                        
                        bodyvo.setClocationid(rackvo.getPk_rack());
                    }
                    // 设置序列号主键
                    String vserialcode = lvo.getVserialcode();
                    if (!PubAppTool.isNull(vserialcode)) {
                        SerialNoVO snVO = snMap.get(vserialcode + cmaterialvid);
                        if (snVO == null) {
                            throw new BusinessException(NCLangRes4VoTransl.getNCLangRes()
                                    .getStrByID("4008001_0", "04008001-0962", null, new String[] {
                                            vserialcode
                                    })/* @res "序列号[{0}]不存在！" */);
                        }
                        if (MathTool.greaterThan(lvo.getNnum(), new UFDouble(1))) {
                            throw new BusinessException(
                                    nc.vo.ml.NCLangRes4VoTransl.getNCLangRes().getStrByID(
                                            "4008001_0", "04008001-0963")/* @res "序列号数量不能大于1" */);
                        }
                        if (MathTool.isZero(lvo.getNnum())
                                || MathTool.isZero(lvo.getNassistnum())) {
                            throw new BusinessException(
                                    nc.vo.ml.NCLangRes4VoTransl.getNCLangRes().getStrByID(
                                            "4008001_0", "04008001-0964")/* @res "序列号数量不能为0" */);
                        }

                        lvo.setPk_serialcode(snVO.getPk_serialno());
                    }
                    // 补充货位序列号孙表的组织信息
                    lvo.setCorpoid(bodyvo.getPk_org());
                    lvo.setCorpvid(bodyvo.getPk_org_v());
                    lvo.setPk_group(bodyvo.getPk_group());
                    lvo.setPk_group(bodyvo.getPk_group());
                    lvo.setStatus(VOStatus.NEW);
                }
            }
        }
    }

    /**
     * 翻译货位
     * @param orgSet
     * @param wareSet
     * @param locSet
     * @return rackMap
     * @throws BusinessException
     */
    private static Map<String, RackVO> getRack(Set<String> wareSet,
                                               Set<String> locSet) throws BusinessException {
        Map<String, RackVO> rackMap = new HashMap<>();
        // 如果没有传货位不处理主键转换
        if (ValueCheckUtil.isNullORZeroLength(locSet)) {
            return rackMap;
        }
        // 根据code查询货位信息
        IRMGlobalCache cacheSvr =
                NCLocator.getInstance().lookup(IRMGlobalCache.class);
        rackMap = cacheSvr.getRackVO(locSet.toArray(new String[locSet.size()]),
                wareSet.toArray(new String[wareSet.size()]));
        // key:code+pk_stordoc
        return rackMap;
    }

    /**
     * 翻译序列号
     * @param marSet
     * @param serialSet
     * @return snMap
     */
    private static Map<String, SerialNoVO> getSerialNoVO(
            SnDocQueryParam[] snDoc) {

        Map<String, SerialNoVO> snMap = new HashMap<String, SerialNoVO>();
        SerialNoVO[] serialnovos = SnInterfaceAdapter.querySerialnos(snDoc);
        for (SerialNoVO serialnovo : serialnovos) {
            // key:code+cmaterialvid
            String key = serialnovo.getVcode() + serialnovo.getCmaterialvid();
            snMap.put(key, serialnovo);
        }
        return snMap;
    }

}
