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

import kd.bos.bill.OperationStatus;
import kd.bos.common.enums.EnableEnum;
import kd.bos.dataentity.entity.DynamicObject;
import kd.bos.dataentity.entity.DynamicObjectCollection;
import kd.bos.entity.QueryEntityType;
import kd.bos.entity.constant.StatusEnum;
import kd.bos.entity.datamodel.events.ChangeData;
import kd.bos.entity.datamodel.events.PropertyChangedArgs;
import kd.bos.form.events.AfterDoOperationEventArgs;
import kd.bos.form.field.DateEdit;
import kd.bos.form.operate.FormOperate;
import kd.bos.form.plugin.AbstractFormPlugin;
import kd.bos.mvc.base.BaseModel;
import kd.bos.orm.query.QCP;
import kd.bos.orm.query.QFilter;
import kd.bos.servicehelper.MetadataServiceHelper;
import kd.hr.hbp.business.servicehelper.HRBaseServiceHelper;
import kd.hr.hbp.business.servicehelper.HRQueryEntityHelper;
import kd.hr.hbp.common.constants.history.HisModelDataStatusEnum;
import kd.hr.hbp.common.util.HRDateTimeUtils;
import kd.hr.hbp.common.util.HRObjectUtils;
import kd.hr.hbp.common.util.HRStringUtils;
import nckd.jxccl.base.common.utils.QueryFieldBuilder;
import nckd.jxccl.base.orm.helper.QFilterCommonHelper;
import nckd.jxccl.hr.sdm.business.SdmBusinessService;
import nckd.jxccl.hr.sdm.common.SanDingConstant;
import nckd.jxccl.hr.sdm.common.SanDingPlanEntryStatus;

import java.util.Arrays;
import java.util.Date;
import java.util.EventObject;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * 三定计划表单插件
 * @entity: nckd_sandingplan
 * @author: jtd
 * @date: 2025/12/2 18:28
 */
public class SanDingPlanFormPlugin extends AbstractFormPlugin {
    /** 获取公司负责人查询标识 */
    private static final String NCKD_SDM_GETCOMPANYMANAGERQUERY_ENTITY = "nckd_sdm_getcompanymanagerquery";

    @Override
    public void afterCreateNewData(EventObject e) {
        super.afterCreateNewData(e);

        DynamicObject dyo = ((BaseModel) e.getSource()).getDataEntity();
        // 初始化单头数据
        initBillData(dyo.getDate(SanDingConstant.NCKD_SANDINGYEAR_KEY));
        // 初始化单据体数据
        initEntryData();
    }

    private void initBillData(Date sanDingYear) {
        if (HRObjectUtils.isEmpty(sanDingYear)) {
            return;
        }
        // 获取年
        int year = HRDateTimeUtils.getYear(sanDingYear);
        // 查询 适用生效日期、适用批次人力资源需求批次.编码
        String selectProperties = QueryFieldBuilder.create()
                .add(SanDingConstant.NCKD_STARTDATE_KEY)
                .add(SanDingConstant.NCKD_SANDINGTIME_KEY, SanDingConstant.NUMBER_KEY)
                .buildSelect();
        QFilter qFilter = new QFilter(SanDingConstant.NCKD_SANDINGYEAR_TEXT_KEY, QCP.equals, String.valueOf(year))
                .and(SanDingConstant.NCKD_ISCOMPLATED_KEY, QCP.equals, EnableEnum.YES.getCode());
        String orderBys = QueryFieldBuilder.create().addDesc(SanDingConstant.NCKD_SANDINGTIME_KEY).buildOrder();
        // 判断 是否存在三定计划数据
        DynamicObject[] sanDingPlanDyos = HRBaseServiceHelper.create(SanDingConstant.NCKD_SANDINGPLAN_ENTITY).load(selectProperties, new QFilter[]{qFilter}, orderBys);
        HRBaseServiceHelper sanDingTimeServiceHelper = HRBaseServiceHelper.create(SanDingConstant.NCKD_SANDINGTIME_ENTITY);
        if (sanDingPlanDyos == null || sanDingPlanDyos.length == 0) {
            // 设置 适用批次人力资源需求批次
            DynamicObject sanDingTimeDyo = sanDingTimeServiceHelper.loadDynamicObject(new QFilter(SanDingConstant.NUMBER_KEY, QCP.equals, "1"));
            if (!HRObjectUtils.isEmpty(sanDingTimeDyo)) {
                getModel().setValue(SanDingConstant.NCKD_SANDINGTIME_KEY, sanDingTimeDyo);
            }
            // 设置 上一批次适用生效日期
            getModel().setValue(SanDingConstant.NCKD_STARTDATE_LAST_KEY, null);
        } else {
            // 获取 年度最后一个批次的计划数据
            DynamicObject sanDingPlanDyo = sanDingPlanDyos[0];
            // 获取 批次编码
            int sanDingTimeNumber = sanDingPlanDyo.getInt(String.join(".", SanDingConstant.NCKD_SANDINGTIME_KEY, SanDingConstant.NUMBER_KEY));
            String nextSanDingTimeNumber = String.valueOf(sanDingTimeNumber + 1);
            // 获取 下一个批次的对象
            DynamicObject sanDingTimeDyo = sanDingTimeServiceHelper.loadDynamicObject(new QFilter(SanDingConstant.NUMBER_KEY, QCP.equals, nextSanDingTimeNumber));
            // 如果存在值，则设置适用批次人力资源需求批次
            if (!HRObjectUtils.isEmpty(sanDingPlanDyo)) {
                getModel().setValue(SanDingConstant.NCKD_SANDINGTIME_KEY, sanDingTimeDyo);
            } else {
                getView().showTipNotification(HRStringUtils.format("请先维护编码[{}]的三定批次基础数据", nextSanDingTimeNumber));
            }
            // 设置 上一批次适用生效日期
            getModel().setValue(SanDingConstant.NCKD_STARTDATE_LAST_KEY, sanDingPlanDyo.getDate(SanDingConstant.NCKD_STARTDATE_KEY));
        }
    }

