package yem.wmzh.csm.customeraccess.from;

import com.alibaba.druid.util.StringUtils;
import kd.bos.bill.AbstractBillPlugIn;
import kd.bos.bill.OperationStatus;
import kd.bos.dataentity.entity.DynamicObject;
import kd.bos.dataentity.entity.DynamicObjectCollection;
import kd.bos.dataentity.entity.ILocaleString;
import kd.bos.entity.datamodel.IDataModel;
import kd.bos.entity.datamodel.events.ChangeData;
import kd.bos.entity.datamodel.events.PropertyChangedArgs;
import kd.bos.form.CloseCallBack;
import kd.bos.form.FormShowParameter;
import kd.bos.form.IFormView;
import kd.bos.form.ShowType;
import kd.bos.form.control.Control;
import kd.bos.form.control.EntryGrid;
import kd.bos.form.events.ClosedCallBackEvent;
import kd.bos.orm.query.QCP;
import kd.bos.orm.query.QFilter;
import kd.bos.servicehelper.BusinessDataServiceHelper;
import kd.bos.servicehelper.user.UserServiceHelper;
import yem.base.common.utils.YEM;


import java.util.*;

/**
 * @Description 客商准入单表单插件
 * @Author: LiuHB
 * @CreateTime: 2025-02-07  14:40
 */
public class CustomeraccessBillPlugin extends AbstractBillPlugIn {

    /**
     * @Description: 在此事件，可以侦听各个控件的插件事件
     * @function 1.侦听【客商地址】字段点击
     * @purposes 用户与界面上的控件进行交互时，触发此事件。
     */

    @Override
    public void registerListener(EventObject e) {
        super.registerListener(e);
        this.addClickListeners("yem_associatedaddress"); //监听【客商地址】
    }

    /**
     * @Description: 界面初始化
     * @function 根据当前人员携带所在部门
     * @purposes 对已创建好的模型数据包进一步加工
     */
    @Override
    public void afterCreateNewData(EventObject e) {
        super.afterCreateNewData(e);
        IDataModel model = this.getModel();
        IFormView view = this.getView();
        //获取当前登录人所在部门
        Long dptid = getdepartmentid();
        model.setValue("yem_department", dptid);

    }

    /**
     * @Description: 根据当前登陆人获取所在部门
     * @function 获取当前登录人部门id
     * @purposes 客商准入单初始化【部门】赋值
     */

    private Long getdepartmentid() {
        // 获取当前登录人id
        long userId = UserServiceHelper.getCurrentUserId();
        //查询人员
        DynamicObject user = BusinessDataServiceHelper.loadSingle("bos_user", new QFilter[]{new QFilter("id", QCP.equals, userId)});
        DynamicObjectCollection entryentity = user.getDynamicObjectCollection("entryentity");
        Long dptid = 0L;
        if (entryentity.size() > 0) {
            for (DynamicObject userow : entryentity) {
                boolean ispartjob = userow.getBoolean("ispartjob");
                if(!ispartjob){
                    DynamicObject dpt = (DynamicObject) userow.get("dpt");
                    dptid = null != dpt ? dpt.getLong("id") : null;
                }
            }
        }
        return dptid;
    }

    /**
     * @description: 值改变事件
     * @function 1.内部业务单元校验
     *           2.去除客商名称中的空格,如果都是中文字符去除所有空格，包含其他字符则去除前后空格
     *           3.去除客商英文名称前后空格
     * @purposes 通知插件字段发生了改变，可以同步调整其他字段值
     */
    @Override
    public void propertyChanged(PropertyChangedArgs e) {
        super.propertyChanged(e);
        String key = e.getProperty().getName();
        ChangeData changeData = e.getChangeSet()[0];
        int index = changeData.getRowIndex();
        IDataModel model = this.getModel();
        IFormView view = this.getView();
        switch (key) {
            case "yem_internal":
            case "yem_merchantstname":
                ILocaleString yemMerchantstnamed = (ILocaleString) this.getModel().getValue("yem_merchantstname");
                String yemMerchantstnames = yemMerchantstnamed.getLocaleValue();
                Boolean yemInternal = (Boolean) model.getValue("yem_internal");//内部业务单元
                String domesticoroverseas = (String)model.getValue("yem_domesticoroverseas");
                //去除客商名称中的空格
                String merchantstnames = nameprocessing(yemMerchantstnames,domesticoroverseas);
                //校验必须有与客商名称匹配的组织
                matchOrganizations(yemInternal, merchantstnames);
                break;
            case "yem_merchantstnames_en":
                String yemMerchantstnamesEns = (String) this.getModel().getValue("yem_merchantstnames_en");
                String trimmedString = yemMerchantstnamesEns.trim();
                this.getModel().setValue("yem_merchantstnames_en", trimmedString);
                break;

        }
    }



