package nc.bs.bd.pfxx.plugin;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

import com.yonyou.cloud.utils.CollectionUtils;

import nc.bs.dao.BaseDAO;
import nc.bs.dao.DAOException;
import nc.bs.framework.common.NCLocator;
import nc.bs.logging.Logger;
import nc.bs.pfxx.ISwapContext;
import nc.itf.bd.material.baseinfo.IMaterialBaseInfoService;
import nc.jdbc.framework.processor.ColumnListProcessor;
import nc.itf.bd.material.plan.IMaterialPlanQueryService;
import nc.itf.bd.material.plan.IMaterialPlanService;
import nc.itf.bd.material.stock.IMaterialStockQueryService;
import nc.itf.bd.material.stock.IMaterialStockService;
import nc.vo.bd.errorlog.ErrLogReturnValue;
import nc.vo.bd.errorlog.ErrorMsgVO;
import nc.vo.bd.material.IMaterialEnumConst;
import nc.vo.bd.material.MaterialConvertVO;
import nc.vo.bd.material.MaterialTaxTypeVO;
import nc.vo.bd.material.MaterialVO;
import nc.vo.bd.material.plan.MaterialPlanVO;
import nc.vo.bd.material.stock.MaterialStockVO;
import nc.vo.bd.pub.IPubEnumConst;
import nc.vo.pfxx.auxiliary.AggxsysregisterVO;
import nc.vo.pfxx.util.PfxxPluginUtils;
import nc.vo.pub.BusinessException;
import nc.vo.pub.VOStatus;
import nc.vo.pub.lang.UFBoolean;

import nccloud.commons.lang.StringUtils;

/**
 * 物料基本信息外部交互平台导入
 * 
 * @author jiangjuna
 * @since NC6.0
 */
public class MaterialPfxxPlugin extends nc.bs.pfxx.plugin.AbstractPfxxPlugin {

	private BaseDAO baseDAO = null;

	private IMaterialBaseInfoService service = null;

	@Override
	protected Object processBill(Object vo, ISwapContext swapContext, AggxsysregisterVO aggxsysvo) throws BusinessException {
		String pk = null;
		try {
			MaterialVO materialVO = (MaterialVO) vo;
			// by_zhangzhyz_20220113//项目专项需求 根据物料编码和组织进行查询，不通过ID对照表
			String whereSql =  MaterialVO.CODE + " = '" + materialVO.getCode() + "'";
			@SuppressWarnings("unchecked")
			Collection<MaterialVO> cols = new BaseDAO().retrieveByClause(MaterialVO.class, whereSql);
			if (cols != null && !cols.isEmpty()) {
				MaterialVO[] vos = cols.toArray(new MaterialVO[0]);
				pk = vos[0].getPk_material();
			}
			if (StringUtils.isBlank(pk)) {
				//默认值
				materialVO.setIsfeature(UFBoolean.FALSE);
				materialVO = this.insertMaterialVO(materialVO);
				PfxxPluginUtils.addDocIDVsPKContrast(swapContext.getBilltype(), swapContext.getDocID(), materialVO.getPrimaryKey());
				return materialVO.getPrimaryKey();
			} else {
				this.getService().updateMaterial(this.getUpdateVO(materialVO, pk));
				String sender = swapContext.getSender();
				if("pdm".equalsIgnoreCase(sender)) {
					// 物料更新后更新计划信息
					updatePlanVOsAfterMaterialUpdate(materialVO);
					// 物料更新后更新库存信息
					updateStockVOsAfterMaterialUpdate(materialVO);
				}
			}
		} catch (Exception ex) {
			Logger.error(ex.getMessage(), ex.getCause());
			throw new BusinessException(ex.getMessage(), ex.getCause());
		}
		return pk;
	}

	/**
	 * 物料更新后更新计划信息
	 * 
	 * @param materialVO
	 * @throws BusinessException
	 */
	private void updatePlanVOsAfterMaterialUpdate(MaterialVO materialVO) throws BusinessException {
		if (materialVO.getDef19() == null)
			return;
		String pk_org = materialVO.getPk_org();
		String pk_material = materialVO.getPk_material();
		IMaterialPlanQueryService queryService = NCLocator.getInstance().lookup(IMaterialPlanQueryService.class);
		// 查询物料计划信息
		MaterialPlanVO[] pvos = queryService.queryMaterialPlanVOs(new String[] { pk_org }, pk_material);
		IMaterialPlanService planService = NCLocator.getInstance().lookup(IMaterialPlanService.class);
		for (MaterialPlanVO planVO : pvos) {
			// PLM计划虚项映射到计划信息
			if (materialVO.getDef19() != null && UFBoolean.TRUE.toString().equals(materialVO.getDef19()))
				planVO.setIsvirtual(UFBoolean.TRUE);
			else
				planVO.setIsvirtual(UFBoolean.FALSE);
			planVO.setStatus(VOStatus.UPDATED);
			planService.updateMaterialPlanVO(planVO);
		}
	}

