package nckd.jxccl.hr.excells.plugin.form;

import kd.bos.common.enums.EnableEnum;
import kd.bos.dataentity.entity.DynamicObject;
import kd.bos.dataentity.entity.DynamicObjectCollection;
import kd.bos.dataentity.entity.ILocaleString;
import kd.bos.dataentity.metadata.IDataEntityProperty;
import kd.bos.entity.BasedataEntityType;
import kd.bos.entity.EntityMetadataCache;
import kd.bos.entity.MainEntityType;
import kd.bos.entity.datamodel.events.ChangeData;
import kd.bos.entity.datamodel.events.IDataModelChangeListener;
import kd.bos.entity.datamodel.events.PropertyChangedArgs;
import kd.bos.entity.property.BasedataProp;
import kd.bos.form.field.BasedataEdit;
import kd.bos.form.field.events.AfterBindingDataEvent;
import kd.bos.form.field.events.BasedataEditListener;
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.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.entity.helper.EntityHelper;
import nckd.jxccl.base.hrpi.helper.EmpPosOrgRelHelper;
import nckd.jxccl.hr.excells.common.ExcellsConstant;

import java.time.LocalDateTime;
import java.util.Date;
import java.util.EventObject;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
* 优秀生津贴
* 实体标识：nckd_excellentssallowance
* @author W.Y.C
* @date 2026/1/2 20:49
* @version 1.0
*/
public class ExcellentssAllowanceFormPlugin extends AbstractFormPlugin implements Plugin, BeforeF7SelectListener, BasedataEditListener, IDataModelChangeListener {

    @Override
    public void registerListener(EventObject e) {
        // 1. 获取基础资料字段控件
        BasedataEdit materialEdit = this.getView().getControl(FormConstant.NCKD_PERSON);
        if(materialEdit != null) {
            // 2. 注册 beforeF7Select 事件监听器
            materialEdit.addBeforeF7SelectListener(this);
        }

        BasedataEdit mulEdit = this.getControl("nckd_pereduexp");
        mulEdit.addBasedataEditListener(this);
    }


    @Override
    public void beforeF7Select(BeforeF7SelectEvent event) {
        String fieldName = event.getProperty().getName();
        if (FormConstant.NCKD_PERSON.equals(fieldName)) {
            //查询优秀生
            QueryFieldBuilder queryFieldBuilder = QueryFieldBuilder.create().addIdNumberName(FormConstant.EMPLOYEE_KEY).add("nckd_fttopgrad");
            QFilter qFilter = new QFilter(ExcellsConstant.NCKD_HONORTYPE, QCP.is_notnull, null)
                    .and(ExcellsConstant.NCKD_HONORTYPE, QCP.large_equals, 0);
            DynamicObjectCollection query = QueryServiceHelper.query("nckd_hrpi_topstudent", queryFieldBuilder.buildSelect(), new QFilter[]{qFilter});
            LocalDateTime tenYearsAgo = DateUtil.addYears(DateUtil.now(), 10);

            Date date = DateUtil.toDate(tenYearsAgo);
            List<Long> personId = query.stream()
                    .filter(dynamicObject -> {
                        Date nckdFttopgrad = dynamicObject.getDate("nckd_fttopgrad");
                        if (nckdFttopgrad == null) {
                            return false; // 排除空值
                        }
                        LocalDateTime nckdFttopgradLocalDateTime = DateUtil.toLocalDateTime(nckdFttopgrad);
                        return nckdFttopgrad.compareTo(date) <= 0;
                    })
                    .map(dynamicObject -> dynamicObject.getLong(String.join(".", FormConstant.EMPLOYEE_KEY, FormConstant.ID_KEY)))
                    .collect(Collectors.toList());
            // 4. 创建过滤条件：物料编码 like 'Item%'
            QFilter filter = new QFilter(FormConstant.ID_KEY, QCP.in, personId);
            // 5. 将条件添加到事件中
            event.getCustomQFilters().add(filter);
        }
    }

