package nccloud.hrkq.hrkq.monthottimevo.action;

import java.util.Collection;
import java.util.HashMap;
import java.util.Map;

import nc.bs.logging.Logger;
import nc.md.persist.framework.IMDPersistenceQueryService;
import nc.vo.hrkq.monthottime.AggMonthOtTimeVO;
import nc.vo.pf.pub.util.SQLUtil;
import nc.vo.pub.BusinessException;
import nc.vo.pub.pf.BillStatusEnum;
import nc.vo.pubapp.pattern.model.entity.bill.AbstractBill;
import nc.vo.uap.pf.PfProcessBatchRetObject;
import nccloud.framework.core.exception.ExceptionUtils;
import nccloud.framework.core.json.IJson;
import nccloud.framework.web.action.itf.ICommonAction;
import nccloud.framework.web.container.IRequest;
import nccloud.framework.web.json.JsonFactory;
import nccloud.framework.web.ui.pattern.billcard.BillCard;
import nccloud.framework.web.ui.pattern.billcard.BillCardOperator;
import nccloud.hrkq.hrkq.monthottimevo.hrkq.util.CommonUtil;
import nccloud.hrkq.hrkq.monthottimevo.hrkq.util.NccBillOperatorParam;
import nccloud.pubitf.riart.pflow.CloudPFlowContext;
import nccloud.pubitf.riart.pflow.ICloudScriptPFlowService;
import nccloud.vo.hrkq.hrkq.MonthOtTimeVOConst;
import nccloud.web.workflow.approve.util.NCCFlowUtils;

public class MonthOtTimeVOUnCommitAction implements ICommonAction{

	@Override
	  public Object doAction(IRequest request) {
	    // 获取前端请求参数
	    NccBillOperatorParam operaParam = this.getRequestParam(request);
	    Object result = null;
	    try {
	      // 根据pk查询待操作单据
	    	AggMonthOtTimeVO[] operaVOs = this.queryBillsByPks(operaParam);
	      // ts赋值
	      CommonUtil.setBillsTs(operaParam.getPkMapTs(), operaVOs);
	      // 对查询结果执行具体业务处理
	      Object resultVOs = this.unCommit(operaVOs);
	      // 卡片页面需要返回操作后的数据到前端，列表界面操作后，前端重新调用列表查询请求，无需返回操作后数据，所以此处按照卡片处理返回结果
	      result = this.buildFontResult(operaParam, resultVOs);
	    }
	    catch (BusinessException ex) {
	      Logger.error(ex.getMessage(), ex);
	      ExceptionUtils.wrapException(ex);
	    }
	    return result;
	  }

	  protected Object buildFontResult(NccBillOperatorParam operaParam,
	      Object result) {
	    AbstractBill[] resultVOs = (AbstractBill[]) result;
	    if (resultVOs.length == 1) {
	      BillCardOperator billCardOperator =
	          new BillCardOperator(operaParam.getPageCode());
	      BillCard card = billCardOperator.toCard(resultVOs[0]);
	      return card;
	    }
	    return null;
	  }

	  protected Object callActionScript(AggMonthOtTimeVO[] aggVOs)
	      throws BusinessException {

	    String actionCode = this.getActionCode();
	    String billType = MonthOtTimeVOConst.CONST_BILLTYPE_COST;

	    CloudPFlowContext context = new CloudPFlowContext();
	    context.setActionName(actionCode);
	    context.setBillType(billType);
	    context.setBillVos(aggVOs);

	    Logger.debug("开始调用动作脚本 ActionName[" + actionCode + "] BillType[" + billType
	        + "]...");
	    ICloudScriptPFlowService service = CommonUtil.getCPFlowService();
	    Object[] result = service.exeScriptPFlow(context);
	    if ((result == null) || (result.length == 0) || (result[0] == null)) {
	      return null;
	    }

	    if (result[0] instanceof PfProcessBatchRetObject) {
	      PfProcessBatchRetObject batchRetObject =
	          (PfProcessBatchRetObject) result[0];
	      String errMsg = batchRetObject.getExceptionMsg();
	      if ((errMsg != null) && !"".equals(errMsg)) {
	        ExceptionUtils.wrapBusinessException(errMsg);
	      }
	      return batchRetObject.getRetObj();
	    }

	    Logger.debug(
	        "调用动作脚本 ActionName[" + actionCode + "] BillType[" + billType + "]结束");
	    return result;
	  }