    private void initEntryData() {
        // 单位Key
        String companyIdKey = String.join(".", SanDingConstant.NCKD_COMPANY_KEY, SanDingConstant.ID_KEY);
        // 负责人Key
        String managerIdKey = String.join(".", SanDingConstant.NCKD_MANAGER_KEY, SanDingConstant.ID_KEY);
        // 查询公司负责人
        String selectFields = QueryFieldBuilder.create()
                .add(SanDingConstant.NCKD_COMPANYMANAGE_NCKD_MANAGER_ID)
                .add(SanDingConstant.NCKD_COMPANYMANAGE_NCKD_MANAGER_EMPNUMBER)
                .buildSelect();
        // 排序 物理层级、排序号
        String orderBys = QueryFieldBuilder.create()
                .addAsc(SanDingConstant.LEVEL_KEY)
                .addAsc(SanDingConstant.INDEX_KEY)
                .buildOrder();
        //DynamicObject[] companyManagerDyos = HRBaseServiceHelper.create(SanDingConstant.NCKD_COMPANYMANAGER_ENTITY).queryOriginalArray(selectFields, null, orderBys);
        QFilter qFilter = new QFilter(String.join(".", SanDingConstant.PARENTORG_KEY, SanDingConstant.NUMBER_KEY), QCP.equals, "01")
                .and(SanDingConstant.ENABLE, QCP.equals, EnableEnum.YES.getCode())
                .and(SanDingConstant.STATUS, QCP.equals, StatusEnum.C.toString())
                .and(SanDingConstant.DATA_STATUS, QCP.equals, HisModelDataStatusEnum.EFFECTING.getStatus())
                .and(SanDingConstant.ADMINORGTYPE_KEY, QCP.equals, 1020L)
                .and(SanDingConstant.OTCLASSIFY_KEY, QCP.equals, 1010L)
                .and(SanDingConstant.ISVIRTUALORG_KEY, QCP.equals, EnableEnum.NO.getCode())
                .and(SanDingConstant.IS_CURRENT_VERSION, QCP.equals, EnableEnum.YES.getCode());
        DynamicObjectCollection companyManagerDyos = HRQueryEntityHelper.getInstance().getQueryDyoColl((QueryEntityType) MetadataServiceHelper.getDataEntityType(NCKD_SDM_GETCOMPANYMANAGERQUERY_ENTITY), selectFields, new QFilter[]{qFilter}, orderBys);
        // 处理数据
        Set<Long> companyIds = new HashSet<Long>();
        Set<Long> managerIds = new HashSet<Long>();
        for (DynamicObject companyManagerDyo : companyManagerDyos) {
            Long companyId = companyManagerDyo.getLong(SanDingConstant.ID_KEY);
            Long managerId = (Long) companyManagerDyo.get(SanDingConstant.NCKD_COMPANYMANAGE_NCKD_MANAGER_ID);
            companyIds.add(companyId);
            if (managerId != null) {
                managerIds.add(managerId);
            }
        }
        // 获取单位数据
        DynamicObject[] companyDyos = HRBaseServiceHelper.create(SanDingConstant.ADMINORG_ENTITYID).load(new QFilter[]{QFilterCommonHelper.getIdInFilter(companyIds)});
        Map<Long, DynamicObject> companyMap = Arrays.stream(companyDyos).collect(Collectors.toMap(companyDyo -> companyDyo.getLong(SanDingConstant.ID_KEY), Function.identity(), (oldValue, newValue) -> newValue));
        // 获取负责任人数据
        DynamicObject[] managerDyos = HRBaseServiceHelper.create(SanDingConstant.HRPI_EMPLOYEE).load(new QFilter[]{QFilterCommonHelper.getIdInFilter(managerIds)});
        Map<Long, DynamicObject> managerMap = Arrays.stream(managerDyos).collect(Collectors.toMap(managerDyo -> managerDyo.getLong(SanDingConstant.ID_KEY), Function.identity(), (oldValue, newValue) -> newValue));
        // 清空单据体数据
        DynamicObjectCollection entryEntityColl = getModel().getEntryEntity(SanDingConstant.NCKD_ENTRYENTITY);
        entryEntityColl.clear();
        // 写入单据体
        for (DynamicObject companyManagerDyo : companyManagerDyos) {
            DynamicObject entryDyo = entryEntityColl.addNew();
            // 设置 单位
            entryDyo.set(SanDingConstant.NCKD_COMPANY_KEY, companyMap.get(companyManagerDyo.getLong(SanDingConstant.ID_KEY)));
            // 设置 负责人
            entryDyo.set(SanDingConstant.NCKD_MANAGER_KEY, managerMap.getOrDefault((Long) companyManagerDyo.get(SanDingConstant.NCKD_COMPANYMANAGE_NCKD_MANAGER_ID), null));
            // 设置 状态
            entryDyo.set(SanDingConstant.NCKD_STATUS_KEY, SanDingPlanEntryStatus.UNSEND.getCode());// 默认未发起
        }
        // 更新单据体数据缓存和界面
        getModel().updateEntryCache(entryEntityColl);
        getView().updateView(SanDingConstant.NCKD_ENTRYENTITY);
    }

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