    @Override
    public void propertyChanged(PropertyChangedArgs e) {
        String name = e.getProperty().getName();
        ChangeData[] changeSet = e.getChangeSet();
        Object newValue = changeSet[0].getNewValue();
        Object oldValue = changeSet[0].getOldValue();
        if(FormConstant.NCKD_PERSON.equalsIgnoreCase( name)){
            int rowIndex = changeSet[0].getRowIndex();
            if(newValue != null) {
                if(!Objects.equals(newValue, oldValue)) {
                    DynamicObject person = ConvertUtil.toDynamicObjectOrNull(newValue);
                    if (person != null) {
                        initValue(person.getLong(FormConstant.ID_KEY), rowIndex);

                        Date effdt = ConvertUtil.toDate(this.getModel().getValue(ExcellsConstant.NCKD_EFFDT, rowIndex));
                        if (effdt != null) {
                            lastPerfRank(person.getLong(FormConstant.ID_KEY), effdt, rowIndex);
                        }
                    }
                }

            }else{
                this.getModel().setValue(ExcellsConstant.NCKD_DEP,null,rowIndex);
                this.getModel().setValue(ExcellsConstant.NCKD_FTTOPGRAD,null,rowIndex);
                this.getModel().setValue(ExcellsConstant.NCKD_POSITION,null,rowIndex);
                this.getModel().setValue(ExcellsConstant.NCKD_UNIV,null,rowIndex);
                this.getModel().setValue(ExcellsConstant.NCKD_UNDERGRADMAJOR,null,rowIndex);
                this.getModel().setValue(ExcellsConstant.NCKD_PEREDUEXP,null,rowIndex);
                this.getModel().setValue(ExcellsConstant.NCKD_HONORTYPE,null,rowIndex);
                this.getModel().setValue(ExcellsConstant.NCKD_RANKANDTOTAL,null, rowIndex);
                this.getModel().setValue(ExcellsConstant.NCKD_APPRAISALRESULT, null,rowIndex);
            }
        }else if("nckd_effdt".equalsIgnoreCase( name)){
            int rowIndex = changeSet[0].getRowIndex();
            if(newValue != null) {
                if(!Objects.equals(newValue, oldValue)) {
                    Date date = ConvertUtil.toDate(this.getModel().getValue(ExcellsConstant.NCKD_EFFDT));

                    Object value = this.getModel().getValue(FormConstant.NCKD_PERSON, rowIndex);
                    if (date != null && value != null) {
                        DynamicObject person = ConvertUtil.toDynamicObjectOrNull(value);
                        if (person != null) {
                            lastPerfRank(person.getLong(FormConstant.ID_KEY), date, rowIndex);
                        }
                    }
                }
            }else{
                this.getModel().setValue(ExcellsConstant.NCKD_RANKANDTOTAL,null, rowIndex);
                this.getModel().setValue(ExcellsConstant.NCKD_APPRAISALRESULT, null,rowIndex);
            }



        }
    }