	/**
	 * 物料更新后更新库存信息
	 * 
	 * @param materialVO
	 * @throws BusinessException
	 */
	private void updateStockVOsAfterMaterialUpdate(MaterialVO materialVO) throws BusinessException {
		if (materialVO.getDef18() == null)
			return;
		IMaterialStockQueryService queryService = NCLocator.getInstance().lookup(IMaterialStockQueryService.class);
		MaterialStockVO[] svos = queryService.queryMaterialStockVOs(new String[] { materialVO.getPk_org() }, materialVO.getPk_material());
		IMaterialStockService stockService = NCLocator.getInstance().lookup(IMaterialStockService.class);
		for (MaterialStockVO stockVO : svos) {
			if (stockVO.getMartype() != null) {
				// PLM物料类型映射到库存信息
				switch (materialVO.getDef18()) {
				case IMaterialEnumConst.MATERTYPE_DR:
					stockVO.setMartype(IMaterialEnumConst.MATERTYPE_DR);
					break;
				case IMaterialEnumConst.MATERTYPE_FR:
					stockVO.setMartype(IMaterialEnumConst.MATERTYPE_FR);
					break;
				case IMaterialEnumConst.MATERTYPE_MR:
					stockVO.setMartype(IMaterialEnumConst.MATERTYPE_MR);
					break;
				case IMaterialEnumConst.MATERTYPE_PR:
					stockVO.setMartype(IMaterialEnumConst.MATERTYPE_PR);
					break;
				case IMaterialEnumConst.MATERTYPE_OT:
					stockVO.setMartype(IMaterialEnumConst.MATERTYPE_OT);
					break;
				case IMaterialEnumConst.MATERTYPE_ET:
					stockVO.setMartype(IMaterialEnumConst.MATERTYPE_ET);
					break;
				default:
					// 物料类型默认为“MR”
					stockVO.setMartype(IMaterialEnumConst.MATERTYPE_MR);
					break;
				}
			}
		}
		stockService.updateMaterialStockVOs(svos);
	}

	private BaseDAO getBaseDAO() {
		if (this.baseDAO == null) {
			this.baseDAO = new BaseDAO();
		}
		return this.baseDAO;
	}

	private MaterialVO getInsertVO(MaterialVO materialVO) throws DAOException {
		materialVO.setEnablestate(IPubEnumConst.ENABLESTATE_ENABLE);
		materialVO.setStatus(VOStatus.NEW);
		materialVO.setMaterialconvert(this.getMaterialConvertVOs(materialVO));
		materialVO.setMaterialtaxtype(this.getMaterialTaxTypeVOs(materialVO));
		return materialVO;
	}

	@SuppressWarnings("unchecked")
	private MaterialConvertVO[] getMaterialConvertVOs(MaterialVO MaterialVO) throws DAOException {
		List<MaterialConvertVO> newConverts = new ArrayList<MaterialConvertVO>();
		if (StringUtils.isNotBlank(MaterialVO.getPrimaryKey())) {
			Collection<MaterialConvertVO> oldAgentStores = this.getBaseDAO().retrieveByClause(MaterialConvertVO.class,
					MaterialConvertVO.PK_MATERIAL + " = '" + MaterialVO.getPrimaryKey() + "'", new String[] { MaterialConvertVO.PK_MATERIALCONVERT });
			for (MaterialConvertVO agentstore : oldAgentStores) {
				agentstore.setStatus(VOStatus.DELETED);
				newConverts.add(agentstore);
			}
		}
		if (MaterialVO.getMaterialconvert() != null && MaterialVO.getMaterialconvert().length > 0) {
			for (MaterialConvertVO agentstore : MaterialVO.getMaterialconvert()) {
				agentstore.setStatus(VOStatus.NEW);
				newConverts.add(agentstore);
			}
		}
		return newConverts.toArray(new MaterialConvertVO[0]);
	}