    /**
     * @Description: 插件可以在此相应点击事件，如弹出单独的编辑界面。
     * @function 1.弹出{客商地址}动态表单，回填联系人分录
     * @purposes 点击文本字段的按钮时，触发此事件
     */

    @Override
    public void click(EventObject evt) {
        super.click(evt);
        Control c = (Control) evt.getSource();
        String key = c.getKey();
        switch (key){
            case "yem_associatedaddress":
                addressPasswd("yem_wmzh_cusadress", "yem_associatedaddress");
                break;
            default:
                break;
        }


    }


    /**
     * @Description: 弹出{客商地址}动态表单
     */
    private void addressPasswd(String dynamicform, String button) {
        FormShowParameter showParameter = new FormShowParameter();
        showParameter.setStatus(OperationStatus.ADDNEW);
        showParameter.getOpenStyle().setShowType(ShowType.Modal);
        Map<String, Object> map = this.showInfoForm();
        showParameter.setCustomParams(map);
        showParameter.setCloseCallBack(new CloseCallBack(this, button));
        showParameter.setFormId(dynamicform);
        this.getView().showForm(showParameter);
    }

    /**
     * @Description: 构建向动态表单传递的数据集
     */

    private Map<String, Object> showInfoForm() {
        Map<String, Object> map = new HashMap<>();
        DynamicObjectCollection yem_contactinfo_e = this.getModel().getEntryEntity("yem_linkmaninfo_e");
        EntryGrid contactinfo = this.getControl("yem_linkmaninfo_e");
        int[] selectRows = contactinfo.getSelectRows();
        if (selectRows != null) {
            for (int selectRow : selectRows) {
                DynamicObject yem_contactinfo = yem_contactinfo_e.get(selectRow); // 获取选中行的单据体数据
                map.put("row", yem_contactinfo);
            }
        }
        return map;
    }

    /**
     * @Description: 动态表单关闭回调事件
     */

    @Override
    public void closedCallBack(ClosedCallBackEvent closedCallBackEvent) {
        // super.closedCallBack(closedCallBackEvent);
        Object returnData = closedCallBackEvent.getReturnData();
        // 判断标识是否匹配，并验证动态表单返回数据不为空，不验证返回值可能会报空指针
        if (StringUtils.equals(closedCallBackEvent.getActionId(), "yem_associatedaddress")
                && null != closedCallBackEvent.getReturnData()) {
            // 这里返回对象为Object，可强转成相应的其他类型，
            HashMap<String, Object> values = (HashMap<String, Object>) returnData;
            this.setInwardInfo(values);
        }
    }

    /**
     * @Description: 分录赋值
     * @purposes 将动态表单数据回填到对应行上
     */

    private void setInwardInfo(Map<String, Object> values) {
        IDataModel model = this.getModel();
        int indexof = (int) values.get("indexof");
        model.setValue("yem_associatedaddress", values.get("yem_addressname"), indexof);
        model.setValue("yem_addressnumber", values.get("yem_addressnumber"), indexof);
        model.setValue("yem_addressname", values.get("yem_addressname"), indexof);
        model.setValue("yem_tradeterms", values.get("yem_tradeterms"), indexof);
        model.setValue("yem_clearanceco", values.get("yem_clearanceco"), indexof);
        model.setValue("yem_forwarderco", values.get("yem_forwarderco"), indexof);
        model.setValue("yem_addressphone", values.get("yem_addressphone"), indexof);
        model.setValue("yem_zipcode", values.get("yem_zipcode"), indexof);
        model.setValue("yem_linkman", values.get("yem_linkman"), indexof);
        model.setValue("yem_timezone", values.get("yem_timezone"), indexof);
        model.setValue("yem_addressenable", values.get("yem_addressenable"), indexof);
        model.setValue("yem_addressdefault", values.get("yem_addressdefault"), indexof);
        model.setValue("yem_admindivision", values.get("yem_admindivision"), indexof);
        model.setValue("yem_detailaddress", values.get("yem_detailaddress"), indexof);
        model.setValue("yem_customeraddrsspur", values.get("yem_customeraddrsspur"), indexof);
    }

