package nc.impl.fa.alter.rule;

import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.util.List;
import java.util.Map;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.databind.node.ObjectNode;

import nc.bs.am.framework.action.ActionContext;
import nc.bs.am.framework.action.IRule;
import nc.bs.dao.BaseDAO;
import nc.bs.dao.DAOException;
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.itf.fa.byzlog.IbyzLogRcord;
import nc.jdbc.framework.SQLParameter;
import nc.jdbc.framework.processor.ColumnListProcessor;
import nc.jdbc.framework.processor.ColumnProcessor;
import nc.util.fa.httputil.BillHttpRequestUtil;
import nc.vo.fa.alter.AlterBodyVO;
import nc.vo.fa.alter.AlterHeadVO;
import nc.vo.fa.alter.AlterVO;
import nc.vo.fa.asset.AssetVO;
import nc.vo.fa.byzLogVO.ByzLogRcordVO;
import nc.vo.fa.category.CategoryVO;
import nc.vo.fa.depmethod.DepmethodVO;
import nc.vo.pub.BusinessException;
import nc.vo.pubapp.pattern.exception.ExceptionUtils;
import nccloud.web.byz.action.ARCApproveAction;

public class SendARCAlterRule implements IRule<AlterVO> {
	// 变动项目
	private ArrayNode pk_fa_alters;
	private ObjectMapper mapper;

	// 获取数据库操作对象
	private BaseDAO baseDAO;

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