	private MaterialTaxTypeVO[] getMaterialTaxTypeVOs(MaterialVO MaterialVO) throws DAOException {
		List<MaterialTaxTypeVO> newConverts = new ArrayList<MaterialTaxTypeVO>();
		if (StringUtils.isNotBlank(MaterialVO.getPrimaryKey())) {
			Collection<MaterialTaxTypeVO> oldAgentStores = this.getBaseDAO().retrieveByClause(MaterialTaxTypeVO.class,
					MaterialTaxTypeVO.PK_MATERIAL + " = '" + MaterialVO.getPrimaryKey() + "'", new String[] { MaterialTaxTypeVO.PK_MATERIALTAXTYPE });
			for (MaterialTaxTypeVO agentstore : oldAgentStores) {
				agentstore.setStatus(VOStatus.DELETED);
				newConverts.add(agentstore);
			}
		}
		if (MaterialVO.getMaterialtaxtype() != null && MaterialVO.getMaterialtaxtype().length > 0) {
			for (MaterialTaxTypeVO agentstore : MaterialVO.getMaterialtaxtype()) {
				agentstore.setStatus(VOStatus.NEW);
				newConverts.add(agentstore);
			}
		}
		return newConverts.toArray(new MaterialTaxTypeVO[0]);
	}

	private IMaterialBaseInfoService getService() {
		if (this.service == null) {
			this.service = NCLocator.getInstance().lookup(IMaterialBaseInfoService.class);
		}
		return this.service;
	}

	private MaterialVO getUpdateVO(MaterialVO materialVO, String pk) throws BusinessException {
		MaterialVO oldVO = (MaterialVO) this.getBaseDAO().retrieveByPK(MaterialVO.class, pk,
				new String[] { MaterialVO.CREATOR, MaterialVO.CREATIONTIME, MaterialVO.PK_SOURCE, MaterialVO.VERSION, MaterialVO.LATEST, MaterialVO.ENABLESTATE });
		if (oldVO == null) {
			throw new BusinessException(nc.vo.ml.NCLangRes4VoTransl.getNCLangRes().getStrByID("bdpub", "0bdpub0057")
			/* @res "该数据已被删除" */);
		}
		materialVO.setPrimaryKey(pk);
		materialVO.setCreator(oldVO.getCreator());
		materialVO.setCreationtime(oldVO.getCreationtime());
		materialVO.setPk_source(oldVO.getPk_source());
		materialVO.setVersion(oldVO.getVersion());
		materialVO.setLatest(oldVO.getLatest());
		materialVO.setEnablestate(oldVO.getEnablestate());
		materialVO.setStatus(VOStatus.UPDATED);
		materialVO.setTs(oldVO.getTs());
		materialVO.setMaterialconvert(this.getMaterialConvertVOs(materialVO));
		materialVO.setMaterialtaxtype(this.getMaterialTaxTypeVOs(materialVO));
		materialVO.setIsfeature(UFBoolean.FALSE);
		
		return materialVO;
	}

	private MaterialVO insertMaterialVO(MaterialVO materialVO) throws BusinessException, DAOException {
		if (StringUtils.isBlank(materialVO.getPk_source())) {
			materialVO = this.getService().insertMaterial(this.getInsertVO(materialVO));
		} else {
			ErrLogReturnValue value = this.getService().createMaterialVersion(materialVO, materialVO.getPk_source());
			if (value.getReturnValue() == null || !value.getReturnValue().getClass().isArray()) {
				return materialVO;
			}
			materialVO = (MaterialVO) ((Object[]) value.getReturnValue())[0];
			this.LogErrorMessage(value);
		}
		return materialVO;
	}

	private void LogErrorMessage(ErrLogReturnValue value) {
		ErrorMsgVO[] vos = value.getErrLogResult().getErrorMsgs();
		if (vos != null && vos.length > 0) {
			String message = nc.vo.ml.NCLangRes4VoTransl.getNCLangRes().getStrByID("10140mag", "010140mag0200", null,
					new String[] { Integer.toString(value.getTotalNum()), Integer.toString(value.getErrLogResult().getErrorMessagegNum()) })
					/* @res "外部交换平台导入物料新版本数据时，分配操作部分成功，共处理了{0}条记录，其中有{1}条处理失败：" */+ "\n";
			for (int i = 0; i < vos.length; i++) {
				message += vos[i].getErrormsg() + "\n";
			}
			Logger.debug(message);
		}
	}

}
