package nckd.jxccl.sit.hcsi.formplugin.web.coordination;

import kd.bos.dataentity.entity.DynamicObject;
import kd.bos.dataentity.entity.DynamicObjectCollection;
import kd.bos.dataentity.utils.ObjectUtils;
import kd.bos.entity.datamodel.IDataModel;
import kd.bos.entity.datamodel.RowDataEntity;
import kd.bos.entity.datamodel.events.AfterAddRowEventArgs;
import kd.bos.entity.datamodel.events.PropertyChangedArgs;
import kd.bos.form.field.BasedataEdit;
import kd.bos.form.field.events.BeforeF7SelectEvent;
import kd.bos.form.field.events.BeforeF7SelectListener;
import kd.bos.form.plugin.AbstractFormPlugin;
import kd.bos.orm.query.QCP;
import kd.bos.orm.query.QFilter;
import kd.hr.hbp.common.util.HRStringUtils;
import kd.sdk.plugin.Plugin;
import kd.sdk.sit.sitbp.business.helper.SITBPServiceHelper;
import kd.sdk.sit.sitbp.common.StdResultInfoDTO;
import nckd.jxccl.sit.hcsi.common.constant.SitConstant;
import nckd.jxccl.sit.hcsi.utils.SITCoordinationUtils;

import java.util.*;

/**
 * Tyx 2025-12-05
 * 员工变动处理核定单 【nckd_hpdi_empcoordver_ext】
 */
public class HCSIEmpCoordVerifBillEditEx extends AbstractFormPlugin implements Plugin, BeforeF7SelectListener {

    private static final Map<Long, StdResultInfoDTO> stdResultInfoDTOMap = new HashMap<Long, StdResultInfoDTO>();


    @Override
    public void registerListener(EventObject e) {
        super.registerListener(e);
        BasedataEdit basedataEdit = this.getView().getControl("nckd_sinsurdimension");
        if (basedataEdit != null) {
            basedataEdit.addBeforeF7SelectListener(this);
        }
    }

    @Override
    public void afterBindData(EventObject e) {
        super.afterBindData(e);
        setWelfareTypeInsuranceTypeAttrEnable();
    }

    @Override
    public void propertyChanged(PropertyChangedArgs e) {
        super.propertyChanged(e);
        IDataModel model = this.getModel();
        String key = e.getProperty().getName();
        // 如果是 参保标准 / 险种 / 险种维度发生变化，需要去取参保标准中的标准维度值
        // 如果是 险种 / 险种维度发生变化，只需要修改当前子单据体的数据
        if(HRStringUtils.equalsAny(key, "nckd_welfaretype", "nckd_sinsurdimension")) {
            int rowIndex = model.getEntryCurrentRowIndex("nckd_entryentity");
            DynamicObject sinSurStd = (DynamicObject) model.getValue("sinsurstd_r31");
            if(ObjectUtils.isEmpty(sinSurStd))
                return;
            getStdInfoAndStdDimfromCache(sinSurStd);
            DynamicObject welfaretype = (DynamicObject) model.getValue("nckd_welfaretype", rowIndex);
            DynamicObject sinSurDimension = (DynamicObject) model.getValue("nckd_sinsurdimension", rowIndex);
            getDimensionValue(sinSurStd, welfaretype, sinSurDimension, rowIndex);
            setWelfareTypeInsuranceTypeAttrEnable();

            // 如果是险种，新旧值不一样的情况下，把个人基数跟单位基数清除掉
            if(HRStringUtils.equalsAny(key, "nckd_welfaretype")) {
                if(e.getChangeSet()[0].getNewValue() != e.getChangeSet()[0].getOldValue()) {
                    model.setValue(SitConstant.PAY_BASE_OF_EMPLOYEE_KEY, null, rowIndex);
                    model.setValue(SitConstant.PAY_BASE_OF_COMPANY_KEY, null, rowIndex);
                    this.getView().updateView("nckd_entryentity");
                }
            }
        }
        else if (HRStringUtils.equals(key, "sinsurstd_r31")) {
            Object newValue = e.getChangeSet()[0].getNewValue();
            if(!ObjectUtils.isEmpty(newValue)) {
                // 因为险种维度会根据参保标准+险种进行过滤，这里把子单据体的险种维度清空
                clearSubEntryDimension();
                getStdInfoAndStdDimfromCache((DynamicObject) newValue);
                getDimensionValue((DynamicObject) newValue);
                this.getView().updateView("nckd_entryentity");
            }
        }
    }


