package nc.impl.fa.byzimpl;

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ObjectNode;

import nc.bs.framework.common.InvocationInfoProxy;
import nc.bs.framework.common.NCLocator;
import nc.bs.hz.utils.BillInfoQueryUtil;
import nc.bs.hz.utils.SafeObject;
import nc.bs.hz.utils.SendUtil;
import nc.bs.logging.Logger;
import nc.impl.pubapp.pattern.data.bill.BillQuery;
import nc.itf.fa.byzitf.IBackOffOperator;
import nc.itf.fa.byzlog.IbyzLogRcord;
import nc.itf.uap.IUAPQueryBS;
import nc.itf.uap.pf.IPFBusiAction;
import nc.itf.uap.pf.IWorkflowAdmin;
import nc.itf.uap.pf.metadata.IFlowBizItf;
import nc.jdbc.framework.SQLParameter;
import nc.jdbc.framework.processor.ColumnProcessor;
import nc.md.data.access.NCObject;
import nc.util.fa.httputil.BillHttpRequestUtil;
import nc.vo.fa.byzLogVO.ByzLogRcordVO;
import nc.vo.fa.deployin.DeployInVO;
import nc.vo.pub.AggregatedValueObject;
import nc.vo.pub.BusinessException;
import nc.vo.pubapp.pattern.exception.ExceptionUtils;
import nc.vo.pubapp.pattern.model.entity.bill.AbstractBill;
import nc.vo.uap.pf.PFBusinessException;
import nc.vo.wfengine.definition.WorkflowTypeEnum;
import nccloud.framework.service.ServiceLocator;
import nccloud.framework.web.container.IRequest;
import nccloud.web.fa.byz.action.BillTypeToVO;

public class BackOffOperatorImpl implements IBackOffOperator{

	@Override
	public void terminateWorkflow(AggregatedValueObject aggvo, int iWorkflowtype)
			throws BusinessException {
		// TODO Auto-generated method stub
		NCObject ncObj = NCObject.newInstance(aggvo);
		IFlowBizItf itf = (IFlowBizItf) ncObj.getBizInterface(IFlowBizItf.class);
		
		NCLocator.getInstance().lookup(IWorkflowAdmin.class).terminateWorkflow(itf.getBillId(), itf.getTranstype()==null?itf.getBilltype():itf.getTranstype(), itf.getBillNo(), iWorkflowtype);
	}

