package nckd.jxccl.hrmp.hbpm.business.hr.service.impl;

import com.google.common.collect.Lists;
import kd.bos.dataentity.entity.DynamicObject;
import kd.bos.dataentity.entity.DynamicObjectCollection;
import kd.bos.dataentity.metadata.IDataEntityProperty;
import kd.bos.dataentity.metadata.IMetadata;
import kd.bos.dataentity.metadata.clr.DataEntityPropertyCollection;
import kd.bos.entity.EntityMetadataCache;
import kd.bos.entity.MainEntityType;
import kd.bos.entity.datamodel.AbstractFormDataModel;
import kd.bos.entity.datamodel.TableValueSetter;
import kd.bos.form.IFormView;
import kd.bos.form.events.ClosedCallBackEvent;
import kd.bos.orm.query.QCP;
import kd.bos.orm.query.QFilter;
import kd.hr.hbp.business.servicehelper.HRBaseServiceHelper;
import kd.hr.hbp.common.util.HRDyObjectPropUtil;
import nckd.jxccl.base.common.utils.PatternUtil;;
import nckd.jxccl.hrmp.hbpm.common.hr.PositionBillConstant;
import nckd.jxccl.hrmp.hbpm.common.hr.PositionChangeTypeEnum;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.Set;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * 岗位申请单关闭回调服务类
 * @from: kd.hr.homs.business.domain.batchbill.service.impl.AdminOrgBatchBillClosedCallBackService
 * @author: jtd
 * @date: 2025/12/20 17:29
 */
public class PositionBillClosedCallBackService extends PositionBillBaseService {

    public PositionBillClosedCallBackService(IFormView view) {
        super(view);
    }

    public void closedCallBack(ClosedCallBackEvent closedCallBackEvent) {
        switch (closedCallBackEvent.getActionId()) {
            case PositionBillConstant.NCKD_ENTRYENTITY_ADD_KEY:
                if (onlyForView(closedCallBackEvent)) {
                    return;
                }
                updateAddEntryEntity();

                if (getView().getPageCache().get(PositionBillConstant.PC_LASTTIMEADDENTRYID) != null) {
                    getView().invokeOperation(PositionBillConstant.NEWENTRY_ADD_OP);
                }
                break;
            case  PositionBillConstant.NCKD_ENTRYENTITY_CHANGE_KEY:
                saveReturn(closedCallBackEvent.getReturnData(), PositionBillConstant.NCKD_ENTRYENTITY_CHANGE_KEY);
        }
    }

    private boolean onlyForView(ClosedCallBackEvent closedCallBackEvent) {
        return closedCallBackEvent.getReturnData() == null;
    }

    private void updateAddEntryEntity() {
        DataEntityPropertyCollection entryEntityInfo = getModel().getDataEntity(true).getDynamicObjectCollection(PositionBillConstant.NCKD_ENTRYENTITY_ADD_KEY).getDynamicObjectType().getProperties();
        MainEntityType entityType = EntityMetadataCache.getDataEntityType(PositionBillConstant.NCKD_POSBILLENTRYADD_ENTITY);
        DataEntityPropertyCollection addEntityInfo = entityType.getProperties();
        Map<String, IDataEntityProperty> addNamePropMap = addEntityInfo.stream().collect(Collectors.toMap(IMetadata::getName, Function.identity()));
        List<String> selectPropList = new ArrayList<String>();
        Set<String> toSetValueEntryPropList = new HashSet<String>();

        String lineSuffix = "_"+PositionBillConstant.ADD_TAG;
        // 获取分录要转换的键值，将单据分录字段转换转成分录页面字段
        Map<String, String> posBillEntryTransKeyMap = PositionBillServiceHelper.getPosBillEntryTransKeyMap();
        for(IDataEntityProperty iDataEntityProperty : entryEntityInfo) {
            String entryPropName = iDataEntityProperty.getName();
            if (entryPropName.endsWith(lineSuffix)) {
                String entryPropNameSub = PositionBillServiceHelper.getNoLineSuffixProp(entryPropName, lineSuffix);
                if (posBillEntryTransKeyMap.containsKey(entryPropNameSub)) {
                    selectPropList.add(posBillEntryTransKeyMap.get(entryPropNameSub));
                    toSetValueEntryPropList.add(entryPropName);
                } else if (addNamePropMap.containsKey(entryPropNameSub)) {
                    selectPropList.add(entryPropNameSub);
                    toSetValueEntryPropList.add(entryPropName);
                }
            }
        }

        toSetValueEntryPropList.add(PositionBillConstant.ID_KEY);
        HRBaseServiceHelper posBillEntryAddServiceHelper = new HRBaseServiceHelper(PositionBillConstant.NCKD_POSBILLENTRYADD_ENTITY);
        Long billId = getModel().getDataEntity().getLong(PositionBillConstant.ID_KEY);
        QFilter qFilter = (new QFilter(PositionBillConstant.NCKD_BILLID, QCP.equals, billId)).and(new QFilter(String.join(".", PositionBillConstant.NCKD_CHANGETYPE, PositionBillConstant.NUMBER_KEY), QCP.equals, PositionChangeTypeEnum.ADD.getNumber()));
        DynamicObject[] addPositionDyArr = posBillEntryAddServiceHelper.load(String.join(",", selectPropList), qFilter.toArray(), PositionBillConstant.NCKD_SEQUENCE);

        getModel().deleteEntryData(PositionBillConstant.NCKD_ENTRYENTITY_ADD_KEY);
        TableValueSetter vs = new TableValueSetter();
        toSetValueEntryPropList.forEach((prop) -> vs.addField(prop, new Object[0]));

        for(DynamicObject addPositionDy : addPositionDyArr) {
            List<Object> values = Lists.newArrayListWithCapacity(addPositionDyArr.length);

            for(String entryPropName : toSetValueEntryPropList) {
                if (entryPropName.equals(PositionBillConstant.ID_KEY)) {
                    values.add(addPositionDy.getLong(PositionBillConstant.ID_KEY));
                } else {
                    String propName = PositionBillServiceHelper.getNoLineSuffixProp(entryPropName, lineSuffix);
                    propName = posBillEntryTransKeyMap.getOrDefault(propName, propName);
                    if (addPositionDy.get(propName) instanceof DynamicObject) {
                        values.add(HRDyObjectPropUtil.getIdLongObject(addPositionDy.getDynamicObject(propName)));
                    } else {
                        values.add(addPositionDy.get(propName));
                    }
                }
            }

            vs.addRow(values.toArray());
        }

        AbstractFormDataModel model = (AbstractFormDataModel) getModel();
        model.beginInit();
        model.batchCreateNewEntryRow(PositionBillConstant.NCKD_ENTRYENTITY_ADD_KEY, vs);
        model.endInit();
        getView().updateView(PositionBillConstant.NCKD_ENTRYENTITY_ADD_KEY);
    }

