package nckd.jxccl.hrmp.hbpm.plugin.operate.hr;

import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
import kd.bos.dataentity.entity.DynamicObject;
import kd.bos.db.tx.TXHandle;
import kd.bos.entity.plugin.AbstractOperationServicePlugIn;
import kd.bos.entity.plugin.AddValidatorsEventArgs;
import kd.bos.entity.plugin.PreparePropertysEventArgs;
import kd.bos.entity.plugin.args.BeginOperationTransactionArgs;
import kd.bos.entity.plugin.args.EndOperationTransactionArgs;
import kd.bos.logging.Log;
import kd.bos.logging.LogFactory;
import kd.bos.orm.query.QCP;
import kd.bos.orm.query.QFilter;
import kd.hr.hbp.business.servicehelper.HRBaseServiceHelper;
import nckd.jxccl.hrmp.hbpm.business.hr.service.impl.PositionBillEffectService;
import nckd.jxccl.hrmp.hbpm.common.hr.PositionBillConstant;
import nckd.jxccl.hrmp.hbpm.common.hr.PositionChangeTypeEnum;

import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * 岗位申请单生效操作插件
 * @from: kd.hr.homs.opplugin.web.orgbatch.OrgBatchChgBillEffectOp
 * @operate: audit
 * @author: jtd
 * @date: 2026/1/10 15:39
 */
public class PositionBillEffectOpPlugin extends AbstractOperationServicePlugIn {
    private static final Log log = LogFactory.getLog(PositionBillEffectOpPlugin.class);

    @Override
    public void onPreparePropertys(PreparePropertysEventArgs e) {
        super.onPreparePropertys(e);

        e.getFieldKeys().addAll(billEntityType.getAllFields().keySet());
    }

    @Override
    public void onAddValidators(AddValidatorsEventArgs e) {
        super.onAddValidators(e);
    }

    @Override
    public void beginOperationTransaction(BeginOperationTransactionArgs e) {
        super.beginOperationTransaction(e);

        log.info("PositionBillEffectOpPlugin.beginOperationTransaction start.");
        String operationKey = e.getOperationKey();
        DynamicObject[] bills = e.getDataEntities();
        if (PositionBillConstant.AUDIT_OP.equals(operationKey) || PositionBillConstant.SUBMITEFFECT_OP.equals(operationKey)) {
            PositionBillEffectService positionBillEffectService = new PositionBillEffectService();
            positionBillEffectService.billEffect(bills);
        }
    }

    @Override
    public void endOperationTransaction(EndOperationTransactionArgs e) {
        super.endOperationTransaction(e);

        DynamicObject[] bills = e.getDataEntities();
        Set<Long> billIds = Sets.newHashSetWithExpectedSize(bills.length);

        for(DynamicObject bill : bills) {
            billIds.add(bill.getLong(PositionBillConstant.ID_KEY));
        }

        HRBaseServiceHelper positionBillEntryEntityHelper = new HRBaseServiceHelper(PositionBillConstant.NCKD_POSITIONBILLENTRY_ENTITY);
        QFilter positionIdFilter = new QFilter(PositionBillConstant.CREATOR_KEY, QCP.equals, 0);
        QFilter billIdFilter = new QFilter(PositionBillConstant.NCKD_BILLID, QCP.in, billIds);
        positionIdFilter.and(billIdFilter);
        positionBillEntryEntityHelper.deleteByFilter(positionIdFilter.toArray());
        QFilter filter = new QFilter(PositionBillConstant.NCKD_BILLID, QCP.in, billIds);
        DynamicObject[] entries = positionBillEntryEntityHelper.loadDynamicObjectArray(new QFilter[]{filter});
        Map<String, List<DynamicObject>> changeTypeGroupMap = Arrays.stream(entries).collect(Collectors.groupingBy((dy) -> dy.getString(String.join(".", PositionBillConstant.NCKD_CHANGETYPE, PositionBillConstant.NUMBER_KEY))));
        List<DynamicObject> positionDyList = changeTypeGroupMap.get(PositionChangeTypeEnum.ADD.getNumber());
        if (positionDyList != null && !positionDyList.isEmpty()) {
            Map<Long, Long> positionBoIdToVidMap = Maps.newHashMapWithExpectedSize(positionDyList.size());

            for(DynamicObject positionDy : positionDyList) {
                DynamicObject positionBoDy = positionDy.getDynamicObject(PositionBillConstant.NCKD_POSITION_KEY);
                positionBoIdToVidMap.put(positionBoDy.getLong(PositionBillConstant.ID_KEY), positionBoDy.getLong(PositionBillConstant.SOURCEVID_KEY));
            }

            List<DynamicObject> updateEntryValue = Lists.newArrayListWithExpectedSize(10);

            for(Map.Entry<String, List<DynamicObject>> entry : changeTypeGroupMap.entrySet()) {
                for(DynamicObject entryValue : entry.getValue()) {
                    boolean change = false;
                    long parentId = entryValue.getLong(String.join(".", PositionBillConstant.NCKD_PARENT, PositionBillConstant.ID_KEY));
                    if (positionBoIdToVidMap.containsKey(parentId)) {
                        entryValue.set(PositionBillConstant.NCKD_PARENT, positionBoIdToVidMap.get(parentId));
                        change = true;
                    }

                    long positionId = entryValue.getLong(String.join(".", PositionBillConstant.NCKD_POSITION_KEY, PositionBillConstant.ID_KEY));
                    if (positionBoIdToVidMap.containsKey(positionId)) {
                        entryValue.set(PositionBillConstant.NCKD_POSITION_KEY, positionBoIdToVidMap.get(positionId));
                        change = true;
                    }

                    if (change) {
                        updateEntryValue.add(entryValue);
                    }
                }
            }

            if (!updateEntryValue.isEmpty()) {
                positionBillEntryEntityHelper.save(updateEntryValue.toArray(new DynamicObject[0]));
            }
        }

        TXHandle txHandle = TXHandle.get();
        log.info("endOperationTransaction_tx_isRollBack_is_{}", txHandle.isRollback());
    }
}