    private void lastPerfRank(Long personId, Date date, int rowIndex) {
        if(personId != null && personId > 0) {
            Date lastDate = DateUtil.minusYears(date, 1);
            //上年度绩效和排名
            QueryFieldBuilder perfRankMgmtFieldBuilder = QueryFieldBuilder.create()
                    .add("nckd_topranks")
                    .addGroup(new String[]{"nckd_perfrankmgmtentry"}, "nckd_toprank")
                    .addIdNumberName("nckd_perfrankmgmtentry", "nckd_appraisalresult");
            QFilter qFilter1 = new QFilter(String.join(".", "nckd_perfrankmgmtentry", "nckd_person"), QCP.equals, personId)
                    .and("nckd_theyear", QCP.less_equals, DateUtil.getYear(lastDate));
            DynamicObjectCollection query = QueryServiceHelper.query("nckd_perfrankmgmt", perfRankMgmtFieldBuilder.buildSelect(), new QFilter[]{qFilter1});
            if(!query.isEmpty()){
                String topRanks = query.get(0).getString("nckd_topranks");
                String topRank = query.get(0).getString(String.join(".", "nckd_perfrankmgmtentry", "nckd_toprank"));
                this.getModel().setValue(ExcellsConstant.NCKD_RANKANDTOTAL,topRank+"/"+topRanks, rowIndex);
                long appraisalResultId = query.get(0).getLong(String.join(".", "nckd_perfrankmgmtentry", "nckd_appraisalresult", FormConstant.ID_KEY));
                if(appraisalResultId > 0) {
                    DynamicObject dynamicObject = EntityHelper.newEntity("nckd_appraisalresult", appraisalResultId);
                    String appraisalResultName = query.get(0).getString(String.join(".", "nckd_perfrankmgmtentry", "nckd_appraisalresult", FormConstant.NAME_KEY));
                    dynamicObject.set(FormConstant.NAME_KEY, appraisalResultName);
                    this.getModel().setValue(ExcellsConstant.NCKD_APPRAISALRESULT, dynamicObject,rowIndex);
                }
            }
        }
    }

    private void initValue(Long personId,int rowIndex){
        //任职经历
        DynamicObject empPosOrgRel = EmpPosOrgRelHelper.queryEmpPosOrgRelByEmployees(personId);
        if(empPosOrgRel != null) {
            this.getModel().setValue(ExcellsConstant.NCKD_DEP,empPosOrgRel.getDynamicObject(FormConstant.ADMINORG),rowIndex);
            this.getModel().setValue(ExcellsConstant.NCKD_POSITION,empPosOrgRel.getDynamicObject(FormConstant.POSITION_KEY),rowIndex);
        }

        //--------------------------- 最高学历 和 本科学历 begin --------------------------
        QueryFieldBuilder perEduExpFieldBuilder = QueryFieldBuilder.create().add(FormConstant.ID_KEY);
        QFilter highEducationFilter = new QFilter(ExcellsConstant.ISFULLTIME, QCP.equals, EnableEnum.YES.getCode());
        //本科
        QFilter undergradEducationFilter = new QFilter(String.join(".",ExcellsConstant.EDUCATION_KEY,FormConstant.NUMBER_KEY), QCP.equals, "1030_S");
        QFilter educationFilter = highEducationFilter.or(undergradEducationFilter).and(FormConstant.EMPLOYEE_KEY, QCP.equals, personId);
        DynamicObjectCollection perEduExp = QueryServiceHelper.query(FormConstant.HRPI_PEREDUEXP, perEduExpFieldBuilder.buildSelect(), new QFilter[]{educationFilter});
        List<Long> eduExpIds = perEduExp.stream().map(dynamicObject -> dynamicObject.getLong(FormConstant.ID_KEY)).collect(Collectors.toList());
        MainEntityType eduExpEntityType = EntityMetadataCache.getDataEntityType(FormConstant.HRPI_PEREDUEXP);
        DynamicObject[] eduExpArray = BusinessDataServiceHelper.load(eduExpIds.toArray(new Long[0]), eduExpEntityType);
        for (DynamicObject eduExp : eduExpArray) {
            boolean isFulltime = eduExp.getBoolean(FormConstant.ISFULLTIME);
            DynamicObject education = eduExp.getDynamicObject(ExcellsConstant.EDUCATION_KEY);
            String educationNumber = education.getString(FormConstant.NUMBER_KEY);
            if("1030_S".equalsIgnoreCase(educationNumber)){
                this.getModel().setValue(ExcellsConstant.NCKD_UNIV,eduExp.getString("schoolrecord"),rowIndex);
                this.getModel().setValue(ExcellsConstant.NCKD_UNDERGRADMAJOR,eduExp.getString("major"),rowIndex);
            }
            if(isFulltime){
                this.getModel().setValue(ExcellsConstant.NCKD_PEREDUEXP,eduExp,rowIndex);
            }
        }
        //--------------------------- 最高学历 和 本科学历 end --------------------------

        //--------------------------- 优秀生类型 begin --------------------------
        QueryFieldBuilder queryFieldBuilder = QueryFieldBuilder.create().addIdNumberName(ExcellsConstant.NCKD_HONORTYPE).add(ExcellsConstant.NCKD_FTTOPGRAD);
        QFilter qFilter = new QFilter(ExcellsConstant.NCKD_HONORTYPE, QCP.is_notnull, null)
                .and(ExcellsConstant.NCKD_HONORTYPE, QCP.large_equals, 0)
                .and(FormConstant.EMPLOYEE_KEY, QCP.equals, personId);
        DynamicObjectCollection query = QueryServiceHelper.query("nckd_hrpi_topstudent", queryFieldBuilder.buildSelect(), new QFilter[]{qFilter});
        if(!query.isEmpty()) {
            List<Long> collect = query.stream().map(dynamicObject -> dynamicObject.getLong(String.join(".", ExcellsConstant.NCKD_HONORTYPE, FormConstant.ID_KEY))).collect(Collectors.toList());
            MainEntityType honorTypeEntityType = EntityMetadataCache.getDataEntityType("nckd_hbss_honortype");
            DynamicObject[] honorTypeArray = BusinessDataServiceHelper.load(collect.toArray(new Long[0]), honorTypeEntityType);
            if (honorTypeArray != null && honorTypeArray.length > 0) {
                this.getModel().setValue(ExcellsConstant.NCKD_HONORTYPE, honorTypeArray[0], rowIndex);
                this.getModel().setValue(ExcellsConstant.NCKD_FTTOPGRAD, query.get(0).getDate(ExcellsConstant.NCKD_FTTOPGRAD), rowIndex);
            }
        }
        //--------------------------- 优秀生类型 begin --------------------------
    }


