package nckd.jxccl.opmc.pm.plugin.form.cycle;

import kd.bos.entity.datamodel.events.PropertyChangedArgs;
import kd.bos.form.control.EntryGrid;
import kd.bos.form.field.DateEdit;
import kd.bos.form.field.FieldEdit;
import kd.bos.form.plugin.AbstractFormPlugin;
import kd.bos.logging.Log;
import kd.bos.logging.LogFactory;
import kd.sdk.plugin.Plugin;
import nckd.jxccl.base.common.utils.ConvertUtil;
import nckd.jxccl.base.common.utils.DateUtil;
import nckd.jxccl.opmc.pm.common.PerfManagerFormConstant;

import java.util.Date;
import java.util.EventObject;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

/**
* 考核周期表单插件
* 实体标识：nckd_perfmanager
* @author W.Y.C
* @date 2025/11/4 12:30
* @version 1.0
*/
public class PerfManagerFormPlugin extends AbstractFormPlugin implements Plugin {

    private final static Log logger = LogFactory.getLog(PerfManagerFormPlugin.class);


    public PerfManagerFormPlugin() {
        super();
    }

    @Override
    public void afterBindData(EventObject e) {
        setEntryYear();
        // this.getModel().setValue(FormConstant.STATUS, StatusEnum.A.toString());
    }


    @Override
    public void propertyChanged(PropertyChangedArgs e) {
        super.propertyChanged(e);
        String fieldKey = e.getProperty().getName();
        if(PerfManagerFormConstant.NCKD_ENDYEAR.equalsIgnoreCase(fieldKey)){
            setEntryYear();
        }
    }



    /*@Override
    public void beforeDoOperation(BeforeDoOperationEventArgs e) {
        String operateKey = ((FormOperate) e.getSource()).getOperateKey();
        DynamicObject dataEntity = this.getModel().getDataEntity();
        DynamicObjectCollection entrys = dataEntity.getDynamicObjectCollection(PerfManagerFormConstant.NCKD_PERFMANAGERENTRY);
        List<Date> dateList = entrys.stream().map(entry -> entry.getDate(PerfManagerFormConstant.NCKD_APPRAISALYEAR)).collect(Collectors.toList());
        if(FormConstant.SAVE_OP.equals(operateKey)){
            if(CollectionUtils.isNotEmpty(dateList) && !dateList.stream().allMatch(Objects::isNull)) {
                Date beginYear = dataEntity.getDate(PerfManagerFormConstant.NCKD_BEGINYEAR);
                Date endYear = dataEntity.getDate(PerfManagerFormConstant.NCKD_ENDYEAR);
                if(beginYear != null && endYear != null){
                    //校验考核年份是否在周期内
                    boolean hasOutOfRangeEntry = entrys != null ? entrys.stream()
                            .map(entry -> entry.getDate(PerfManagerFormConstant.NCKD_APPRAISALYEAR))
                            .filter(Objects::nonNull)
                            .anyMatch(date -> !DateUtil.isInRange(DateUtil.toLocalDateTime(date), DateUtil.toLocalDateTime(beginYear), DateUtil.toLocalDateTime(endYear))) : false;
                    if(hasOutOfRangeEntry){
                        e.setCancel(true);
                        this.getView().showErrorNotification("考核年份不在周期范围内，请检查！");
                        return;
                    }
                }

                //校验考核年份是否重复
                if(hasDuplicateYear(dateList)){
                    e.setCancel(true);
                    this.getView().showErrorNotification("考核结果存在重复的考核年份，请检查！");
                    return;
                }

                //判断人员是否有重叠的考核周期
                DynamicObject person = (DynamicObject) this.getModel().getValue(PerfManagerFormConstant.NCKD_PERSON);
                QFilter finalFilter = new QFilter(PerfManagerFormConstant.NCKD_PERSON, QCP.equals, person.getLong(PerfManagerFormConstant.ID_KEY));
                Object id = this.getModel().getValue(PerfManagerFormConstant.ID_KEY);
                if (id != null) {
                    QFilter filter = new QFilter(PerfManagerFormConstant.ID_KEY, QCP.not_equals, id);
                    finalFilter.and(filter);
                }
                QFilter filter = new QFilter(PerfManagerFormConstant.NCKD_PERFMANAGERENTRY + "." + PerfManagerFormConstant.NCKD_APPRAISALYEAR, QCP.in, dateList);
                finalFilter.and(filter);
                DynamicObjectCollection query = QueryServiceHelper.query(PerfManagerFormConstant.PERFMANAGER_ENTITYID, PerfManagerFormConstant.NCKD_PERFMANAGERENTRY + "." + PerfManagerFormConstant.NCKD_APPRAISALYEAR, new QFilter[]{finalFilter}, null);
                if(!query.isEmpty()){
                    List<String> yearList = query.stream()
                            .map(dynamicObject -> {
                                Date date = dynamicObject.getDate(PerfManagerFormConstant.NCKD_PERFMANAGERENTRY + "." + PerfManagerFormConstant.NCKD_APPRAISALYEAR);
                                return DateUtil.format(date, "yyyy");
                            })
                            .collect(Collectors.toList());
                    String yearJoin = String.join("、", yearList);
                    e.setCancel(true);
                    this.getView().showErrorNotification(StrFormatter.format("人员【{}】已存在【{}】年的考核结果，不能重复添加", person.getString(PerfManagerFormConstant.NAME_KEY), yearJoin));
                }
            }
        }

    }*/

    /**
     * 设置分录考核年份只能在周期开始和结束范围内
     * @author W.Y.C
     * @date 2025/6/10 18:15
     * @version 1.0
     */
    private void setEntryYear() {
        EntryGrid entryGrid = this.getControl(PerfManagerFormConstant.NCKD_PERFMANAGERENTRY);
        List<FieldEdit> fieldEdits = entryGrid.getFieldEdits();
        for (FieldEdit fieldEdit : fieldEdits) {
            //选择周期结束年份后设置分录考核年份只能在周期开始和结束范围内
            if(PerfManagerFormConstant.NCKD_APPRAISALYEAR.equalsIgnoreCase(fieldEdit.getProperty().getName())) {
                DateEdit appraisalYearEdit = (DateEdit) fieldEdit;
                Date beginYear = ConvertUtil.toDate(this.getModel().getValue(PerfManagerFormConstant.NCKD_BEGINYEAR));
                Date endYear = ConvertUtil.toDate(this.getModel().getValue(PerfManagerFormConstant.NCKD_ENDYEAR));
                appraisalYearEdit.setMinDate(beginYear);
                appraisalYearEdit.setMaxDate(endYear);
            }
        }
    }

    /**
     * 判断日期列表中是否有重复的年份
     *
     * @param dateList 日期列表
     * @return true 表示有重复的年份，false 表示无重复
     */
    public static boolean hasDuplicateYear(List<Date> dateList) {
        if (dateList == null || dateList.isEmpty()) {
            return false;
        }
        Set<Integer> yearSet = new HashSet<>();
        for (Date date : dateList) {
            int year = DateUtil.getYear(DateUtil.toLocalDateTime(date));
            if (yearSet.contains(year)) {
                return true;
            }
            yearSet.add(year);
        }
        return false;
    }



}