//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by FernFlower decompiler)
//

package nccloud.web.ic.pub.action;

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

import nc.bs.dao.BaseDAO;
import nc.bs.dao.DAOException;
import nc.itf.scmpub.reference.uap.bd.currency.CurrencyInfo;
import nc.jdbc.framework.processor.ColumnProcessor;
import nc.pubitf.ic.flowaccount.BillInfo;
import nc.pubitf.ic.flowaccount.FlowAccountQuery;
import nc.vo.ic.general.define.ICBillBodyVO;
import nc.vo.ic.general.define.ICBillVO;
import nc.vo.ic.m4a.entity.GeneralInVO;
import nc.vo.ic.m4c.entity.SaleOutVO;
import nc.vo.ic.m4i.entity.GeneralOutVO;
import nc.vo.ic.pub.lang.ResBase;
import nc.vo.ic.pub.lang.RuleRes;
import nc.vo.ic.pub.util.ValueCheckUtil;
import nc.vo.ml.NCLangRes4VoTransl;
import nc.vo.pub.BusinessException;
import nc.vo.pub.CircularlyAccessibleValueObject;
import nc.vo.pub.lang.UFDouble;
import nc.vo.pubapp.pattern.model.transfer.bill.ClientBillCombinServer;
import nc.vo.pubapp.pattern.pub.MathTool;
import nc.vo.scmpub.res.billtype.ICBillType;
import nc.vo.scmpub.util.AppInfoContext;
import nccloud.commons.lang.StringUtils;
import nccloud.framework.core.exception.ExceptionUtils;
import nccloud.framework.core.json.IJson;
import nccloud.framework.core.util.GridCompareUtils;
import nccloud.framework.service.ServiceLocator;
import nccloud.framework.web.action.itf.ICommonAction;
import nccloud.framework.web.container.IRequest;
import nccloud.framework.web.json.JsonFactory;
import nccloud.framework.web.ui.config.PageTemplet;
import nccloud.framework.web.ui.model.row.Cell;
import nccloud.framework.web.ui.pattern.billcard.BillCard;
import nccloud.pubitf.ic.inbound.service.IICFilterData;
import nccloud.pubitf.riart.pflow.CloudPFlowContext;
import nccloud.pubitf.riart.pflow.ICloudScriptPFlowService;
import nccloud.web.ic.pub.entity.SrcFlagDTO;
import nccloud.web.ic.pub.precision.ICBaseBillcardPrecisionHandler;
import nccloud.web.ic.pub.resexp.ICPFResumeExceptionUtil;
import nccloud.web.ic.pub.utils.PageUtils;
import nccloud.web.ic.ui.pattern.billcard.ICBillCardOperator;

public class SaveAction implements ICommonAction {
    public SaveAction() {
    }

    public Object doAction(IRequest request) {
        CloudPFlowContext context = ICPFResumeExceptionUtil.processBefore(request);
        String str = request.read();
        IJson json = JsonFactory.create();
        BillCard card = (BillCard)json.fromJson(str, BillCard.class);
        SrcFlagDTO srcFlag = (SrcFlagDTO)json.fromJson(str, SrcFlagDTO.class);
        ICBillCardOperator operator = this.getOperator(card);
        ICBillVO[] vos = new ICBillVO[]{(ICBillVO)operator.toBill(request)};
        vos = this.fillBill(vos);

        for(ICBillVO vo : vos) {
            if ((vo instanceof GeneralOutVO || vo instanceof GeneralInVO) && !StringUtils.isNotEmpty(vo.getPrimaryKey()) && srcFlag.getSrcFlag() != null) {
                if ("assembly".equals(srcFlag.getSrcFlag().get("srcFlag"))) {
                    vo.getParentVO().setAttributeValue("srcflag", "1");
                }

                if ("teardown".equals(srcFlag.getSrcFlag().get("srcFlag"))) {
                    vo.getParentVO().setAttributeValue("srcflag", "2");
                }
            }
        }

        operator.setOriginBillcard(card);
        if (vos != null && vos.length > 0) {
            this.checkReferencedBill(vos);
            this.checkncorrespond(vos);
            vos = (ICBillVO[])((IICFilterData)ServiceLocator.find(IICFilterData.class)).filterFromFront(this.getBilltype().getCode(), vos);
            context.setBillType(this.getBilltype().getCode());
            context.setBillVos(vos);
            ICloudScriptPFlowService service = (ICloudScriptPFlowService)ServiceLocator.find(ICloudScriptPFlowService.class);
            context.setActionName("WRITE");
            ICBillVO[] obj = null;

            try {
                AppInfoContext.setBtnCode(this.getBtnCode());
                Object ret = service.exeScriptPFlow(context);
                if (ret instanceof ICBillVO[]) {
                    obj = (ICBillVO[])ret;
                } else {
                    obj = (ICBillVO[])((Object[])ret)[0];
                }
            } catch (Exception e) {
                return ICPFResumeExceptionUtil.handleICResumeException(e);
            }

            obj = ((IICFilterData)ServiceLocator.find(IICFilterData.class)).fillLocationVOs(this.getBilltype().getCode(), obj);
            ClientBillCombinServer<ICBillVO> util = new ClientBillCombinServer();
            this.processDelBody(vos);
            util.combine(vos, obj);
            this.processLocationVOs(vos, obj);
            this.handlerComputedPropertyField(vos);
            BillCard retcard = null;
            try {
                retcard = this.afterProcess(operator, vos[0]);
            } catch (DAOException e) {
                throw new RuntimeException(e);
            }
            retcard = GridCompareUtils.compareBillCardGrid(operator.getOriginBillcard(), retcard);
            operator.translate(retcard);
            this.dealCarrier(retcard);
            return retcard;
        } else {
            return null;
        }
    }

