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

import com.google.common.collect.Maps;
import kd.bos.dataentity.entity.DynamicObject;
import kd.bos.dataentity.entity.DynamicObjectCollection;
import kd.bos.dataentity.metadata.IDataEntityProperty;
import kd.bos.dataentity.metadata.clr.DataEntityPropertyCollection;
import kd.bos.dataentity.metadata.dynamicobject.DynamicObjectType;
import kd.bos.entity.datamodel.AbstractFormDataModel;
import kd.bos.entity.datamodel.TableValueSetter;
import kd.bos.form.FieldTip;
import kd.bos.form.IFormView;
import kd.bos.form.IPageCache;
import kd.bos.mvc.cache.PageCache;
import kd.bos.orm.ORM;
import kd.bos.orm.query.QCP;
import kd.bos.orm.query.QFilter;
import kd.bos.orm.util.CollectionUtils;
import kd.hr.hbp.business.servicehelper.HRBaseServiceHelper;
import kd.hr.hbp.common.util.HRArrayUtils;
import kd.hr.hbp.common.util.HRStringUtils;
import nckd.jxccl.base.common.utils.PatternUtil;;
import nckd.jxccl.base.common.utils.QueryFieldBuilder;
import nckd.jxccl.hrmp.hbpm.common.hr.PositionBillConstant;
import nckd.jxccl.hrmp.hbpm.common.hr.PositionChangeTypeEnum;

import java.util.Arrays;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * 岗位申请单后置绑定数据服务
 * @from: kd.hr.homs.business.domain.batchbill.service.impl.AdminOrgBatchBillAfterBindDataService
 * @author: jtd
 * @date: 2025/12/27 21:48
 */
public class PositionBillAfterBindDataService extends PositionBillBaseService {
    public PositionBillAfterBindDataService(IFormView view) {
        super(view);
    }

    public void afterBindData() {
        genBillIdIfNotExist();
        deleteAllEntryData();
        updateAllChangeTypeEntry();
        deleteAddEntryIfChangeOrg();
        changeOrgFiledTip();
        getModel().setDataChanged(false);
    }

    private void changeOrgFiledTip() {
        FieldTip orgTip = new FieldTip();
        orgTip.setFieldKey(PositionBillConstant.ORG_KEY);
        orgTip.setSuccess(true);
        getView().showFieldTip(orgTip);
    }

    private void deleteAddEntryIfChangeOrg() {
        String orgCache = getView().getPageCache().get(PositionBillConstant.PC_ORGCACHE);
        Object org = getModel().getValue(PositionBillConstant.ORG_KEY);
        if (Objects.isNull(orgCache)) {
            if (Objects.nonNull(org)) {
                DynamicObject dy = (DynamicObject) org;
                getView().getPageCache().put(PositionBillConstant.PC_ORGCACHE, dy.getLong(PositionBillConstant.ID_KEY) + "");
            }
        } else if (Objects.nonNull(org)) {
            DynamicObject dy = (DynamicObject) org;
            String newId = dy.getLong(PositionBillConstant.ID_KEY) + "";
            if (!orgCache.equals(newId)) {
                long billId = getModel().getDataEntity().getLong(PositionBillConstant.ID_KEY);
                HRBaseServiceHelper positionBillEntryHelper = new HRBaseServiceHelper(PositionBillConstant.NCKD_POSITIONBILLENTRY_ENTITY);
                QFilter billIdFilter = new QFilter(PositionBillConstant.NCKD_BILLID, QCP.equals, billId);
                String selectProperties = QueryFieldBuilder.create().add(PositionBillConstant.ID_KEY)
                        .add(PositionBillConstant.NUMBER_KEY)
                        .add(PositionBillConstant.NCKD_CHANGETYPE, PositionBillConstant.NUMBER_KEY)
                        .add(PositionBillConstant.NCKD_POSITION_KEY)
                        .buildSelect();
                DynamicObject[] positionBillEntryDynArr = positionBillEntryHelper.query(selectProperties, new QFilter[]{billIdFilter});
                positionBillEntryHelper.deleteByFilter(new QFilter[]{billIdFilter});
                List<Long> addPositionIdList = Arrays.stream(positionBillEntryDynArr).filter((dyn) -> HRStringUtils.equals(dyn.getString(String.join(".", PositionBillConstant.NCKD_CHANGETYPE, PositionBillConstant.NUMBER_KEY)), PositionChangeTypeEnum.ADD.getNumber())).map((dyn) -> dyn.getLong(String.join(".", PositionBillConstant.NCKD_POSITION_KEY, PositionBillConstant.ID_KEY))).collect(Collectors.toList());
                getView().getPageCache().put(PositionBillConstant.PC_ORGCACHE, newId);
                if (addPositionIdList.size() == 0) {
                    return;
                }

                PositionBillServiceHelper.delAddMaster(addPositionIdList);
            }
        }

    }

