package fi.cas.opplugin;

import com.kingdee.util.StringUtils;
import kd.bos.dataentity.entity.DynamicObject;
import kd.bos.entity.plugin.AbstractOperationServicePlugIn;
import kd.bos.entity.plugin.PreparePropertysEventArgs;
import kd.bos.entity.plugin.args.*;
import kd.bos.logging.Log;
import kd.bos.logging.LogFactory;
import kd.bos.orm.query.QFilter;
import kd.bos.servicehelper.BusinessDataServiceHelper;
import kd.bos.servicehelper.operation.SaveServiceHelper;
import org.json.JSONArray;
import org.json.JSONObject;
import java.io.IOException;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 付款处理，同步资金系统付款状态
 * @author wanghaiwu_kd
 * @date 2025/06/12
 */
public class PaymentSynPayStatusOpPlugin extends AbstractOperationServicePlugIn {
    private static final Log logger = LogFactory.getLog(PaymentSynPayStatusOpPlugin.class);

    @Override
    public void onPreparePropertys(PreparePropertysEventArgs e) {
        super.onPreparePropertys(e);

        List<String> fieldKeys = e.getFieldKeys();

        fieldKeys.add("billno");
        fieldKeys.add("billstatus");
        fieldKeys.add("nckd_paystatus");
        fieldKeys.add("nckd_sbyy");
        fieldKeys.add("nckd_fqqdrq");
        fieldKeys.add("nckd_fkcs");
        fieldKeys.add("nckd_bbh");
        fieldKeys.add("paymenttype");
    }