        OperationStatus status = getView().getFormShowParameter().getStatus();
        if (status == OperationStatus.ADDNEW || status == OperationStatus.EDIT) {
            DynamicObject dyo = getModel().getDataEntity();
            // 设置 适用生效日期最小值
            Date startDateLast = dyo.getDate(SanDingConstant.NCKD_STARTDATE_LAST_KEY);
            setStartDateMinDate(startDateLast);
        }
        DynamicObject dyo = getModel().getDataEntity();
        // 获取 ID
        DynamicObject dataEntity = getModel().getDataEntity();
        Long id = (Long) dataEntity.get(SanDingConstant.ID_KEY);
        // 获取 最近一条三定计划数据
        DynamicObject lastSanDingPlanDyo = SdmBusinessService.getLastSanDingPlanDyo(id == null ? 0L : id);
        if (!HRObjectUtils.isEmpty(lastSanDingPlanDyo)) {
            // 设置 年度最小值
            Date sanDingYear = lastSanDingPlanDyo.getDate(SanDingConstant.NCKD_SANDINGYEAR_KEY);
            DateEdit sanDingYearControl = getControl(SanDingConstant.NCKD_SANDINGYEAR_KEY);
            sanDingYearControl.setMinDate(HRDateTimeUtils.addYear(sanDingYear, -1));
        }
    }

    private void setStartDateMinDate(Date startDateLast) {
        DateEdit startDateControl = getControl(SanDingConstant.NCKD_STARTDATE_KEY);
        if (!HRObjectUtils.isEmpty(startDateLast)) {
            startDateControl.setMinDate(HRDateTimeUtils.addDay(startDateLast, 1));
        } else {
            // 无法清除最小值，只能设置一个最小值
            startDateControl.setMinDate(new Date(0));
        }
    }

    @Override
    public void propertyChanged(PropertyChangedArgs e) {
        super.propertyChanged(e);

        String fieldKey = e.getProperty().getName();
        if (SanDingConstant.NCKD_SANDINGYEAR_KEY.equals(fieldKey)) {
            ChangeData[] changeSet = e.getChangeSet();
            Date sanDingYear = (Date) changeSet[0].getNewValue();
            initBillData(sanDingYear);
            // 清空 适用生效日期
            getModel().setValue(SanDingConstant.NCKD_STARTDATE_KEY, null);
            // 设置 适用生效日期最小值
            setStartDateMinDate((Date) getModel().getValue(SanDingConstant.NCKD_STARTDATE_LAST_KEY));
        }
    }

    @Override
    public void afterDoOperation(AfterDoOperationEventArgs afterDoOperationEventArgs) {
        super.afterDoOperation(afterDoOperationEventArgs);

        if (afterDoOperationEventArgs.getOperationResult() != null && afterDoOperationEventArgs.getOperationResult().isSuccess()) {
            FormOperate operate = (FormOperate) afterDoOperationEventArgs.getSource();
            String operateKey = operate.getOperateKey();
            if (HRStringUtils.equalsAny(operateKey, SanDingConstant.SAVE_OP, SanDingConstant.SENDTASK_OP)) {
                // 设置页面状态为查看
                getView().setStatus(OperationStatus.VIEW);
                // 刷新
                getView().updateView();
            }
        }
    }
}