    private void genBillIdIfNotExist() {
        long billId = getModel().getDataEntity().getLong(PositionBillConstant.ID_KEY);
        if (billId == 0L) {
            billId = ORM.create().genLongId(getView().getEntityId());
            getModel().setValue(PositionBillConstant.ID_KEY, billId);
        }
    }

    private void deleteAllEntryData() {
        IPageCache pageCache = new PageCache(getView().getPageId());
        Object importPageClose = pageCache.get(PositionBillConstant.PC_CACHE_KEY_IMPORT_START_CLOSE);
        Object entryImport = pageCache.get(PositionBillConstant.PC_CACHE_KEY_IMPORT_DATA_FLAG);
        if (!Boolean.TRUE.toString().equals(importPageClose) || Boolean.TRUE.toString().equals(entryImport)) {
            Arrays.stream(PositionChangeTypeEnum.values()).forEach((changeTypeEnum) -> getModel().deleteEntryData(changeTypeEnum.getTag(PositionBillConstant.NCKD_ENTRYENTITYUNDERLINE_KEY)));
        }
    }

    private void updateAllChangeTypeEntry() {
        IPageCache pageCache = new PageCache(getView().getPageId());
        Object importPageClose = pageCache.get(PositionBillConstant.PC_CACHE_KEY_IMPORT_START_CLOSE);
        Object entryImport = pageCache.get(PositionBillConstant.PC_CACHE_KEY_IMPORT_DATA_FLAG);
        if (Boolean.TRUE.toString().equals(importPageClose) && !Boolean.TRUE.toString().equals(entryImport)) {
            pageCache.remove(PositionBillConstant.PC_CACHE_KEY_IMPORT_START_CLOSE);
            pageCache.remove(PositionBillConstant.PC_CACHE_KEY_IMPORT_DATA_FLAG);
        } else {
            Long billId = getModel().getDataEntity().getLong(PositionBillConstant.ID_KEY);
            HRBaseServiceHelper positionBillEntryEntityHelper = new HRBaseServiceHelper(PositionBillConstant.NCKD_POSITIONBILLENTRY_ENTITY);
            QFilter billIdFilter = new QFilter(PositionBillConstant.NCKD_BILLID, QCP.equals, billId);
            DynamicObject[] batchOrgEntryEntityDynArr = positionBillEntryEntityHelper.loadDynamicObjectArray(new QFilter[]{billIdFilter});
            Arrays.sort(batchOrgEntryEntityDynArr, Comparator.comparingLong((dyn) -> dyn.getLong(PositionBillConstant.NCKD_SEQUENCE)));
            Map<String, List<DynamicObject>> changeTypeForBillDynMap = Maps.newHashMap();
            if (!HRArrayUtils.isEmpty(batchOrgEntryEntityDynArr)) {
                changeTypeForBillDynMap = Arrays.stream(batchOrgEntryEntityDynArr).collect(Collectors.groupingBy((dyn) -> dyn.getString(String.join(".", PositionBillConstant.NCKD_CHANGETYPE, PositionBillConstant.NUMBER_KEY))));
            }

            // 获取分录要转换的键值
            Map<String, String> posBillEntryTransKeyMap = PositionBillServiceHelper.getPosBillEntryTransKeyMap();
            for(Map.Entry<String, List<DynamicObject>> stringListEntry : changeTypeForBillDynMap.entrySet()) {
                String changeTypeNumber = stringListEntry.getKey();
                List<DynamicObject> entryEntityDynList = stringListEntry.getValue();
                String suffix = PositionChangeTypeEnum.getTagByNumber(changeTypeNumber);
                String entryEntity = String.join("_", PositionBillConstant.NCKD_ENTRYENTITY, suffix);
                DynamicObjectCollection dynamicObjectCollection = getModel().getDataEntity(true).getDynamicObjectCollection(entryEntity);
                DynamicObjectType dynamicObjectType = dynamicObjectCollection.getDynamicObjectType();
                DataEntityPropertyCollection properties = dynamicObjectType.getProperties();
                TableValueSetter tableValueSetter = new TableValueSetter();
                setTableValueSetterField(suffix, tableValueSetter, properties);
                setTableValueSetterValue(suffix, tableValueSetter, properties, entryEntityDynList, posBillEntryTransKeyMap);
                batchCreateNewEntryRow(tableValueSetter, entryEntity);
            }

        }
    }