    private void checkncorrespond(ICBillVO[] vos) {
        ArrayList<String> lbids = new ArrayList();

        for(int i = 0; i < vos.length; ++i) {
            ICBillBodyVO[] bodys = vos[i].getBodys();

            for(int j = 0; j < bodys.length; ++j) {
                String cgeneralbid = bodys[j].getCgeneralbid();
                lbids.add(cgeneralbid);
            }
        }

        IICFilterData service = (IICFilterData)ServiceLocator.find(IICFilterData.class);
        Map<String, UFDouble> extnum = service.getExtnum(vos[0].getParentVO().getBillType(), (String[])lbids.toArray(new String[0]));
        StringBuilder errs = new StringBuilder();
        if (!ValueCheckUtil.isNullORZeroLength(extnum)) {
            for(int i = 0; i < vos.length; ++i) {
                ICBillBodyVO[] bodys = vos[i].getBodys();

                for(int j = 0; j < bodys.length; ++j) {
                    String cgeneralbid = bodys[j].getCgeneralbid();
                    UFDouble ncorrespondastnum = bodys[j].getNcorrespondastnum();
                    if (!MathTool.equals(ncorrespondastnum, (UFDouble)extnum.get(cgeneralbid))) {
                        errs.append(ResBase.getCrowno()).append(": ").append(bodys[j].getCrowno()).append(NCLangRes4VoTransl.getNCLangRes().getStrByID("4008001_0", "04008001-0975")).append("\n");
                    }
                }
            }
        }

        if (StringUtils.isNotEmpty(errs)) {
            ExceptionUtils.wrapBusinessException(errs.toString());
        }

    }

    private void checkReferencedBill(ICBillVO[] vos) {
        ICBillVO vo = vos[0];
        if (!StringUtils.isEmpty(vo.getHead().getCgeneralhid())) {
            List<String> idList = new ArrayList();
            String vbillcode = vos[0].getHead().getVbillcode();

            for(ICBillBodyVO bodyVO : vo.getBodys()) {
                if (StringUtils.isNotEmpty(bodyVO.getCgeneralbid())) {
                    idList.add(bodyVO.getCgeneralbid());
                }
            }

            if (idList != null && idList.size() > 0) {
                FlowAccountQuery flow = (FlowAccountQuery)ServiceLocator.find(FlowAccountQuery.class);
                Map<String, List<BillInfo>> refmap = new HashMap();

                try {
                    refmap = flow.queryBillReferenced((String[])idList.toArray(new String[idList.size()]));
                } catch (BusinessException e) {
                    ExceptionUtils.wrapException(e);
                }

                if (ValueCheckUtil.isNullORZeroLength(refmap)) {
                    return;
                }

                if (vo instanceof SaleOutVO) {
                    List<String> errList = new ArrayList();

                    for(ICBillBodyVO bodyVO : vo.getBodys()) {
                        if (bodyVO.getStatus() == 3) {
                            String cgeneralbid = bodyVO.getCgeneralbid();
                            if (StringUtils.isNotEmpty(cgeneralbid) && refmap.containsKey(cgeneralbid)) {
                                errList.add(bodyVO.getCrowno());
                            }
                        }
                    }

                    if (ValueCheckUtil.isNullORZeroLength(errList)) {
                        return;
                    }

                    StringBuilder errs = new StringBuilder();
                    errs.append(RuleRes.getBillRownReferencedErr(vbillcode)).append("\n");

                    for(String row : errList) {
                        errs.append(ResBase.getCrowno()).append(": ").append(row).append(NCLangRes4VoTransl.getNCLangRes().getStrByID("4008001_0", "04008001-0975")).append("\n");
                    }

                    ExceptionUtils.wrapBusinessException(errs.toString());
                }

                ExceptionUtils.wrapBusinessException(RuleRes.getBillReferencedErr(vbillcode));
            }

        }
    }

    public void handlerComputedPropertyField(ICBillVO[] obj) {
    }

    public String getBtnCode() {
        return null;
    }