    private void saveReturn(Object data, String entryEntityInfo) {
        if (data instanceof Map) {
            Map<String, Object> map = (Map) data;
            DynamicObjectCollection info = getModel().getDataEntity(true).getDynamicObjectCollection(entryEntityInfo);
            DataEntityPropertyCollection properties = info.getDynamicObjectType().getProperties();
            Optional<DynamicObject> changeEntry = info.stream().filter((entry) -> entry.getLong(PositionBillConstant.ID_KEY) == (Long) map.get(PositionBillConstant.ID_KEY)).findFirst();
            if (changeEntry.isPresent()) {
                DynamicObject dynamicObject = changeEntry.get();
                DataEntityPropertyCollection propers = dynamicObject.getDataEntityType().getProperties();
                map.keySet().forEach((item) -> {
                    if (propers.containsKey(item)) {
                        dynamicObject.set(item, map.get(item));
                    }

                });
                getView().updateView(entryEntityInfo);
            } else {
                String lineSuffix = entryEntityInfo.substring(entryEntityInfo.lastIndexOf("_"));
                TableValueSetter vs = new TableValueSetter();
                List<String> propList = new ArrayList();

                for(IDataEntityProperty property : properties) {
                    String propName = property.getName();
                    if (PatternUtil.isExProperty(propName) && propName.endsWith(lineSuffix)) {
                        vs.addField(property.getName());
                        propList.add(property.getName());
                    }
                }

                vs.addField(PositionBillConstant.ID_KEY);
                propList.add(PositionBillConstant.ID_KEY);
                List<Object> values = Lists.newArrayListWithCapacity(16);

                for(String prop : propList) {
                    Object obj = map.get(prop);
                    // 原上级岗位特殊处理
                    if (PositionBillConstant.NCKD_ORIPARENT_KEY.equals(prop)) {
                        values.add(getLongId(map.get(PositionBillConstant.NCKD_PARENT)));
                        continue;
                    }

                    if (obj instanceof DynamicObject) {
                        values.add(getLongId(obj));
                    } else {
                        values.add(obj);
                    }
                }

                vs.addRow(values.toArray());
                AbstractFormDataModel model = (AbstractFormDataModel) getModel();
                model.beginInit();
                model.batchCreateNewEntryRow(PositionBillConstant.NCKD_ENTRYENTITY_CHANGE_KEY, vs);
                model.endInit();
                getView().updateView(PositionBillConstant.NCKD_ENTRYENTITY_CHANGE_KEY);
            }
        }

    }

    private Object getLongId(Object mapValue) {
        if (Objects.isNull(mapValue)) {
            return null;
        } else {
            return mapValue instanceof DynamicObject ? ((DynamicObject) mapValue).getLong(PositionBillConstant.ID_KEY) : mapValue;
        }
    }

}