	@Override
	public boolean doBackByz(IRequest req) throws Exception {
		
		ObjectMapper mapper = new ObjectMapper();
		
		String arcip = null, request = null, response = null, src_code = null;
		try {
			JsonNode node = mapper.readTree(req.read());
			String approveStatus = null;

			boolean flag = false;
			if (node.get("approvestatus") != null && node.get("approvestatus").isTextual()) {
				// 如果是字符串且字符串的值等于1则为提交态
				flag = node.get("approvestatus").asText().equals("1");
			}
			if (node.get("approvestatus") != null && node.get("approvestatus").isBoolean()) {
				// 如果该值是true则为提交态
				flag = node.get("approvestatus").asBoolean();
			}

			String pk = node.get("pk_primary").asText();
			String billtype = node.get("bill_type").asText();
//			String trantype = node.get("tran_type").asText();
		
			BillInfoQueryUtil.initSysBilltypeCache(new String[] {"F0-Cxx-W63","HG","HF","HO","HM","HC","HC-01","HD","HD-01","HZ","HG-00","H0","F0","F1",billtype});
			
			AggregatedValueObject aggvo = queryBillByPrimaryKey(pk, billtype);
			
			String ARCNO = getARCNO(aggvo, billtype);
			
			// 回退给ARC
			ObjectNode data = mapper.createObjectNode();
			// 单据主键
			data.put("pkCard", pk);
			// 回退类型
			data.put("type", BillTypeToVO.getTypeByBilltype(billtype));
			src_code = SafeObject
					.toString(aggvo.getParentVO().getAttributeValue(BillTypeToVO.getBillNoByBilltype(billtype)));
			// 单据编号(ARC)
			data.put("billno", ARCNO);
			// 审批结果
			data.put("auditResult", 1);
			// 回退原因
			data.put("backReason", node.get("backtext").asText());
			// 回退用户
			String user = InvocationInfoProxy.getInstance().getUserCode();
			
			data.put("backUser", user);
			// 回退用户名
			data.put("backUserName", getUserName(user));
			arcip = SendUtil.getSysinittempValue("backtobyz");
			request = SendUtil.getResult(data);
			// 推送给ARC
			response = BillHttpRequestUtil.sendPost(arcip, request);
			JsonNode json = mapper.readTree(response);
			
			if (json.findValue("code").asInt() != 200) {
				throw new BusinessException("ARC返回信息：" + json.findValue("msg").asText());
			}
			
			if (billtype.equals("HD")) {
				ServiceLocator.find(nc.itf.fa.prv.IDeployIn.class).delete((DeployInVO) aggvo);
			} else {
				if (flag) {
					//终止流程
					terminateWorkflow(aggvo,WorkflowTypeEnum.Approveflow.getIntValue());
				}
			}
			// 执行删除动作			
			IPFBusiAction busiAction=NCLocator.getInstance().lookup(IPFBusiAction.class);
			busiAction.processAction("DELETE", billtype, null, aggvo, null, null);
			
			return true;
		}
		catch (PFBusinessException e) {
			ExceptionUtils.wrappBusinessException(e.getMessage());
		}
		catch (Exception e) {
			if(e.getCause()!=null) {
				if(e.getCause().getCause()!=null) {
					ExceptionUtils.wrappBusinessException(e.getCause().getCause().getMessage());
				}
			}
			
			ExceptionUtils.wrappBusinessException(e.getMessage());
		} finally {
			IbyzLogRcord ibyzLogRcord = (IbyzLogRcord) ServiceLocator.find(IbyzLogRcord.class);
			ByzLogRcordVO byzLogRcordVO = new ByzLogRcordVO();
			byzLogRcordVO.setVbillcode(src_code);
			byzLogRcordVO.setItf_type("固定资产相关单据回退碧优资");
			byzLogRcordVO.setItfclass(this.getClass().toString());
			byzLogRcordVO.setNcctobyzresult(request);
			byzLogRcordVO.setByztonccparam(response);
			byzLogRcordVO.setItfaddress(arcip);
			try {
				ibyzLogRcord.RcordLogBYZ__RequiresNew(byzLogRcordVO);
			} catch (BusinessException e) {
				Logger.error(e.getMessage(), e);
				Logger.error("日志生成失败！！nc.itf.fa.byzlog.IbyzLogRcord");
			}
		}
		
		return false;
	}
	
	private String getUserName(String usercode) throws BusinessException {
		String sql = "SELECT USER_NAME FROM SM_USER WHERE USER_CODE = ?";
		SQLParameter parameter = new SQLParameter();
		parameter.addParam(usercode);
		IUAPQueryBS bs = ServiceLocator.find(IUAPQueryBS.class);
		String result = SafeObject.toString(bs.executeQuery(sql, parameter, new ColumnProcessor()));
		if (result == null) {
			throw new BusinessException("没有找到该用户,请检查数据:" + usercode);
		}
		return result;
	}

	public AggregatedValueObject queryBillByPrimaryKey(String key, String billType) throws BusinessException {
		if (null == key) {
			return null;
		}
		AggregatedValueObject[] vos = new BillQuery<AbstractBill>(BillTypeToVO.getVOClassByBilltype(billType))
				.query(new String[] { key });

		handleDef(vos, billType);

		return (null != vos) && (vos.length > 0) ? vos[0] : null;
	}

	// add by djy 前台删除和接口删除公用的校验差异处理
	public void handleDef(AggregatedValueObject[] vos, String billType) {
		if (vos == null || vos.length == 0)
			return;
		String def;
		if ("F0".equals(billType) || "F1".equals(billType))
			def = "def56";
		else
			def = "def1";
		for (AggregatedValueObject vo : vos) {
			vo.getParentVO().setAttributeValue(def, "");
		}
	}

	// add by djy 获取对应单据ARC单据号
	public String getARCNO(AggregatedValueObject aggvo, String billType) {
		String type = null;
		if ("F0".equals(billType) || "F1".equals(billType))
			type = (String) aggvo.getParentVO().getAttributeValue("def57");
		else if ("HG".equals(billType))
			type = (String) aggvo.getParentVO().getAttributeValue("def4");
		else
			type = (String) aggvo.getParentVO().getAttributeValue("def2");
		return type;
	}

}