    @Override
    public void beforeExecuteOperationTransaction(BeforeOperationArgs args) {
        super.beforeExecuteOperationTransaction(args);

        String operationKey = args.getOperationKey();
        DynamicObject[] payBillObjs = args.getDataEntities();
        logger.info("开始执行操作：{},实体:{}",operationKey, payBillObjs);


        StringBuilder errMsg = new StringBuilder();

        //支付状态同步
        if("nckd_synpaystatus".equals(operationKey)){
            DynamicObject jkpzxx = BusinessDataServiceHelper.loadSingle("nckd_jkpzxx",new QFilter[]{new QFilter("number","=","paytoJHX")});
            String url =  jkpzxx.getString("nckd_servername");
            boolean isESBApi = jkpzxx.getBoolean("nckd_isesb");

            for (DynamicObject dataEntity : payBillObjs) {
                String billNum = dataEntity.getString("billno");
                String billStatus = dataEntity.getString("billstatus");
                String payStatus = dataEntity.getString("nckd_paystatus");
                int fkcs = dataEntity.getInt("nckd_fkcs");
                DynamicObject paymenttype = dataEntity.getDynamicObject("paymenttype");

                String billName = "付款单";
                if("同名转账".equals(paymenttype.getString("name")) || "跨主体调拨".equals(paymenttype.getString("name"))){
                    billName = "资金调度单";
                }

                if(!"C".equals(billStatus)){
                    logger.info(billName + "同步失败，未提交资金付款。实体：{}", dataEntity);

                    errMsg.append(billName + "(" + billNum + ")不是已审核状态，不需要同步付款状态").append("\r\n");
                    continue;
                }

                if(!payStatus.matches("2|6")){
                    logger.info(billName + "同步失败，未提交资金付款。实体：{}", dataEntity);

                    errMsg.append(billName + "(" + billNum + ")不是【支付中】【支付失败】状态，不需要同步付款状态").append("\r\n");
                    continue;
                }

                if(fkcs <= 0){
                    logger.info(billName + "同步失败，未提交资金付款。实体：{}", dataEntity);

                    errMsg.append(billName + "(" + billNum + ")未提交资金付款，请提交资金付款后再操作同步付款状态").append("\r\n");
                    continue;
                }

                //调用接口查询付款状态
                JSONObject param = new JSONObject();
                PayBillToolUtil.headJson(param);
                JSONObject data = new JSONObject();
                data.put("ERP_INS_ID",dataEntity.getPkValue()+"");

                param.put("data",data);
                param.put("txDateTime",Utils.getData(new Date(), "yyyyMMddHHmmss"));
                param.put("batchNo",TypeUtils.nullToString(dataEntity.get("billno"))+"-"+TypeUtils.nullToString(dataEntity.get("nckd_bbh"))+"-"+Utils.getData(new Date(), "yyyyMMddHHmmss"));
                param.put("code","JY-NSTC-Q001");

                String bodyjson = param.toString();


                logger.info(billName + "："+billNum+"传入参数"+param.toString());


                /***************************************add by wanghaiwu 20225/05/24*************************************************************/
                //改成调用restful ebs api的方式
//            Map<String, String> header = new HashMap<>();
//            header.put("Content-Type", "application/json; charset=UTF-8");

                Map<String, String> tokenMap = PayBillToolUtil.getNtscToken();

                if(tokenMap == null){
                    logger.info(billName + "：" + billNum + "查询失败： 获取token失败");

                    errMsg.append(billName + "(" + billNum + ")查询失败： 获取token失败").append("\r\n");
                    continue;
                }

                if(!"0".equals(tokenMap.get("code"))){
                    logger.info(billName + "：" + billNum + "查询失败：获取token失败, " + tokenMap.get("msg"));

                    errMsg.append(billName + "(" + billNum + ")查询失败： 获取token失败").append("\r\n");

                    continue;
                }

                String token = tokenMap.get("msg");

                //改成调用轻舟的方式
                Map<String, String> header = new HashMap<>();
                header.put("Content-Type", "application/json; charset=UTF-8");
                header.put("Authorization", "Bearer " + token);

                //如果是esb接口，需要包一层参数
                if(isESBApi) {
                    bodyjson = PayBillToolUtil.buildEsbApiBodyJSON(new JSONObject(bodyjson));
                }

                String apiResult = "";
                try {
                    logger.info("付款查询接口调用参数：" + bodyjson);

                    apiResult = HttpUtils.postjson(url, header, bodyjson);
                } catch (IOException e) {
                    logger.info(billName + "：" + billNum + "查询失败：" + e.getMessage());
                    errMsg.append(billName + "(" + billNum + ")查询失败：" + e.getMessage()).append("\r\n");
                    continue;
                }

                if(StringUtils.isEmpty(apiResult)){
                    logger.info(billName + "：" + billNum + "查询结果为空");

                    errMsg.append(billName + "(" + billNum + ")查询结果为空").append("\r\n");
                    continue;
                }

                logger.info(billName + "：" + billNum + "返回参数" + apiResult);

//            JSONObject cbsReturnJson = new JSONObject(apiResult);

                JSONObject esbReturnJson = new JSONObject(apiResult);
                if(esbReturnJson.get("responseData") == null){
                    logger.info(billName + "：" + billNum + ", 未正常返回responseData参数");

                    errMsg.append(billName + "(" + billNum + "), 未正常返回responseData参数").append("\r\n");
                    return;
                }

                JSONArray esbJSONArray = esbReturnJson.getJSONArray("responseData");
                if(esbJSONArray == null || esbJSONArray.length() == 0){
                    logger.info(billName + "：" + billNum + ", 未正常返回responseData参数");

                    errMsg.append(billName + "(" + billNum + "), 未正常返回responseData参数").append("\r\n");
                    return;
                }

                JSONObject cbsReturnJson = esbJSONArray.getJSONObject(0);
                /************************************************************/


                logger.info(billName + "："+billNum+"返回参数"+cbsReturnJson.toString());

                if(cbsReturnJson==null||cbsReturnJson.get("data")==null){
                } else{
                    String errcode = cbsReturnJson.get("resultCode")+"";
                    JSONObject bodyinfo = cbsReturnJson.getJSONObject("data");
                    if(bodyinfo!=null){
                        boolean isupdate = false;
                        if ("000000".equals(errcode)) {//已查询到，不代表支付成功
                            String zfstatus = bodyinfo.getString("RET_CODE");//0：付款成功  1：付款失败 2：流程中 3:驳回 4：部分成功
                            String errormsg =bodyinfo.getString("ERROR_MSG");
                            if("-2".equals(zfstatus)){//流程中
                                //判断原因是否有变化
                                String sbyy =  dataEntity.getString("nckd_sbyy");
                                if(errormsg == null || "".equals(errormsg)){//空不更新

                                }else if(errormsg.equals(sbyy)){//相等不更新

                                }else{
                                    dataEntity.set("nckd_sbyy",errormsg);//错误信息更新
                                    isupdate = true;
                                }
                            }else if("0".equals(zfstatus)){//成功
                                dataEntity.set("nckd_paystatus",3);
                                dataEntity.set("nckd_sbyy","支付成功");//错误信息更新
                                isupdate = true;
                            }else if("-1".equals(zfstatus)){//失败
                                dataEntity.set("nckd_paystatus",6);//支付失败
                                dataEntity.set("nckd_sbyy",errormsg);//错误信息更新
                                isupdate = true;
                            }else if("-3".equals(zfstatus)){//驳回
                                dataEntity.set("nckd_paystatus",5);//驳回
                                dataEntity.set("nckd_sbyy",errormsg);//错误信息更新
                                isupdate = true;
                            }
                            if(isupdate){
                                SaveServiceHelper.update(new DynamicObject[]{dataEntity});
                                PayBillToolUtil.saveupdatelog(dataEntity,bodyjson,cbsReturnJson.toString());
                            }
                        }
                    }
                }
            }
        }


        if(errMsg.length() > 0) {
            ////将错误信息返回到前端
            args.setCancelMessage(errMsg.toString());
            args.setCancel(true);

            System.out.println("PaymentSynPayStatusOpPlugin 错误信息：" + errMsg.toString());
        }

    }

    @Override
    public void beginOperationTransaction(BeginOperationTransactionArgs e) {
        super.beginOperationTransaction(e);
    }

    @Override
    public void rollbackOperation(RollbackOperationArgs e) {
        super.rollbackOperation(e);
    }

    @Override
    public void endOperationTransaction(EndOperationTransactionArgs e) {
        super.endOperationTransaction(e);
    }

    @Override
    public void afterExecuteOperationTransaction(AfterOperationArgs e) {
        super.afterExecuteOperationTransaction(e);
    }
}