    private void setTableValueSetterField(String suffix, TableValueSetter tableValueSetter, DataEntityPropertyCollection properties) {
        if (!HRStringUtils.isEmpty(suffix)) {
            for(IDataEntityProperty property : properties) {
                String propName = property.getName();
                if (PatternUtil.isExProperty(propName) && propName.endsWith("_"+suffix)) {
                    tableValueSetter.addField(propName);
                }
            }
            tableValueSetter.addField(PositionBillConstant.ID_KEY);
        }
    }

    private void setTableValueSetterValue(String suffix, TableValueSetter tableValueSetter, DataEntityPropertyCollection properties, List<DynamicObject> entryEntityDynList, Map<String, String> posBillEntryTransKeyMap) {
        if (!HRStringUtils.isEmpty(suffix)) {
            for(int i = 0; i < entryEntityDynList.size(); ++i) {
                for(IDataEntityProperty property : properties) {
                    String propName = property.getName();
                    if (PatternUtil.isExProperty(propName) && propName.endsWith("_"+suffix)) {
                        String propNameSub = PositionBillServiceHelper.getNoLineSuffixProp(propName, "_"+suffix);
                        tableValueSetter.set(propName, getValue(entryEntityDynList.get(i).get(posBillEntryTransKeyMap.getOrDefault(propNameSub, propNameSub))), i);
                    }
                }
                tableValueSetter.set(PositionBillConstant.ID_KEY, entryEntityDynList.get(i).get(PositionBillConstant.ID_KEY), i);

                if (PositionBillConstant.ADD_TAG.equals(suffix)) {
                    tableValueSetter.set(String.join("_", PositionBillConstant.NCKD_POSITION_KEY, suffix), entryEntityDynList.get(i).getLong(String.join(".", PositionBillConstant.NCKD_POSITION_KEY, PositionBillConstant.ID_KEY)), i);
                }

            }

        }
    }

    private Object getValue(Object object) {
        return object instanceof DynamicObject ? ((DynamicObject) object).get(PositionBillConstant.ID_KEY) : object;
    }

    private void batchCreateNewEntryRow(TableValueSetter tableValueSetter, String entryEntity) {
        if (!CollectionUtils.isEmpty(tableValueSetter.getFields())) {
            AbstractFormDataModel model = (AbstractFormDataModel) getModel();
            model.beginInit();
            model.batchCreateNewEntryRow(entryEntity, tableValueSetter);
            model.endInit();
            getView().updateView(entryEntity);
        }
    }

}
