package yem.base.common.module.code.dynamic;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import kd.bos.entity.datamodel.IDataModel;
import kd.bos.form.FormShowParameter;
import kd.bos.form.IFormView;
import kd.bos.form.control.CodeEdit;
import kd.bos.form.control.Control;
import kd.bos.form.events.ClientCallBackEvent;
import kd.bos.form.plugin.AbstractFormPlugin;
import kd.sdk.plugin.Plugin;
import yem.base.common.utils.HttpHelper;
import yem.base.common.utils.YEM;

import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import java.util.EventObject;
import java.util.HashMap;
import java.util.Map;
import java.util.regex.Matcher;

/**
 * @author longh
 * @description: 脚本编辑器
 * @date 2024/1/27
 */
public class BillPostCodeEdit extends AbstractFormPlugin implements Plugin {
    private static final String KEY_ENGINE = "nashorn";// Nashorn -JavaScript引擎
    private static final String KEY_CTRL = "yem_codeeditap";
    private static final String KEY_EDIT = "setText";

    public static Object getRunResult(String jsCode, String... jsonParams) {
        return getRunResult(jsCode, false, jsonParams);
    }

    public static Object getRunResult(String jsCode, boolean backError, String... jsonParams) {
        jsCode = initCodeParams(jsCode, jsonParams);
        ScriptEngineManager manager = new ScriptEngineManager();
        ScriptEngine engine = manager.getEngineByName(KEY_ENGINE);
        Object resultObj = null;
        try {
            resultObj = engine.eval(jsCode);
        } catch (Exception e) {
            e.printStackTrace();
            if (backError) {
                return e.toString();
            }
        }
        return resultObj;
    }

    public static String initCodeParams(String jsCode, String... jsonParams) {
        for (int i = 0; i < jsonParams.length; i++) {
            String jsonParam = jsonParams[i];
            jsCode = jsCode.replaceAll("\\$" + (i + 1), Matcher.quoteReplacement(jsonParam));
        }
        return jsCode;
    }

    @Override
    public void afterCreateNewData(EventObject e) {
        super.afterCreateNewData(e);
        this.getView().addClientCallBack(KEY_EDIT);
    }

    @Override
    public void clientCallBack(ClientCallBackEvent e) {
        super.clientCallBack(e);
        String key = e.getName();
        if (KEY_EDIT.equals(key)) {
            setCodeText();
        }
    }

    private void setCodeText() {
        IDataModel model = this.getModel();
        model.deleteEntryData("yem_params");
        IFormView view = this.getView();
        FormShowParameter showParameter = view.getFormShowParameter();
        JSONArray params = showParameter.getCustomParam("params");
        if (params == null) {
            return;
        }
        for (int i = 0; i < params.size(); i++) {
            String param = params.getString(i);
            if (i == 0) {
                CodeEdit codeEdit = view.getControl(KEY_CTRL);
                if (YEM.isNotEmpty(param)) {
                    codeEdit.setText(param);
                } else {
                    codeEdit.setText("var Long = Packages.java.lang.Long;\nvar bill = $1;\nvar data = $2;\n");
                }
            } else {
                int index = model.createNewEntryRow("yem_params");
                model.setValue("yem_param", param.length() > 50 ? "点击查看详情" : param, index);
                model.setValue("yem_param_tag", param, index);
            }
        }
    }

    @Override
    public void registerListener(EventObject e) {
        super.registerListener(e);
        this.addClickListeners("btnok", "yem_test");
    }

    @Override
    public void click(EventObject evt) {
        super.click(evt);
        String key = ((Control) evt.getSource()).getKey();
        if ("btnok".equals(key)) {
            okClick();
        }
        if ("yem_test".equals(key)) {
            showResult();
        }
    }

    private void okClick() {
        IFormView view = this.getView();
        CodeEdit codeEdit = view.getControl(KEY_CTRL);
        String code = codeEdit.getText();
        view.returnDataToParent(code);
        view.close();
    }

    private void showResult() {
        IFormView view = this.getView();
        IDataModel model = this.getModel();
        CodeEdit codeEdit = view.getControl(KEY_CTRL);
        String jsCode = codeEdit.getText();
        String[] params = model.getEntryEntity("yem_params").stream().map(x -> x.getString("yem_param_tag")).toArray(String[]::new);
        Boolean apiexcute = (Boolean) model.getValue("yem_apiexcute");
        Object result;
        if (apiexcute) {
            result = getApiRunResult(jsCode, params);
        } else {
            result = getRunResult(jsCode, true, params);
        }
        view.showMessage(String.format("类型：%s\r\n结果：%s", result == null ? null : result.getClass().getName(), result));
    }

    private Object getApiRunResult(String jsCode, String[] params) {
        String codeNew = initCodeParams(jsCode, params);
        Map<String, String> header = new HashMap<>();
//        header.put("access_token", BillPostListOp.getAccessToken());
        header.put("access_token", "");
        JSONObject paramCode = new JSONObject();
        paramCode.put("code", codeNew);
        paramCode.put("backError", true);
//        String url = BillPostListOp.DOMAIN_CONTEXT_URL + BillPostListOp.CODE_EXCUTE_API;
        String url = "";
        String requestData;
        try {
            requestData = HttpHelper.httpPost(url, header, paramCode.toJSONString());
        } catch (Exception ex) {
            ex.printStackTrace();
            return String.format("接口异常：%s。", ex);
        }
        if (YEM.isNotEmpty(requestData)) {
            JSONObject data = JSONObject.parseObject(requestData);
            if (data.getBoolean("success")) {
                return data.get("data");
            } else {
                return String.format("接口失败：%s。", data.getString("message"));
            }
        }
        return null;
    }

}