package nckd.jxccl.swc.stm.plugin.form.unitst;

import kd.bos.bill.BillShowParameter;
import kd.bos.dataentity.entity.DynamicObject;
import kd.bos.dataentity.entity.DynamicObjectCollection;
import kd.bos.dataentity.metadata.IDataEntityProperty;
import kd.bos.dataentity.metadata.clr.DataEntityPropertyCollection;
import kd.bos.entity.EntityMetadataCache;
import kd.bos.entity.MainEntityType;
import kd.bos.entity.datamodel.events.ChangeData;
import kd.bos.entity.datamodel.events.PropertyChangedArgs;
import kd.bos.form.ShowType;
import kd.bos.form.StyleCss;
import kd.bos.form.control.Control;
import kd.bos.form.events.AfterDoOperationEventArgs;
import kd.bos.form.plugin.AbstractFormPlugin;
import kd.bos.list.ListFilterParameter;
import kd.bos.list.ListShowParameter;
import kd.bos.orm.query.QCP;
import kd.bos.orm.query.QFilter;
import kd.bos.servicehelper.BusinessDataServiceHelper;
import kd.bos.servicehelper.QueryServiceHelper;
import kd.sdk.plugin.Plugin;
import nckd.jxccl.base.common.constant.FormConstant;
import nckd.jxccl.base.common.utils.ConvertUtil;
import nckd.jxccl.base.common.utils.DateUtil;
import nckd.jxccl.base.common.utils.QueryFieldBuilder;
import nckd.jxccl.base.common.utils.StrFormatter;
import nckd.jxccl.base.entity.helper.EntityHelper;
import nckd.jxccl.base.orm.helper.QFilterCommonHelper;
import nckd.jxccl.swc.constants.MasConstant;
import nckd.jxccl.swc.stm.business.StmService;
import nckd.jxccl.swc.constants.StmConstant;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Date;
import java.util.EventObject;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
* 单位工资总额预算申报
* 实体标识：nckd_unitstbudgetapply
* @author W.Y.C
* @date 2025/12/9 16:44
* @version 1.0
*/
public class UnitStBudgetApplyFormPlugin extends AbstractFormPlugin implements Plugin {

    @Override
    public void registerListener(EventObject e) {
        this.addClickListeners("nckd_labelap");
    }

    @Override
    public void click(EventObject evt) {
        String key = ((Control) evt.getSource()).getKey();
        if(key.equalsIgnoreCase("nckd_labelap")){
            Object value = this.getModel().getValue(StmConstant.NCKD_PAYUNIT);
            if(value == null){
                this.getView().showTipNotification("请先选择【填报单位】");
            }else{
                DynamicObject org = ConvertUtil.toDynamicObjectOrNull(value);
                if(org == null){
                    this.getView().showTipNotification("请先选择【填报单位】");
                }else{
                    DynamicObjectCollection corp = StmService.corp(org);
                    ListShowParameter listParameter = new ListShowParameter();
                    listParameter.setFormId("bos_listf7");
//                    listParameter.setFormId("haos_orgtreelistf7");
                    listParameter.setBillFormId("hbss_lawentity");
                    listParameter.setCaption(StrFormatter.format("【{}】下的法人企业",org.getString(FormConstant.NAME_KEY)));
                    listParameter.getOpenStyle().setShowType(ShowType.Modal);
                    StyleCss inlineStyleCss = new StyleCss();
                    inlineStyleCss.setHeight("600");
                    inlineStyleCss.setWidth("800");
                    listParameter.getOpenStyle().setInlineStyleCss(inlineStyleCss);

                    QFilter qFilter = QFilter.of("1=1");
                    List<Long> ids = new ArrayList<Long>();
                    for (DynamicObject dynamicObject : corp) {
                        long corpoRateOrgId = dynamicObject.getLong(String.join(".", "corporateorg", FormConstant.ID_KEY));
                        if(corpoRateOrgId > 0) {
                            ids.add(corpoRateOrgId);
                        }
                    }
                    qFilter.and(FormConstant.ID_KEY,QCP.in,ids);
                    ListFilterParameter listFilterParameter = new ListFilterParameter();
                    listFilterParameter.setFilter(qFilter); // 设置过滤条件
                    listParameter.setListFilterParameter(listFilterParameter);

                    this.getView().showForm(listParameter);
                }

            }

        }
    }