    @Override
    public void afterBindingData(AfterBindingDataEvent evt) {
        BasedataEdit edit = (BasedataEdit) evt.getSource();
        String fieldKey = edit.getFieldKey();
        //修改“全日制最高学历”F7显示字段
        if ("nckd_pereduexp".equalsIgnoreCase(fieldKey)) {
            Object v = evt.getDataEntity();
            Object editSearchProp = null;
            Object displayProp = "";
            if (v == null) {
                return;
            }

            BasedataEntityType dt;
            if (((DynamicObject) v).getDataEntityType() instanceof BasedataEntityType) {
                dt = (BasedataEntityType) ((DynamicObject) v).getDataEntityType();
            } else {
                dt = (BasedataEntityType) ((BasedataProp) edit.getProperty()).getComplexType();
            }

            //获取数据包中的名称字段值
            String nameKey = dt.getNameProperty();
            IDataEntityProperty p2 = dt.findProperty(nameKey);
            if (p2 != null) {
                displayProp = p2.getValueFast(v);
                if (displayProp instanceof ILocaleString) {
                    displayProp = displayProp.toString();
                }
            }

            //动态修改基础资料的显示属性为名称(部门)
            if ("nckd_pereduexp".equals(edit.getKey())) {
                nameKey = "education";
            }
            IDataEntityProperty p4 = dt.findProperty(nameKey);
            if (p4 != null) {
                Object valueFast = p4.getValueFast(v);
                if (valueFast instanceof DynamicObject) {
                    displayProp = ConvertUtil.toDynamicObjectOrNull(valueFast).getString(FormConstant.NAME_KEY);
                    editSearchProp = ConvertUtil.toDynamicObjectOrNull(valueFast).getString(FormConstant.NUMBER_KEY);

                }
            }

            //设置显示属性
            evt.setDisplayProp(displayProp.toString());
            //设置编辑显示属性
            evt.setEditSearchProp(editSearchProp == null ? "" : editSearchProp.toString());

        }
    }

}