    /**
     * @Description: 去除客商名称中的空格
     * @function 去除客商名称中的空格, 如果都是中文字符去除所有空格，包含其他字符则去除前后空格
     */
    private String nameprocessing(String yemMerchantstnames, String domesticoroverseas) {
        String merchantstnames = "";
        boolean containsValidChars = false;
        boolean containsChinese = false;
//        if("A".equals(domesticoroverseas)) {
        // 检查是否包含中文字符
        if(null!=yemMerchantstnames) {
            if("A".equals(domesticoroverseas)) {
                yemMerchantstnames = yemMerchantstnames.replace("(", "（").replace(")", "）");
                containsValidChars = yemMerchantstnames.codePoints()
                        .allMatch(codePoint ->
                                (codePoint >= 0x4e00 && codePoint <= 0x9fa5) || // 基本汉字
                                        (codePoint >= 0x3400 && codePoint <= 0x4dbf) || // 扩展A
                                        (codePoint >= 0xf900 && codePoint <= 0xfaff) || // 兼容汉字
                                        (codePoint >= 0x20000 && codePoint <= 0x2a6df) || // 扩展B
                                        (codePoint >= 0x2a700 && codePoint <= 0x2b73f) || // 扩展C
                                        (codePoint >= 0x2b740 && codePoint <= 0x2b81f) || // 扩展D
                                        (codePoint >= 0x2b820 && codePoint <= 0x2ceaf) || // 扩展E
                                        (codePoint == 0xFF08 || codePoint == 0xFF09) ||   // 中文括号 （）
                                        (codePoint == 0x0020)                            // 空格
                        );

                // 检查字符串中是否包含至少一个中文字符
                 containsChinese = yemMerchantstnames.codePoints()
                        .anyMatch(codePoint ->
                                (codePoint >= 0x4e00 && codePoint <= 0x9fa5) || // 基本汉字
                                        (codePoint >= 0x3400 && codePoint <= 0x4dbf) || // 扩展A
                                        (codePoint >= 0xf900 && codePoint <= 0xfaff) || // 兼容汉字
                                        (codePoint >= 0x20000 && codePoint <= 0x2a6df) || // 扩展B
                                        (codePoint >= 0x2a700 && codePoint <= 0x2b73f) || // 扩展C
                                        (codePoint >= 0x2b740 && codePoint <= 0x2b81f) || // 扩展D
                                        (codePoint >= 0x2b820 && codePoint <= 0x2ceaf)    // 扩展E
                        );
            }
            boolean isValid = containsValidChars && containsChinese;
            if (isValid) {
                    //字符串全部由中文字符组成
                    //去除客商名称空格
                    merchantstnames = removeSpacesFromString(yemMerchantstnames);
                    this.getModel().setValue("yem_merchantstname", merchantstnames);

            } else {
                //字符串包含非中文字符
                merchantstnames = yemMerchantstnames.trim();
                this.getModel().setValue("yem_merchantstname", merchantstnames);
            }
        }
        return merchantstnames;
    }


    /**
     * @Description: 去除客商名称空格
     * @function 删除空格
     * @purposes 避免客户输入失误
     */
    private String removeSpacesFromString(String yemMerchantstnames) {
        if (yemMerchantstnames == null) {
            return null;
        }
        // 去除字符串中的所有空格并返回结果
        return yemMerchantstnames.replace(" ", "");
    }

    /**
     * @Description:  内部业务单元校验
     * @function 1.校验必须有与客商名称匹配的组织
     *           2.校验内部业务单元客商和准入组织名称是否相同
     * @purposes 确保该客商在系统的行政组织中
     */
    private void matchOrganizations(Boolean yemInternal, String yemMerchantstnames) {
        IDataModel model = this.getModel();
        // 如果 内部业务单元 为 false 或 客商中文名称 为空，直接返回
        if (!yemInternal || YEM.isEmpty(yemMerchantstnames)) {
            return;
        }
        //获取当前单据准入组织
        DynamicObject org = (DynamicObject)model.getValue("org");
        String name = null != org ? org.getString("name") : "";
        // 加载行政组织信息
        List<String> adminOrgNames = loadAdminOrgNames();
        // 1.检查 客商名称 是否在行政组织列表中
        if (!adminOrgNames.contains(yemMerchantstnames)) {
            model.setValue("yem_merchantstname",null);
            this.getView().showErrorNotification("未找到与之匹配的组织，请重新检查相关信息。");
        }if(!name.equals(yemMerchantstnames)){
            model.setValue("yem_merchantstname",null);
            this.getView().showErrorNotification("该内部业务单元客商:"+yemMerchantstnames+"与准入组织不符，请检查！");
        }
        this.getView().updateView();
    }

    /**
     * @Description: 获取所有组织名称
     * @function 查询行政组织
     * @purposes 辅助方法：加载行政组织名称列表
     */
    public static List<String> loadAdminOrgNames() {
        String adminOrgFields = "number,name"; // 查询字段：编码和名称
        DynamicObject[] adminOrgs = BusinessDataServiceHelper.load("bos_adminorg", adminOrgFields, null);

        List<String> adminOrgNames = new ArrayList<>();
        for (DynamicObject adminOrg : adminOrgs) {
            String name = adminOrg.getLocaleString("name").getLocaleValue();
            adminOrgNames.add(name);
        }
        return adminOrgNames;
    }
}