    @Override
    public void propertyChanged(PropertyChangedArgs e) {
        String fieldKey = e.getProperty().getName();
        ChangeData[] changeSet = e.getChangeSet();
        Object oldValue = changeSet[0].getOldValue();
        Object newValue = changeSet[0].getNewValue();
        if (Stream.of(StmConstant.NCKD_YEAR,  StmConstant.NCKD_PAYUNIT)
                .anyMatch(op -> op.equalsIgnoreCase(fieldKey))) {
            if(StmConstant.NCKD_PAYUNIT.equalsIgnoreCase(fieldKey)){
                if(!Objects.equals(oldValue, newValue) && newValue != null){
                    int count = StmService.countCorpNum(ConvertUtil.toDynamicObject(newValue));
                    this.getModel().setValue(StmConstant.NCKD_MGTELEFIRMCOUNT,count);
                }
            }
            if(!Objects.equals(oldValue, newValue)){
                loadData();
            }

        }
    }

    @Override
    public void afterDoOperation(AfterDoOperationEventArgs e) {
        if(e.getOperationResult() != null && e.getOperationResult().isSuccess()){
            String operateKey = e.getOperateKey();
            if("loadsubucybgtot".equalsIgnoreCase(operateKey)){
                Date year = this.getModel().getDataEntity(true).getDate(StmConstant.NCKD_YEAR);
                DynamicObject payUnit = this.getModel().getDataEntity(true).getDynamicObject(StmConstant.NCKD_PAYUNIT);
                if(year == null || payUnit == null){
                    this.getView().showErrorNotification("请先填写“年度”和“填报单位”");
                    return;
                }
                //载入直属下级单位本年度预算数合计
                MainEntityType mainEntityType = EntityMetadataCache.getDataEntityType(StmConstant.UNITSTBUDGETAPPLY_ENTITYID);
                Set<String> allFields = mainEntityType.getAllFields().keySet();
                QueryFieldBuilder queryFieldBuilder = QueryFieldBuilder.create();
                for (String field : allFields) {
                    if (field.startsWith("nckd_") && StmConstant.IGNORE_FIELDS.stream().noneMatch(ignoreField -> ignoreField.equalsIgnoreCase(field))) {
                        queryFieldBuilder.add(field);
                    }
                }
                queryFieldBuilder.add(String.join( ".", StmConstant.NCKD_PAYUNIT, FormConstant.NAME_KEY));
                Date beginOfYear = DateUtil.beginOfYear(year);
                Date endOfYear = DateUtil.endOfYear(year);
                QFilter qFilter = new QFilter(String.join(".",StmConstant.NCKD_PAYUNIT, FormConstant.PARENTORG_KEY, FormConstant.ID_KEY), QCP.equals, payUnit.getLong(FormConstant.ID_KEY))
                        .and(StmConstant.NCKD_YEAR,QCP.large_equals, beginOfYear)
                        .and(StmConstant.NCKD_YEAR,QCP.less_equals,  endOfYear)
                        .and(QFilterCommonHelper.getBillStatusFilter());
                DynamicObjectCollection query = QueryServiceHelper.query(StmConstant.UNITSTBUDGETAPPLY_ENTITYID, queryFieldBuilder.buildSelect(), new QFilter[]{qFilter});
                // 对查询结果按照buildSelectArray()中的字段进行汇总
                String[] summaryFields = queryFieldBuilder.buildSelectArray();
                Map<String, BigDecimal> summaryMap = new HashMap<>();
                String payUnitNames = "";
                if (!query.isEmpty()) {
                    // 初始化汇总值
                    for (String field : summaryFields) {
                        if (field.startsWith("nckd_")
                                && StmConstant.IGNORE_FIELDS.stream().noneMatch(ignoreField -> ignoreField.equalsIgnoreCase(field))) {
                            // 数值字段汇总
                            java.math.BigDecimal sumValue = query.stream()
                                    .map(obj -> obj.get(field))
                                    .filter(Objects::nonNull)
                                    .map(value -> new java.math.BigDecimal(value.toString()))
                                    .reduce(java.math.BigDecimal.ZERO, java.math.BigDecimal::add);
                            summaryMap.put(field, sumValue);
                        }
                    }
                    // 获取所有payunit名称并去重，然后用中文逗号连接
                    payUnitNames = query.stream()
                            .map(obj -> obj.getString(String.join(".", StmConstant.NCKD_PAYUNIT, FormConstant.NAME_KEY)))
                            .filter(Objects::nonNull)
                            .distinct()
                            .collect(Collectors.joining("，"));
                }else{
                    this.getView().showTipNotification(StrFormatter.format("【{}】直属下级单位没有【{}】年度预算数据", payUnit.getString(FormConstant.NAME_KEY),DateUtil.getYear(beginOfYear)));
                }
                if(!summaryMap.isEmpty()) {
                    List<String> summaryList = new ArrayList<>();
                    for (Map.Entry<String, BigDecimal> summaryEntry : summaryMap.entrySet()) {
                        //汇总字段不赋值
                        if (StmConstant.IGNORE_SUMMARY_FIELDS.stream().noneMatch(ignoreField -> ignoreField.equalsIgnoreCase(summaryEntry.getKey()))) {
                            this.getModel().setValue(summaryEntry.getKey(), summaryEntry.getValue());
                        }
                    }

                    this.getView().showSuccessNotification(StrFormatter.format("成功加载直属下级组织【{}】数据！",payUnitNames));
                }
            }
        }
    }