    protected void processLocationVOs(ICBillVO[] vos, ICBillVO[] obj) {
        ICBillBodyVO[] clientBodys = vos[0].getChildrenVO();
        ICBillBodyVO[] serverBodys = obj[0].getChildrenVO();
        Map<String, ICBillBodyVO> bvomap = new HashMap();

        for(ICBillBodyVO bvo : serverBodys) {
            bvomap.put(bvo.getCgeneralbid(), bvo);
        }

        for(int i = 0; i < clientBodys.length; ++i) {
            if (bvomap.get(clientBodys[i].getCgeneralbid()) != null) {
                ICBillBodyVO serverBody = (ICBillBodyVO)bvomap.get(clientBodys[i].getCgeneralbid());
                clientBodys[i].setLocationVOs(serverBody.getLocationVOs());
            }
        }

    }

    private void processDelBody(ICBillVO[] vos) {
        ICBillBodyVO[] bodys = vos[0].getBodys();
        List<ICBillBodyVO> realbody = new ArrayList();

        for(ICBillBodyVO body : bodys) {
            if (body.getStatus() != 3) {
                realbody.add(body);
            }
        }

        vos[0].setChildrenVO((CircularlyAccessibleValueObject[])null);
        vos[0].setChildrenVO((CircularlyAccessibleValueObject[])realbody.toArray(new ICBillBodyVO[0]));
    }

    private ICBillCardOperator getOperator(BillCard card) {
        String[] info = card.getUserjson().split(",");
        String pagecode = null;
        String appcode = null;
        String pagecodecard = null;
        if (info.length > 1) {
            pagecode = info[0];
            appcode = info[1];
            pagecodecard = info[2];
        } else {
            pagecode = info[0];
            pagecodecard = card.getPageid();
        }

        ICBillCardOperator operator;
        if (appcode == null) {
            operator = new ICBillCardOperator((String)null, pagecodecard, pagecode);
        } else {
            PageTemplet pageTemplet = PageUtils.getPageTemplet(appcode, pagecodecard);
            operator = new ICBillCardOperator(pageTemplet.getOid(), pagecodecard, pagecode);
        }

        return operator;
    }

    protected ICBillVO[] fillBill(ICBillVO[] vos) {
        return vos;
    }

    private BillCard afterProcess(ICBillCardOperator operator, ICBillVO vo) throws DAOException {
        BillCard retcard = operator.toCard(vo, false, false);
        operator.processICBillstatusForWeb(retcard);

        // 获取来源单据号
        ICBillBodyVO[] bodys = vo.getChildrenVO();
        for(ICBillBodyVO body : bodys){
            String billid = body.getCfirstbillhid();
            String billid2 = body.getCfirstbillbid();
            //合格入库数量=数量
            if (StringUtils.isNotEmpty(billid) && body.getCfirsttype().equals("55A2")) {
                // 更新来源单据状态为 完成泰
                updateSourceBillStatus(billid,billid2, "2");
            }
        }

        // 其他处理逻辑
        String ccurrencyid = (String) vo.getBody(0).getAttributeValue("ccurrencyid");
        if (!StringUtils.isEmpty(ccurrencyid)) {
            String name = CurrencyInfo.getName(ccurrencyid);
            retcard.getBody().getModel().getListRows().forEach((row) -> {
                Cell cell = new Cell();
                cell.setValue(ccurrencyid);
                cell.setDisplay(name);
                row.addCell("ccurrencyid", cell);
            });
        }

        ICBaseBillcardPrecisionHandler handler = this.getPrecisionHandler(retcard);
        handler.process();
        return retcard;
    }
    private void updateSourceBillStatus(String sourceBillNo,String sourceBillbNo, String status) throws DAOException {
        BaseDAO baseDAO = new BaseDAO();
        //1.查询  流程生产订单明细行产品：合格入库数量=数量
        String getPlanNumSql = "SELECT nastnum from  mm_mo WHERE cmoid='[sourceBillbNo]' AND nastnum = ninastnum";
        getPlanNumSql = getPlanNumSql.replace("[sourceBillbNo]", sourceBillbNo);
        Object nplanoutastnum = baseDAO.executeQuery(getPlanNumSql,
                new ColumnProcessor("nastnum"));
        if (nplanoutastnum == null) {
            return;
        }else{
            // 2.更新流程生产订单明细行对应产品的下游单据备料计划状态改为完成态
            String sql = "update mm_pickm set fbillstatus = '" + status + "' where csourcebillrowid = '" + sourceBillbNo + "'";
            baseDAO.executeUpdate(sql);
        }
    }

    protected ICBillType getBilltype() {
        throw new RuntimeException(NCLangRes4VoTransl.getNCLangRes().getStrByID("4008027_0", "04008027-0198"));
    }

    protected ICBaseBillcardPrecisionHandler getPrecisionHandler(BillCard card) {
        return new ICBaseBillcardPrecisionHandler(card);
    }

    protected void dealCarrier(BillCard card) {
    }
}