    /**
     * 参保标准修改的情况下，把当前单据体下数据也改一下
     * @param sinSurStd
     */
    public void getDimensionValue(DynamicObject sinSurStd) {
        DynamicObjectCollection entryCols = this.getModel().getDataEntity(true).getDynamicObjectCollection("nckd_entryentity");
        for(int i = 0 ; i < entryCols.size(); i++) {
            DynamicObject subEntry = entryCols.get(i);
            DynamicObject welfaretype = subEntry.getDynamicObject("nckd_welfaretype");
            DynamicObject sinSurDimension = subEntry.getDynamicObject("nckd_sinsurdimension");
            getDimensionValue(sinSurStd, welfaretype, sinSurDimension, i);
        }
    }

    /**
     * 子单据体获取并设置维度值
     * @param sinSurStd
     * @param welfaretype
     * @param sinSurDimension
     */
    public void getDimensionValue(DynamicObject sinSurStd, DynamicObject welfaretype, DynamicObject sinSurDimension, int rowIndex) {
        IDataModel model = this.getModel();
        Long cacheKey = sinSurStd.getLong("id");
        StdResultInfoDTO stdResultInfoDTO = stdResultInfoDTOMap.get(cacheKey);

        if(welfaretype == null)
            return;

        SITCoordinationUtils SITCoordinationUtils = new SITCoordinationUtils();
        Map result = SITCoordinationUtils.dealStdResult(stdResultInfoDTO, sinSurStd, welfaretype, sinSurDimension);

        Set<Long> keySet = SitConstant.INSURANCE_PAY_BASE_CONSTANTS.keySet();
        for (Long key : keySet) {
            if(result.get(key) == null) {
                model.setValue(SitConstant.INSURANCE_PAY_BASE_CONSTANTS.get(key), null, rowIndex);
            }
            else {
                model.setValue(SitConstant.INSURANCE_PAY_BASE_CONSTANTS.get(key), result.get(key), rowIndex);
            }
        }
    }

    /**
     * 从缓存中获取参保标准的信息，如果没有缓存则生成缓存
     * @param sinSurStd
     * @return
     */
    public void getStdInfoAndStdDimfromCache (DynamicObject sinSurStd) {
        Long cacheKey = sinSurStd.getLong("id");
        StdResultInfoDTO stdResultInfoDTO = stdResultInfoDTOMap.get(cacheKey);
        if(stdResultInfoDTO == null) {
            stdResultInfoDTO = SITBPServiceHelper.getStdInfoAndStdDim(Arrays.asList(sinSurStd.getLong("id"))).get(sinSurStd.getLong("id"));
            stdResultInfoDTOMap.put(cacheKey, stdResultInfoDTO);
        }
    }

    public void clearSubEntryDimension () {
        int rowCount = this.getModel().getEntryRowCount("nckd_entryentity");
        for (int i = 0; i < rowCount; i++) {
            this.getModel().setValue("nckd_sinsurdimension", null, i);
        }
    }


    /**
     * 险种维度选择前根据参保标准+险种过滤险种维度
     * @param e
     */
    @Override
    public void beforeF7Select(BeforeF7SelectEvent e) {
        String fieldKey = e.getProperty().getName();
        IDataModel model = this.getModel();
        if(HRStringUtils.equals(fieldKey, "nckd_sinsurdimension")) {
            // 行号
            int rowIndex = e.getRow();
            // 过滤前判断 参保标准和险种有没有选择
            DynamicObject sinSurStd = (DynamicObject) model.getValue("sinsurstd_r31");
            DynamicObject welfareType = (DynamicObject) model.getValue("nckd_welfaretype", rowIndex);
            if(ObjectUtils.isEmpty(sinSurStd)) {
                this.getView().showTipNotification("请先选择“参保标准”");
                e.setCancel(true);
                return;
            }
            else if (ObjectUtils.isEmpty(welfareType)) {
                this.getView().showTipNotification("请先选择“险种”");
                e.setCancel(true);
                return;
            }

            // 按照参保标准+险种 查询可选择的险种维度
            QFilter filter = new QFilter("id", QCP.in, getDimensionValueForFilter(sinSurStd, welfareType));
            e.getCustomQFilters().add(filter);
        }
        // 过滤参保标准
        else if (HRStringUtils.equals(fieldKey, "sinsurstd_r31")) {
            DynamicObject welfArePayer = (DynamicObject) model.getValue("welfarepayer_r31");
            if(ObjectUtils.isEmpty(welfArePayer)) {
                this.getView().showTipNotification("请先选择“实际参保单位”");
                e.setCancel(true);
                return;
            }
        }
    }