	  /**
	   * 动作编码
	   *
	   * @return
	   */
	  protected String getActionCode() {
	    return MonthOtTimeVOConst.CONST_ACTION_UNSAVEBILL;
	  }

	  /**
	   * 获取前端请求参数
	   *
	   * @param request
	   * @return
	   */
	  protected NccBillOperatorParam getRequestParam(IRequest request) {
	    // 解析request
	    String str = request.read();
	    IJson json = JsonFactory.create();
	    NccBillOperatorParam operaParam = json.fromJson(str, NccBillOperatorParam.class);
	    return operaParam;
	  }

	  protected AggMonthOtTimeVO[] queryBillsByPks(NccBillOperatorParam operaParam)
	      throws BusinessException {
		  AggMonthOtTimeVO[] vos = null;
	    String[] pks = operaParam.getPks();
	    if (pks.length != 0) {
	      // 根据参数查询结果
	      IMDPersistenceQueryService service =
	          CommonUtil.getMDQueryService();
	      String wheresql = SQLUtil
	          .buildSqlForIn(MonthOtTimeVOConst.CONST_PARENT_PRIMARYKEY, pks);
	      Collection<AggMonthOtTimeVO> bills = service.queryBillOfVOByCond(
	    		  AggMonthOtTimeVO.class, wheresql, true, false);
	      if ((bills == null) || (bills.size() != pks.length)) {
	        ExceptionUtils.wrapBusinessException("单据已被修改，请刷新页面后重试");
	      }
	      vos = bills.toArray(new AggMonthOtTimeVO[0]);
	    }
	    return vos;
	  }

	  protected Object unCommit(AggMonthOtTimeVO[] commitVOs)
	      throws BusinessException {
	    Object result = null;
	    // 判断是否定义审批流
	    boolean hasFlow = NCCFlowUtils.hasApproveflowDef(
	    	MonthOtTimeVOConst.CONST_BILLTYPE_COST, commitVOs[0]);
	    for (AggMonthOtTimeVO vo : commitVOs) {
	      Integer vbillstatus = (Integer) vo.getParent()
	          .getAttributeValue(MonthOtTimeVOConst.CONST_BILL_STATUS);
	      if (hasFlow && (vbillstatus == BillStatusEnum.APPROVED.toIntValue())) {
	        ExceptionUtils.wrapBusinessException("此单据有审批流，请先去审批中心 取消审批或者驳回后再进行操作");
	      }
	    }
	    // 有，则走提交动作脚本
	    if (hasFlow) {
	      result = this.callActionScript(commitVOs);
	    }
	    // 没有，则收回即弃审
	    else {
	      result = this.callAutoUnApproveActionScript(commitVOs);
	    }
	    return result;
	  }

	  private Object callAutoUnApproveActionScript(AggMonthOtTimeVO[] aggVOs)
	      throws BusinessException {

	    String actionCode = this.getActionCode();
	    String billType = MonthOtTimeVOConst.CONST_BILLTYPE_COST;
	    Map<Object, Object> extParam = new HashMap<Object, Object>();
	    extParam.put("IS_RELOADBILL", true);

	    // 调用收回即弃审接口
	    CloudPFlowContext context = new CloudPFlowContext();
	    context.seteParam(extParam);
	    context.setActionName(actionCode);
	    context.setBillType(billType);
	    context.setBillVos(aggVOs);

	    Logger.debug("开始调用动作脚本 ActionName[" + actionCode + "] BillType[" + billType
	        + "]...");
	    ICloudScriptPFlowService service = CommonUtil.getCPFlowService();
	    // 收回即弃审
	    Object[] result = service.exeScriptPFlow_UnSaveNoFlowBatch(context);

	    if ((result == null) || (result.length == 0) || (result[0] == null)) {
	      return null;
	    }
	    // 处理返回结果
	    if (result[0] instanceof PfProcessBatchRetObject) {
	      PfProcessBatchRetObject batchRetObject =
	          (PfProcessBatchRetObject) result[0];
	      String errMsg = batchRetObject.getExceptionMsg();
	      // 没有异常信息则表明执行成功
	      if ((errMsg != null) && !"".equals(errMsg)) {
	        ExceptionUtils.wrapBusinessException(errMsg);
	      }
	      return batchRetObject.getRetObj();
	    }
	    Logger.debug(
	        "调用动作脚本 ActionName[" + actionCode + "] BillType[" + billType + "]结束");
	    return result;
	  }

}
