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

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.plugin.AbstractFormPlugin;
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.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.constants.StmConstant;

import java.time.LocalDateTime;
import java.util.Date;
import java.util.StringJoiner;

/**
* 集团工资总额预算申报
* 实体标识：nckd_grpttlwgbgtsub
* @author W.Y.C
* @date 2025/12/12 15:25
* @version 1.0
*/
public class GrpTtlWgBgtSubFormPlugin extends AbstractFormPlugin implements Plugin {

    @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 (StmConstant.NCKD_YEAR.equalsIgnoreCase(fieldKey)) {
            loadUnitStBudgetApplyData();
            loadData();
            loadLastData();
        }
    }


    private void loadUnitStBudgetApplyData(){
        BillShowParameter showParameter = (BillShowParameter) this.getView().getFormShowParameter();
        String formId = showParameter.getFormId();
        if(formId.equalsIgnoreCase(StmConstant.GRPTTLWGBGTSUB_ENTITYID)) {
            Date year = this.getModel().getDataEntity(true).getDate(MasConstant.NCKD_YEAR);
            if (year != null) {
                // 加载同年度同单位的预算申报数据
                QueryFieldBuilder queryFieldBuilder = QueryFieldBuilder.create()
                        .add(FormConstant.ID_KEY)
                        .add(StmConstant.NCKD_DMTEAMMEM)
                        .add(StmConstant.NCKD_DMOTHER)
                        .add(StmConstant.NCKD_PROFMGR)
                        .add(StmConstant.NCKD_NONDIRONPOST)
                        .add(StmConstant.NCKD_OFFPOST)
                        .add(StmConstant.NCKD_TOTALWAGE)
                        .add(StmConstant.NCKD_DMOTHERTTOTAL)
                        .add(StmConstant.NCKD_PROFMGRTOTAL)
                        .add(StmConstant.NCKD_NONDIRWGBGT)
                        .add(StmConstant.NCKD_OFFPOSTBGT)
                        .addIdNumberName(StmConstant.NCKD_PAYUNIT)
                        .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(QFilterCommonHelper.getBillStatusFilter());

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

                // nckd_onpstnum：职工平均人数（人）-其中：在岗职工
                java.math.BigDecimal onpStNum = java.math.BigDecimal.ZERO;
                // nckd_onpstwg：应发工资总额（万元）-其中：在岗职工
                java.math.BigDecimal onpStWg = java.math.BigDecimal.ZERO;
                // nckd_onpstwg：应发工资总额（万元）-其中：在岗职工
                java.math.BigDecimal offpStNum = java.math.BigDecimal.ZERO;
                // nckd_offpstliv：不在岗职工生活费
                java.math.BigDecimal offpStLiv = java.math.BigDecimal.ZERO;
                if (unitStBudgetApplyColl == null || unitStBudgetApplyColl.isEmpty()) {
                    this.getView().showTipNotification("未加载到数据，根据【年度】未加载到\"单位工资总额预算申报\"数据！");
                }else{
                    StringJoiner payUnitNameJoin = new StringJoiner("，");
                    for (DynamicObject obj : unitStBudgetApplyColl) {
                        /*10+11+12+13+14
                        直管干部（班子成员）：nckd_dmteammem
                        直管干部（其他）：nckd_dmother
                        职业经理人：nckd_profmgr
                        非直管干部在岗职工：nckd_nondironpost
                        不在岗职工：nckd_offpost*/
                        onpStNum = onpStNum.add(obj.getBigDecimal(StmConstant.NCKD_DMTEAMMEM) != null ? obj.getBigDecimal(StmConstant.NCKD_DMTEAMMEM) : java.math.BigDecimal.ZERO)
                                .add(obj.getBigDecimal(StmConstant.NCKD_DMOTHER) != null ? obj.getBigDecimal(StmConstant.NCKD_DMOTHER) : java.math.BigDecimal.ZERO)
                                .add(obj.getBigDecimal(StmConstant.NCKD_PROFMGR) != null ? obj.getBigDecimal(StmConstant.NCKD_PROFMGR) : java.math.BigDecimal.ZERO)
                                .add(obj.getBigDecimal(StmConstant.NCKD_NONDIRONPOST) != null ? obj.getBigDecimal(StmConstant.NCKD_NONDIRONPOST) : java.math.BigDecimal.ZERO);
//                                .add(obj.getBigDecimal(StmConstant.NCKD_OFFPOST) != null ? obj.getBigDecimal(StmConstant.NCKD_OFFPOST) : java.math.BigDecimal.ZERO);
                        offpStNum =  offpStNum.add(obj.getBigDecimal(StmConstant.NCKD_OFFPOST) != null ? obj.getBigDecimal(StmConstant.NCKD_OFFPOST) : java.math.BigDecimal.ZERO);

                        /*15+21+25+29
                        工资总额：nckd_totalwage
                        直管干部（其他）：nckd_dmotherttotal
                        职业经理人：nckd_profmgrtotal
                        非直管干部在岗职工工资：nckd_nondirwgbgt*/
                        onpStWg = //onpStWg.add(obj.getBigDecimal(StmConstant.NCKD_TOTALWAGE) != null ? obj.getBigDecimal(StmConstant.NCKD_TOTALWAGE) : java.math.BigDecimal.ZERO)
                                onpStWg.add(obj.getBigDecimal(StmConstant.NCKD_DMOTHERTTOTAL) != null ? obj.getBigDecimal(StmConstant.NCKD_DMOTHERTTOTAL) : java.math.BigDecimal.ZERO)
                                .add(obj.getBigDecimal(StmConstant.NCKD_PROFMGRTOTAL) != null ? obj.getBigDecimal(StmConstant.NCKD_PROFMGRTOTAL) : java.math.BigDecimal.ZERO)
                                .add(obj.getBigDecimal(StmConstant.NCKD_NONDIRWGBGT) != null ? obj.getBigDecimal(StmConstant.NCKD_NONDIRWGBGT) : java.math.BigDecimal.ZERO);

                        /*30
                        不在岗职工：nckd_offpostbgt*/
                        offpStLiv = offpStLiv.add(obj.getBigDecimal(StmConstant.NCKD_OFFPOSTBGT) != null ? obj.getBigDecimal(StmConstant.NCKD_OFFPOSTBGT) : java.math.BigDecimal.ZERO);

                        String payUnitName = obj.getString(String.join(".", StmConstant.NCKD_PAYUNIT, FormConstant.NAME_KEY));
                        payUnitNameJoin.add(payUnitName);
                    }
                    this.getView().showSuccessNotification(StrFormatter.format("成功加载单位工资总额【{}】数据！", payUnitNameJoin.toString()));
                }

                // 设置汇总值到界面
                this.getModel().setValue(StmConstant.NCKD_ONPSTNUM, onpStNum);
                this.getModel().setValue(StmConstant.NCKD_OFFPSTNUM, offpStNum);
                this.getModel().setValue(StmConstant.NCKD_ONPSTWG, onpStWg);
                this.getModel().setValue(StmConstant.NCKD_OFFPSTLIV, offpStLiv);
                this.getView().updateView(StmConstant.NCKD_ONPSTNUM);
                this.getView().updateView(StmConstant.NCKD_OFFPSTNUM);
                this.getView().updateView(StmConstant.NCKD_ONPSTWG);
                this.getView().updateView(StmConstant.NCKD_OFFPSTLIV);

            }
        }
    }


    private void loadData(){
        BillShowParameter showParameter = (BillShowParameter) this.getView().getFormShowParameter();
        String formId = showParameter.getFormId();
        if(formId.equalsIgnoreCase(StmConstant.GRPTTLWGBGTADJ_ENTITYID)) {
            Date year = this.getModel().getDataEntity(true).getDate(MasConstant.NCKD_YEAR);
            if (year != 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(QFilterCommonHelper.getBillStatusFilter());

                DynamicObjectCollection unitStBudgetApplyColl = QueryServiceHelper.query(
                        StmConstant.GRPTTLWGBGTSUB_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.GRPTTLWGBGTSUB_ENTITYID);
                DynamicObject[] load = BusinessDataServiceHelper.load(new Long[]{id}, entityType);

                if (load == null || load.length == 0) {
                    this.getView().showTipNotification("未加载到数据，根据【年度】未加载到\"集团工资总额预算申报\"数据！");
                    return;
                }

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

    /**
     * 加载上年度执行情况
      * @param 
     * @return: void
     * @author W.Y.C
     * @date: 2025/12/14 18:59
     */
    private void loadLastData(){
        BillShowParameter showParameter = (BillShowParameter) this.getView().getFormShowParameter();
        String formId = showParameter.getFormId();
        if(formId.equalsIgnoreCase(StmConstant.GRPTTLWGBGTSUB_ENTITYID)) {
            Date year = this.getModel().getDataEntity(true).getDate(MasConstant.NCKD_YEAR);
            if (year != null) {
                // 清理现有数据
                DataEntityPropertyCollection currentProperties = this.getModel().getDataEntityType().getProperties();
                for (IDataEntityProperty property : currentProperties) {
                    String name = property.getName();
                    if (name.indexOf("nckd_") > -1 && (name.endsWith("lya") || name.endsWith("lye"))) {
                        this.getModel().setValue(name, null);
                    }
                }
                //ad -> lay
                //ex -> lye


                LocalDateTime lastYear = DateUtil.minusYears(DateUtil.toLocalDateTime(year), 1);

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

                LocalDateTime beginOfYear = DateUtil.beginOfYear(lastYear);
                LocalDateTime endOfYear = DateUtil.endOfYear(lastYear);

                QFilter qFilter = new QFilter(StmConstant.NCKD_YEAR, QCP.large_equals, DateUtil.toDate(beginOfYear))
                        .and(StmConstant.NCKD_YEAR, QCP.less_equals, DateUtil.toDate(endOfYear))
                        .and(QFilterCommonHelper.getBillStatusFilter());

                DynamicObjectCollection unitStBudgetApplyColl = QueryServiceHelper.query(
                        StmConstant.GRPTTLWGBGTEXEC_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.GRPTTLWGBGTEXEC_ENTITYID);
                DynamicObject[] load = BusinessDataServiceHelper.load(new Long[]{id}, entityType);

                if (load == null || load.length == 0) {
                    this.getView().showTipNotification("未加载到数据，根据【年度】未加载到上年度\"集团工资总额执行情况\"数据！");
                    return;
                }

                DataEntityPropertyCollection properties = load[0].getDynamicObjectType().getProperties();
                for (IDataEntityProperty property : properties) {
                    String name = property.getName();
                    if (name.indexOf("nckd_") > -1  && (name.endsWith("ad") || name.endsWith("ex"))) {
                        String currentName = name.replace("ad", "lya").replace("ex", "lye");
                        if(this.getModel().getDataEntityType().getProperties().containsKey(currentName)) {
                            this.getModel().setValue(currentName, load[0].get(name));
                        }
                    }
                }
                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) && !name.endsWith("ad") && !name.endsWith("ex") && StmConstant.IGNORE_FIELDS.stream().noneMatch(ignoreField -> ignoreField.equalsIgnoreCase(name))) {
                this.getModel().setValue(name, null);
            }
        }
    }

    // 提取复制数据逻辑
    private void copyBudgetData(DynamicObject source) {
        DataEntityPropertyCollection properties = source.getDynamicObjectType().getProperties();
        for (IDataEntityProperty property : properties) {
            String name = property.getName();
            if (name.indexOf("nckd_") > -1 && this.getModel().getDataEntityType().getProperties().containsKey(name) && !name.endsWith("ad") && !name.endsWith("ex") && StmConstant.IGNORE_FIELDS.stream().noneMatch(ignoreField -> ignoreField.equalsIgnoreCase(name))) {
                this.getModel().setValue(name, source.get(name));
            }
        }
    }
}