    public List<Long> getDimensionValueForFilter (DynamicObject sinSurStd, DynamicObject welfaretype) {
        Long sinSurStdId = sinSurStd.getLong("id");
        Long welfaretypeId = welfaretype.getLong("id");
        SITCoordinationUtils SITCoordinationUtils = new SITCoordinationUtils();
        return SITCoordinationUtils.queryDimensionValue(sinSurStdId, welfaretypeId);
    }

    /**
     * 获取当前单据体的所有险种
     * @return
     */
    private Set<Long> getWelfareTypeIds() {
        DynamicObjectCollection entryEntity = this.getModel().getEntryEntity("nckd_entryentity");
        Set<Long> welfareTypeIds = new HashSet<>();
        for (DynamicObject dynamicObject : entryEntity) {
            Long welfareTypeId = dynamicObject.getLong("nckd_welfaretype.id");
            if (welfareTypeId != null) {
                welfareTypeIds.add(welfareTypeId);
            }
        }
        return welfareTypeIds;
    }

    /**
     * 设置险种对应的险种属性是否可用
     */
    private void setWelfareTypeInsuranceTypeAttrEnable() {
        DynamicObjectCollection entryEntity = this.getModel().getEntryEntity("nckd_entryentity");
        Set<Long> welfareTypeIds = this.getWelfareTypeIds();
        Map<Long, Map<Long, Boolean>> welfareTypeInsuranceTypeAttrMap = SITCoordinationUtils.queryInsuranceTypeAttrSetting(welfareTypeIds, Arrays.asList(SitConstant.PAY_BASE_OF_EMPLOYEE_ID, SitConstant.PAY_BASE_OF_COMPANY_ID));
        for (int index = 0; index < entryEntity.size(); index++) {
            DynamicObject dynamicObject = entryEntity.get(index);
            if (dynamicObject.getBoolean("nckd_insured")) {
                long welfareTypeId = dynamicObject.getLong("nckd_welfaretype.id");
                Map<Long, Boolean> insuranceTypeAttrMap = (Map)welfareTypeInsuranceTypeAttrMap.get(welfareTypeId);
                if ((Boolean)insuranceTypeAttrMap.get(SitConstant.PAY_BASE_OF_EMPLOYEE_ID)) {
                    this.getView().setEnable(Boolean.TRUE, index, new String[]{SitConstant.PAY_BASE_OF_EMPLOYEE_KEY});
                } else {
                    this.getView().setEnable(Boolean.FALSE, index, new String[]{SitConstant.PAY_BASE_OF_EMPLOYEE_KEY});
                    dynamicObject.set(SitConstant.PAY_BASE_OF_EMPLOYEE_KEY, (Object)null);
                }

                if ((Boolean)insuranceTypeAttrMap.get(SitConstant.PAY_BASE_OF_COMPANY_ID)) {
                    this.getView().setEnable(Boolean.TRUE, index, new String[]{SitConstant.PAY_BASE_OF_COMPANY_KEY});
                } else {
                    this.getView().setEnable(Boolean.FALSE, index, new String[]{SitConstant.PAY_BASE_OF_COMPANY_KEY});
                    dynamicObject.set(SitConstant.PAY_BASE_OF_COMPANY_KEY, (Object)null);
                }
            } else {
                dynamicObject.set(SitConstant.PAY_BASE_OF_EMPLOYEE_KEY, (Object)null);
                dynamicObject.set(SitConstant.PAY_BASE_OF_COMPANY_KEY, (Object)null);
                this.getView().setEnable(Boolean.FALSE, index, new String[]{SitConstant.PAY_BASE_OF_EMPLOYEE_KEY});
                this.getView().setEnable(Boolean.FALSE, index, new String[]{SitConstant.PAY_BASE_OF_COMPANY_KEY});
            }
        }
        
    }


    /**
     * 新增分录的时候：
     * 如果变动大类是非调动的情况则携带表头的理论/实际参保单位
     * @param e
     */
    @Override
    public void afterAddRow(AfterAddRowEventArgs e) {
        super.afterAddRow(e);
        RowDataEntity[] rowDatas = e.getRowDataEntities();
        IDataModel model = this.getModel();
        DynamicObject dyn = model.getDataEntity();
        String chgNumber = dyn.getDynamicObject("coordruleparam").getString("chgevent_z.number");
        if(!chgNumber.equals("1020_S")) {
            for (RowDataEntity rowData : rowDatas) {
                model.setValue("nckd_welfarepayertheory", model.getValue("welfarepayertheory_r31"), rowData.getRowIndex());
                model.setValue("nckd_welfarepayer", model.getValue("welfarepayer_r31"), rowData.getRowIndex());
            }
        }
    }
}