package nc.impl.so.m30.action.main;

import nc.bs.framework.common.NCLocator;
import nc.bs.pub.action.N_30_APPROVE;
import nc.bs.scmpub.rule.VOSagaFrozenValidateRule;
import nc.bs.so.m30.maintain.rule.delete.RewritePromotePriceDeleteRule;
import nc.bs.so.m30.plugin.Action30PlugInPoint;
import nc.bs.so.m30.rule.approve.*;
import nc.bs.so.m30.rule.atp.SaleOrderVOATPAfterRule;
import nc.bs.so.m30.rule.atp.SaleOrderVOATPBeforeRule;
import nc.bs.so.m30.rule.credit.RenovateARByHidsBeginRule;
import nc.bs.so.m30.rule.credit.RenovateARByHidsEndRule;
import nc.bs.so.m30.rule.m35.ArsubOffsetAfterApproveRule;
import nc.bs.so.m30.rule.me.SaleOrderVOApproveAfterRule;
import nc.impl.pubapp.pattern.data.bill.BillQuery;
import nc.impl.pubapp.pattern.data.vo.VOUpdate;
import nc.impl.pubapp.pattern.rule.IRule;
import nc.impl.pubapp.pattern.rule.processer.AroundProcesser;
import nc.itf.scmpub.reference.uap.group.SysInitGroupQuery;
import nc.vo.credit.engrossmaintain.pub.action.M30EngrossAction;
import nc.vo.ml.NCLangRes4VoTransl;
import nc.vo.pub.BusinessException;
import nc.vo.pub.lang.UFBoolean;
import nc.vo.pubapp.AppContext;
import nc.vo.pubapp.pattern.exception.ExceptionUtils;
import nc.vo.pubapp.pattern.log.TimeLog;
import nc.vo.scmpub.msg.rule.UpdateMsgStatusRule;
import nc.vo.scmpub.res.billtype.SOBillType;
import nc.vo.scmpub.util.AppInfoContext;
import nc.vo.so.m30.entity.SaleOrderBVO;
import nc.vo.so.m30.entity.SaleOrderHVO;
import nc.vo.so.m30.entity.SaleOrderVO;
import nc.vo.so.pub.enumeration.BillStatus;
import nc.vo.so.pub.rule.SOPfStatusChgRule;
import nccloud.bs.so.mobile.saleorder.operation.rule.MobAfterApproveMessageRule;
import nccloud.commons.lang.ArrayUtils;
import nccloud.nc.vo.pub.pf.BusFlowInfoVO;
import nccloud.pubitf.riart.businesstype.IPFBusinessTypeService;

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

public class ApproveSaleOrderAction {
    public ApproveSaleOrderAction() {
    }

    public Object approve(SaleOrderVO[] bills, N_30_APPROVE script) {
        Object ret = null;

        try {
            AroundProcesser<SaleOrderVO> processer = new AroundProcesser(Action30PlugInPoint.ApproveAction);
            TimeLog.logStart();
            this.setAppInfoContext();
            this.addBeforeRule(processer);
            processer.before(bills);
            TimeLog.info(NCLangRes4VoTransl.getNCLangRes().getStrByID("4006011_0", "04006011-0162"));
            ret = script.procActionFlow(script.getPfParameterVO());
            SaleOrderVO[] newbills = script.getVos();
            this.updateNewBillStatus(newbills);
            TimeLog.logStart();
            Integer newbillstatus = newbills[0].getParentVO().getFstatusflag();
            String ctranstype = newbills[0].getParentVO().getVtrantypecode();
            this.addAfterRule(processer, newbillstatus, ctranstype);
            processer.after(newbills);
            TimeLog.info(NCLangRes4VoTransl.getNCLangRes().getStrByID("4006011_0", "04006011-0163"));
            String[] pk_so_sales = new String[0];

            for (SaleOrderVO svo : newbills) {
                pk_so_sales = (String[]) ArrayUtils.add(pk_so_sales, svo.getParentVO().getCsaleorderid());
            }

            newbills = (SaleOrderVO[]) (new BillQuery(SaleOrderVO.class)).query(pk_so_sales);
            if (null == ret) {
                ret = newbills;
            }
        } catch (Exception ex) {
            ExceptionUtils.wrappException(ex);
        }

        return ret;
    }