    private void loadData(){
        BillShowParameter showParameter = (BillShowParameter) this.getView().getFormShowParameter();
        String formId = showParameter.getFormId();
        if(formId.equalsIgnoreCase(StmConstant.UNITSTBUDGETADJUST_ENTITYID) || formId.equalsIgnoreCase(StmConstant.UNITSTSETTLEMENT_ENTITYID)) {
            Date year = this.getModel().getDataEntity(true).getDate(MasConstant.NCKD_YEAR);
            DynamicObject payUnit = this.getModel().getDataEntity(true).getDynamicObject(MasConstant.NCKD_PAYUNIT);
            if (year != null && payUnit != null) {
                // 清理现有数据
                clearExistingData();

                // 加载同年度同单位的预算申报数据
                QueryFieldBuilder queryFieldBuilder = QueryFieldBuilder.create()
                        .add(FormConstant.ID_KEY)
                        .orderDesc(FormConstant.CREATE_TIME_KEY);

                LocalDateTime beginOfYear = DateUtil.beginOfYear(DateUtil.toLocalDateTime(year));
                LocalDateTime endOfYear = DateUtil.endOfYear(DateUtil.toLocalDateTime(year));

                QFilter qFilter = new QFilter(StmConstant.NCKD_YEAR, QCP.large_equals, DateUtil.toDate(beginOfYear))
                        .and(StmConstant.NCKD_YEAR, QCP.less_equals, DateUtil.toDate(endOfYear))
                        .and(String.join(",", StmConstant.NCKD_PAYUNIT, FormConstant.ID_KEY), QCP.equals, payUnit.getLong(FormConstant.ID_KEY))
                        .and(QFilterCommonHelper.getBillStatusFilter());

                DynamicObjectCollection unitStBudgetApplyColl = QueryServiceHelper.query(
                        StmConstant.UNITSTBUDGETAPPLY_ENTITYID,
                        queryFieldBuilder.buildSelect(),
                        new QFilter[]{qFilter},
                        queryFieldBuilder.buildOrder());

                if (unitStBudgetApplyColl == null || unitStBudgetApplyColl.isEmpty()) {
                    this.getView().showTipNotification("未加载到数据，根据【年度】、【填报单位】未加载到\"单位工资总额预算申报\"数据！");
                    return;
                }

                DynamicObject unitStBudgetApply = unitStBudgetApplyColl.get(0);
                long id = unitStBudgetApply.getLong(FormConstant.ID_KEY);
                MainEntityType entityType = EntityMetadataCache.getDataEntityType(StmConstant.UNITSTBUDGETAPPLY_ENTITYID);
                DynamicObject[] load = BusinessDataServiceHelper.load(new Long[]{id}, entityType);

                if (load == null || load.length == 0) {
                    this.getView().showTipNotification("未加载到数据，根据【年度】、【填报单位】未加载到\"单位工资总额预算申报\"数据！");
                    return;
                }
                DynamicObject sourceAdj = null;
                //查询调整单
                if(formId.equalsIgnoreCase(StmConstant.UNITSTSETTLEMENT_ENTITYID)){
                    QFilter adjFilter = new QFilter(StmConstant.UNITSTBUDGETAPPLY_ENTITYID, QCP.equals,id)
                            .and(QFilterCommonHelper.getBillStatusFilter());
                    DynamicObjectCollection unitStBudgetAdjColl = QueryServiceHelper.query(
                            StmConstant.UNITSTBUDGETADJUST_ENTITYID,
                            queryFieldBuilder.buildSelect(),
                            new QFilter[]{qFilter},
                            queryFieldBuilder.buildOrder());
                    long adjId = 0;
                    if (!unitStBudgetAdjColl.isEmpty()) {
                        adjId = unitStBudgetAdjColl.get(0).getLong(FormConstant.ID_KEY);
                        MainEntityType adjEntityType = EntityMetadataCache.getDataEntityType(StmConstant.UNITSTBUDGETADJUST_ENTITYID);
                        DynamicObject[] adjLoad = BusinessDataServiceHelper.load(new Long[]{adjId}, adjEntityType);
                        if(adjLoad != null && adjLoad.length > 0){
                            sourceAdj = adjLoad[0];
                        }
                    }

                }

                copyBudgetData(formId,load[0],sourceAdj);
                DynamicObject dynamicObject = EntityHelper.newEntity(StmConstant.UNITSTBUDGETAPPLY_ENTITYID, load[0].getLong(StmConstant.ID_KEY));
                this.getModel().setValue(StmConstant.UNITSTBUDGETAPPLY_ENTITYID, dynamicObject);
                this.getView().showSuccessNotification("数据加载成功！");
            }
        }
    }