	@Override
	public void process(ActionContext<AlterVO> context, AlterVO... vos) throws BusinessException {
		if (vos == null || vos.length == 0) {
			throw new BusinessException("VO为空");
		}
		mapper = new ObjectMapper();
		ObjectNode data = mapper.createObjectNode();
		String request = null, response = null, billno = null;
		String arcip = SendUtil.getSysinittempValue("altertobyz");
		try {
			for (AlterVO vo : vos) {
				AlterHeadVO head = (AlterHeadVO) vo.getParentVO();
				AlterBodyVO[] body = (AlterBodyVO[]) vo.getChildrenVO();
				if ("碧优资".equals(head.getDef1())) {
					// 推送给ARC
					new ARCApproveAction().sendApprove(body[0].getPk_card(), head.getDef4(), 1);
				} else if (BillInfoQueryUtil.isARC(head.getPk_org())) {
					// 是否推ARC
					//表体行变动项目一致取第一行就行
					if(body!=null&&body.length>0)
						this.pk_fa_alters = getChangeItem(getItem_code(body[0].getPk_alter_b()));
						
					data.set("head", setHead(head));
					data.set("body", setBody(body));
					billno = SafeObject.toString(head.getAttributeValue("bill_code"));
					
					if (data.has("head")) {
						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());
						}
						BillInfoQueryUtil.updateStatus("HG", new String[] { head.getPk_alter() });
					}
				}
				
			}
		} catch (Exception e) {
			ExceptionUtils.wrappBusinessException(e.getMessage());
		} finally {
//			if (billno != null) {
//				IbyzLogRcord ibyzLogRcord = (IbyzLogRcord) NCLocator.getInstance().lookup(IbyzLogRcord.class);
				ByzLogRcordVO byzLogRcordVO = new ByzLogRcordVO();
				byzLogRcordVO.setVbillcode(billno);
				byzLogRcordVO.setItf_type("NC变动单推送碧优资");
				byzLogRcordVO.setItfclass(this.getClass().toString());
				byzLogRcordVO.setNcctobyzresult(request);
				byzLogRcordVO.setByztonccparam(response);
				byzLogRcordVO.setItfaddress(arcip);
//				try {	
					BillInfoQueryUtil.insertlog(byzLogRcordVO);
//					ibyzLogRcord.RcordLogBYZ__RequiresNew(byzLogRcordVO);
//				} catch (BusinessException e) {
//					Logger.error(e.getMessage(), e);
//					Logger.error("日志生成失败！！nc.itf.fa.byzlog.IbyzLogRcord");
//				}
//			}
		}
	}

	/**
	 * 根据变动项目设置不同字段
	 * 
	 * @param bodyVO
	 */
	private void judgeChangeItem(ObjectNode bodyVO, AlterBodyVO body) {
		for (JsonNode fa_alter : pk_fa_alters) {
			switch (fa_alter.asText()) {
			// 原币原值变动
			case "BD01":
				// 变动前原币原值
				bodyVO.put("originvalue_before", SafeObject.toString(body.getAttributeValue("originvalue_before")));
				// 变动部分原币原值
				bodyVO.put("originvalue_alter", SafeObject.toString(body.getAttributeValue("originvalue_alter")));
				// 变动后原币原值
				bodyVO.put("originvalue_after", SafeObject.toString(body.getAttributeValue("originvalue_after")));
				break;
			// 本币原值变动
			case "BD02":
				// 变动前本币原值
				bodyVO.put("localoriginvalue_before",
						SafeObject.toString(body.getAttributeValue("localoriginvalue_before")));
				// 变动部分本币原值
				bodyVO.put("localoriginvalue_alter",
						SafeObject.toString(body.getAttributeValue("localoriginvalue_alter")));
				// 变动后本币原值
				bodyVO.put("localoriginvalue_after",
						SafeObject.toString(body.getAttributeValue("localoriginvalue_after")));
				break;
			// 累计折旧变动
			case "BD03":
				// 变动前累计折旧
				bodyVO.put("accudep_before", SafeObject.toString(body.getAttributeValue("accudep_before")));
				// 变动部分累计折旧
				bodyVO.put("accudep_alter", SafeObject.toString(body.getAttributeValue("accudep_alter")));
				// 变动后累计折旧
				bodyVO.put("accudep_after", SafeObject.toString(body.getAttributeValue("accudep_after")));
				break;
			// 使用月限变动
			case "BD09":
				// 变动前使用月限
				bodyVO.put("naturemonth_before", SafeObject.toString(body.getAttributeValue("naturemonth_before")));
				// 变动后使用月限
				bodyVO.put("naturemonth_after", SafeObject.toString(body.getAttributeValue("naturemonth_after")));
				break;
			// 折旧方法变动
			case "BD11":
				// 变动前折旧方法
				DepmethodVO methodbefor=BillInfoQueryUtil.selectDepmethod(SafeObject.toString(body.getAttributeValue("pk_depmethod_before")));
				if(methodbefor!=null)
					bodyVO.put("pk_depmethod_before", methodbefor.getDepmethod_code());
				// 变动后折旧方法
				DepmethodVO methodater=BillInfoQueryUtil.selectDepmethod(SafeObject.toString(body.getAttributeValue("pk_depmethod_after")));
				if(methodater!=null)
					bodyVO.put("pk_depmethod_after", methodater.getDepmethod_code());
				break;
			// 净残值率变动
			case "BD12":
				// 变动前净残值率（%）
				bodyVO.put("salvagerate_before", SafeObject.toString(body.getAttributeValue("salvagerate_before")));
				// 变动后净残值率（%）
				bodyVO.put("salvagerate_after", SafeObject.toString(body.getAttributeValue("salvagerate_after")));
				break;
			// 净残值变动
			case "BD13":
				// 变动前净残值
				bodyVO.put("salvage_before", SafeObject.toString(body.getAttributeValue("salvage_before")));
				// 变动后净残值
				bodyVO.put("salvage_after", SafeObject.toString(body.getAttributeValue("salvage_after")));
				break;
			// 资产类型变动
			case "BD15":
				// 变动前类别
				CategoryVO befor=BillInfoQueryUtil.selectCategory(SafeObject.toString(body.getAttributeValue("pk_category_before")));
				if(befor!=null)
					bodyVO.put("pk_category_before", befor.getCate_code());
				// 变动后类别
				CategoryVO after=BillInfoQueryUtil.selectCategory(SafeObject.toString(body.getAttributeValue("pk_category_after")));
				if(after!=null)
					bodyVO.put("pk_category_after", after.getCate_code());
				break;
			// 购买价款变动
			case "BD29":
				// 变动前购买价款
				bodyVO.put("currmoney_before", SafeObject.toString(body.getAttributeValue("currmoney_before")));
				// 变动部分购买价款
				bodyVO.put("currmoney_alter", SafeObject.toString(body.getAttributeValue("currmoney_alter")));
				// 变动后购买价款
				bodyVO.put("currmoney_after", SafeObject.toString(body.getAttributeValue("currmoney_after")));
				break;
			// 相关税费变动
			case "BD30":
				// 变动前购买价款
				bodyVO.put("tax_cost_before", SafeObject.toString(body.getAttributeValue("tax_cost_before")));
				// 变动部分购买价款
				bodyVO.put("tax_cost_alter", SafeObject.toString(body.getAttributeValue("tax_cost_alter")));
				// 变动后购买价款
				bodyVO.put("tax_cost_after", SafeObject.toString(body.getAttributeValue("tax_cost_after")));
				break;
			// 其他费用变动
			case "BD33":
				// 变动前其他费用
				bodyVO.put("other_cost_before", SafeObject.toString(body.getAttributeValue("other_cost_before")));
				// 变动部分其他费用
				bodyVO.put("other_cost_alter", SafeObject.toString(body.getAttributeValue("other_cost_alter")));
				// 变动后其他费用
				bodyVO.put("other_cost_after", SafeObject.toString(body.getAttributeValue("other_cost_after")));
				break;
			// 进项税变动
			case "BD34":
				// 变动前进项税
				bodyVO.put("tax_input_before", SafeObject.toString(body.getAttributeValue("tax_input_before")));
				// 变动部分进项税
				bodyVO.put("tax_input_alter", SafeObject.toString(body.getAttributeValue("tax_input_alter")));
				// 变动后进项税
				bodyVO.put("tax_input_after", SafeObject.toString(body.getAttributeValue("tax_input_after")));
				break;
			default:
				// 变动前原币原值
				bodyVO.put("originvalue_before", SafeObject.toString(body.getAttributeValue("originvalue_before")));
				// 变动部分原币原值
				bodyVO.put("originvalue_alter", SafeObject.toString(body.getAttributeValue("originvalue_alter")));
				// 变动后原币原值
				bodyVO.put("originvalue_after", SafeObject.toString(body.getAttributeValue("originvalue_after")));
				break;
			}
		}

	}

	/**
	 * 表体
	 * 
	 * @param vo
	 * @return
	 * @throws IOException
	 * @throws NoSuchMethodException
	 * @throws InvocationTargetException
	 * @throws IllegalAccessException
	 * @throws DAOException
	 */
	private ArrayNode setBody(AlterBodyVO[] body) throws BusinessException, IOException, IllegalAccessException,
			InvocationTargetException, NoSuchMethodException {
		ArrayNode arrayNode = mapper.createArrayNode();
		// AlterBodyVO[] body = (AlterBodyVO[]) vo.getChildrenVO();
		for (int i = 0; i < body.length; i++) {
			ObjectNode bodyVO = mapper.createObjectNode();
			// 固定资产主键
			String pk_card = SafeObject.toString(body[i].getAttributeValue("pk_card"));
			bodyVO.put("pk_card", pk_card);
			AssetVO assetVO = BillInfoQueryUtil.selectCard(pk_card);
			// 卡片编号
			bodyVO.put("card_code", assetVO.getCard_code());
			// 固定资产名称
			bodyVO.put("asset_name", assetVO.getAsset_name());
			// 变动原因
			bodyVO.put("pk_reason", getPk_reason(body[i].getPk_reason()));
			// 根据变动项目设置不同字段
			judgeChangeItem(bodyVO, body[i]);
			arrayNode.add(bodyVO);
		}
		return arrayNode;
	}

	private String getPk_reason(String pk) throws BusinessException {
		String sql = "SELECT REASON_NAME FROM FA_REASON WHERE PK_REASON = ? AND DR = 0";
		String result = getColumn(sql, pk);
		if (result == null) {
			throw new BusinessException("没有找到该变动原因(pk_reason),请检查数据:" + pk);
		}
		return result;
	}

	/**
	 * 单值通用查询
	 * 
	 * @param sql
	 * @param code
	 * @return
	 * @throws DAOException
	 */
	private String getColumn(String sql, String code) throws DAOException {
		SQLParameter parameter = new SQLParameter();
		parameter.addParam(code);
		return SafeObject.toString(getBaseDAO().executeQuery(sql, parameter, new ColumnProcessor()));
	}

	/**
	 * 表头
	 * 
	 * @param vo
	 * @return
	 * @throws BusinessException
	 * @throws JsonProcessingException
	 */
	private JsonNode setHead(AlterHeadVO head) throws BusinessException {
		ObjectNode headVO = mapper.createObjectNode();
		// AlterHeadVO head = (AlterHeadVO) vo.getParentVO();
		// 财务组织
		headVO.put("pk_org_v", SafeObject.toString(head.getAttributeValue("pk_org_v")));
		// 业务日期
		headVO.put("business_date", SafeObject.toString(head.getAttributeValue("business_date")));
		// 调整单号
		headVO.put("bill_code", SafeObject.toString(head.getAttributeValue("bill_code")));
		// 交易类型编码
		headVO.put("transi_type", SafeObject.toString(head.getAttributeValue("transi_type")));
		// 变动项目
//		this.pk_fa_alters = getChangeItem(getItem_code(head.getPk_alter()));
		headVO.set("pk_fa_alters", pk_fa_alters);
		// 制单人
		headVO.put("billmaker", SafeObject.toString(head.getAttributeValue("billmaker")));
		return headVO;
	}

	/**
	 * 查询变动类型
	 * 
	 * @param pk
	 * @return
	 * @throws BusinessException
	 */
	private List<String> getItem_code(String pk) throws BusinessException {
		String sql = "SELECT ITEM_CODE FROM FA_ALTERSHEET WHERE PK_ALTER_B = ? AND DR = 0";
		SQLParameter parameter = new SQLParameter();
		parameter.addParam(pk);
		List<String> result = (List<String>) getBaseDAO().executeQuery(sql, parameter, new ColumnListProcessor());
		if (result == null) {
			throw new BusinessException("没有找到该变动类型(item_code),请检查数据:" + pk);
		}
		return result;
	}

	/**
	 * 查询变动项目
	 * 
	 * @param pk
	 * @return
	 */
	private ArrayNode getChangeItem(List<String> pks) {
		ArrayNode node = mapper.createArrayNode();
		Map<String, String> map = BillInfoQueryUtil.getAlterItemValue();
		for (String pk : pks) {
			for (Map.Entry<String, String> entry : map.entrySet()) {
				if (pk.equals(entry.getValue())) {
					node.add(entry.getKey());
					break;
				}
			}
		}
		return node;
	}
}