    private void updateNewBillStatus(SaleOrderVO[] newbills) {
        new HashMap();
        List<String> pk_org = new ArrayList();

        for (SaleOrderVO vo : newbills) {
            for (SaleOrderBVO bvo : vo.getChildrenVO()) {
                String csettleorgid = bvo.getCsettleorgid();
                if (!pk_org.contains(csettleorgid)) {
                    pk_org.add(csettleorgid);
                }
            }
        }

        Map<String, Boolean> isEnable = SysInitGroupQuery.isRMEnabled(pk_org);

        for (SaleOrderVO vo : newbills) {
            List<SaleOrderBVO> newbvo = new ArrayList();

            for (SaleOrderBVO bvo : vo.getChildrenVO()) {
                String csettleorgid = bvo.getCsettleorgid();
                if (!isEnable.isEmpty() && !(Boolean) isEnable.get(csettleorgid)) {
                    bvo.setRmcontractbflag(UFBoolean.TRUE);
                } else {
                    newbvo.add(bvo);
                }
            }
        }

        SOPfStatusChgRule statuschgrule = new SOPfStatusChgRule();
        SaleOrderHVO[] updateheads = new SaleOrderHVO[newbills.length];
        List<SaleOrderBVO> listbody = new ArrayList();
        int i = 0;

        for (SaleOrderVO ordervo : newbills) {
            statuschgrule.changePfToBillStatus(ordervo);
            updateheads[i++] = ordervo.getParentVO();

            for (SaleOrderBVO bvo : ordervo.getChildrenVO()) {
                listbody.add(bvo);
            }
        }

        String[] headupname = new String[]{"fstatusflag"};
        VOUpdate<SaleOrderHVO> headupsrv = new VOUpdate();
        headupsrv.update(updateheads, headupname);
        String[] bodyupname = new String[]{"frowstatus", "rmcontractbflag"};
        VOUpdate<SaleOrderBVO> bodyupsrv = new VOUpdate();
        SaleOrderBVO[] updatebodys = (SaleOrderBVO[]) listbody.toArray(new SaleOrderBVO[listbody.size()]);
        bodyupsrv.update(updatebodys, bodyupname);
    }

    private void addAfterRule(AroundProcesser<SaleOrderVO> processer, Integer newbillstatus, String ctranstype) {
        IRule<SaleOrderVO> rule = null;
        if (SysInitGroupQuery.isCREDITEnabled()) {
            IRule<SaleOrderVO> var6 = new RenovateARByHidsEndRule(M30EngrossAction.M30Approve);
            processer.addAfterRule(var6);
        }

        boolean icEnable = SysInitGroupQuery.isICEnabled();
        if (icEnable) {
            IRule<SaleOrderVO> var7 = new SaleOrderVOATPAfterRule();
            processer.addAfterRule(var7);
        }

        IRule<SaleOrderVO> var8 = new ArsubOffsetAfterApproveRule();
        processer.addAfterRule(var8);
        if (BillStatus.AUDIT.equalsValue(newbillstatus)) {
            IRule<SaleOrderVO> var9 = new ApproveStateRule();
            processer.addAfterRule(var9);
            if (this.isExistDelivery(ctranstype)) {
                processer.addAfterRule(new SendMsgToDeliveryRule());
            }
        }

        if (BillStatus.NOPASS.equalsValue(newbillstatus) && SysInitGroupQuery.isPRICEEnabled()) {
            IRule<SaleOrderVO> var10 = new RewritePromotePriceDeleteRule();
            processer.addAfterRule(var10);
        }

        IRule<SaleOrderVO> var11 = new SaleOrderVOApproveAfterRule();
        processer.addAfterRule(var11);
        processer.addAfterRule(new MobAfterApproveMessageRule());
        processer.addAfterRule(new SaleOrderCreateRmBeforeRule());
        // 在审批后推送到MES系统
        processer.addAfterRule(new AfterApprovingSynchronizeRuleMES());
    }

    private boolean isExistDelivery(String ctranstype) {
        IPFBusinessTypeService pfservice = (IPFBusinessTypeService) NCLocator.getInstance().lookup(IPFBusinessTypeService.class);
        BusFlowInfoVO[] refbillinfos = null;
        String groupId = AppContext.getInstance().getPkGroup();
        String userId = AppContext.getInstance().getPkUser();

        try {
            refbillinfos = pfservice.getDownstreamInfo(SOBillType.Order.getCode(), ctranstype, groupId, userId, true);
            String delieverycode = SOBillType.Delivery.getCode();

            for (BusFlowInfoVO info : refbillinfos) {
                if (delieverycode.equals(info.getBilltype())) {
                    return true;
                }
            }

            return false;
        } catch (BusinessException e) {
            ExceptionUtils.wrappException(e);
            return false;
        }
    }

    private void addBeforeRule(AroundProcesser<SaleOrderVO> processer) {
        IRule<SaleOrderVO> rule = new VOSagaFrozenValidateRule();
        processer.addBeforeRule(rule);
        IRule<SaleOrderVO> var4 = new CheckApprovableRule();
        processer.addBeforeRule(var4);
        if (SysInitGroupQuery.isCREDITEnabled()) {
            IRule<SaleOrderVO> var5 = new RenovateARByHidsBeginRule(M30EngrossAction.M30Approve);
            processer.addBeforeRule(var5);
        }

        boolean icEnable = SysInitGroupQuery.isICEnabled();
        if (icEnable) {
            IRule<SaleOrderVO> var6 = new SaleOrderVOATPBeforeRule();
            processer.addBeforeRule(var6);
        }

        IRule<SaleOrderVO> var7 = new BusiLog();
        processer.addBeforeRule(var7);
        processer.addBeforeRule(new UpdateMsgStatusRule("csaleorderid"));
    }

    private void setAppInfoContext() {
        String buttonCode = AppInfoContext.getBtnCode();
        if ("".equals(buttonCode) || null == buttonCode) {
            AppInfoContext.setBtnCode("appoveCenter");
        }

    }
}