    // 提取清理数据逻辑
    private void clearExistingData() {
        DataEntityPropertyCollection properties = this.getModel().getDataEntityType().getProperties();
        for (IDataEntityProperty property : properties) {
            String name = property.getName();
            if (name.indexOf("nckd_") > -1 && this.getModel().getDataEntityType().getProperties().containsKey(name+"ls")) {
                this.getModel().setValue(name+"ls", null);
            }
        }
    }

    // 提取复制数据逻辑
    private void copyBudgetData(String formId,DynamicObject source,DynamicObject sourceAdj) {
        DataEntityPropertyCollection properties = source.getDynamicObjectType().getProperties();
        if(formId.equalsIgnoreCase(StmConstant.UNITSTBUDGETADJUST_ENTITYID)) {
            for (IDataEntityProperty property : properties) {
                String name = property.getName();
                if (name.indexOf("nckd_") > -1 && this.getModel().getDataEntityType().getProperties().containsKey(name + "ls")) {
                    this.getModel().setValue(name + "ls", source.get(name));
                }
            }
        }else{
            for (IDataEntityProperty property : properties) {
                String name = property.getName();
                if (name.indexOf("nckd_") > -1 && this.getModel().getDataEntityType().getProperties().containsKey(name + "ls")) {
                    this.getModel().setValue(name + "ls", source.get(name));
                }
            }
            if(sourceAdj != null){
                DataEntityPropertyCollection propertiesAdj = sourceAdj.getDynamicObjectType().getProperties();
                for (IDataEntityProperty property : propertiesAdj) {
                    String name = property.getName();
                    if (name.indexOf("nckd_") > -1 && this.getModel().getDataEntityType().getProperties().containsKey(name + "ad")) {
                        this.getModel().setValue(name + "ad", sourceAdj.get(name));
                    }
                }
            }
        }
    }
}