package nckd.jimin.jyyy.fi.plugin.operate.travelcheck;

import kd.bos.dataentity.entity.DynamicObject;
import kd.bos.dataentity.entity.DynamicObjectCollection;
import kd.bos.entity.EntityMetadataCache;
import kd.bos.entity.plugin.AbstractOperationServicePlugIn;
import kd.bos.entity.plugin.args.BeginOperationTransactionArgs;
import kd.bos.org.utils.DynamicObjectUtils;
import kd.bos.orm.query.QCP;
import kd.bos.orm.query.QFilter;
import kd.bos.servicehelper.BusinessDataServiceHelper;
import kd.bos.servicehelper.operation.SaveServiceHelper;
import nckd.jimin.jyyy.fi.common.constant.travelcheck.BusTravelCheckBillConstant;
import nckd.jimin.jyyy.fi.common.constant.travelcheck.FinanceBillConfirmConstant;
import nckd.jimin.jyyy.fi.common.constant.travelcheck.TripReqBillConstant;

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

public class BusTravelCheckBillOp extends AbstractOperationServicePlugIn {

    @Override
    public void beginOperationTransaction(BeginOperationTransactionArgs e) {
        super.beginOperationTransaction(e);
        String operationKey = e.getOperationKey();
        DynamicObject[] dataEntities = e.getDataEntities();
        List<Object> idList = Arrays.stream(dataEntities).map(r -> r.getPkValue()).collect(Collectors.toList());
        DynamicObject[] dataArray = BusinessDataServiceHelper.load(idList.toArray(), EntityMetadataCache.getDataEntityType(BusTravelCheckBillConstant.ENTITYID));
        if("audit".equals(operationKey)){
            Arrays.stream(dataArray).forEach(dataEntity -> writeBackConfirmBill(dataEntity));
        }
        if("save".equals(operationKey) || "submit".equals(operationKey)){
            // 解除对账单关联的出差申请
            for(DynamicObject dataEntity : dataArray){
                unBindTripReqBill(dataEntity);
                writeBackSupDataTripReq(dataEntity);
            }
        }
        if("delete".equals(operationKey)){
            Arrays.stream(dataArray).forEach(dataEntity -> unBindTripReqBill(dataEntity));
        }
    }
    protected void unBindTripReqBill(DynamicObject dataEntity){
        Long checkBillId = dataEntity.getLong(BusTravelCheckBillConstant.ID);
        if(checkBillId != null && checkBillId != 0L){
            DynamicObject[] tripReqBillArray = BusinessDataServiceHelper.load(TripReqBillConstant.ENTITYID_F7, FinanceBillConfirmConstant.NCKD_BZ_CONFRMID, new QFilter[]{
                    new QFilter(FinanceBillConfirmConstant.NCKD_SUP_CHECKID, QCP.equals, checkBillId)
            });
            for(DynamicObject tripReqBill : tripReqBillArray){
                tripReqBill.set(FinanceBillConfirmConstant.NCKD_BZ_CONFRMID, null);
            }
            SaveServiceHelper.save(tripReqBillArray);
        }
    }

    protected void writeBackSupDataTripReq(DynamicObject dataEntity){
        Long checkBillId = dataEntity.getLong(BusTravelCheckBillConstant.ID);
        if(checkBillId != null && checkBillId != 0L){
            DynamicObjectCollection supDataEntryCol = dataEntity.getDynamicObjectCollection(BusTravelCheckBillConstant.NCKD_BZ_SUPDATA.ENTITYID);
            List<Object> tripReqBillList = supDataEntryCol.stream()
                    .map(r -> r.getDynamicObject(BusTravelCheckBillConstant.NCKD_BZ_SUPDATA.NCKD_TRIPREQBILL).getPkValue())
                    .collect(Collectors.toList());
            DynamicObject[] tripReqBillArray = BusinessDataServiceHelper.load(TripReqBillConstant.ENTITYID_F7, FinanceBillConfirmConstant.NCKD_SUP_CHECKID, new QFilter[]{
                    new QFilter(FinanceBillConfirmConstant.ID, QCP.in, tripReqBillList)
            });
            for(DynamicObject tripReqBill : tripReqBillArray){
                tripReqBill.set(FinanceBillConfirmConstant.NCKD_SUP_CHECKID, checkBillId);
            }
            SaveServiceHelper.save(tripReqBillArray);
        }
    }

    protected void writeBackConfirmBill(DynamicObject dataEntity){

        long checkBillId = dataEntity.getLong(BusTravelCheckBillConstant.ID);
        long confirmBillId = dataEntity.getLong(BusTravelCheckBillConstant.NCKD_NCKD_SOURCEBILLID);
        DynamicObject confirmBillInfo = BusinessDataServiceHelper.loadSingle(confirmBillId, FinanceBillConfirmConstant.ENTITYID);
        DynamicObjectCollection bzEntryCol = dataEntity.getDynamicObjectCollection(FinanceBillConfirmConstant.NCKD_BZ_ENTRY.ENTITYID);

        Map<Long, DynamicObject> bzSrcEntryMap = bzEntryCol.stream().collect(Collectors.toMap(bzEntry -> bzEntry.getLong(FinanceBillConfirmConstant.NCKD_BZ_ENTRY.NCKD_BZ_SRCENTRYID), bzEntry -> bzEntry));
        DynamicObjectCollection confirmBzEntryCol = confirmBillInfo.getDynamicObjectCollection(FinanceBillConfirmConstant.NCKD_BZ_ENTRY.ENTITYID);
        for(DynamicObject confirmBzEntry : confirmBzEntryCol){
            if(bzSrcEntryMap.containsKey(confirmBzEntry.getPkValue())){
                DynamicObject bzEntryInfo = bzSrcEntryMap.get(confirmBzEntry.getPkValue());
                DynamicObjectUtils.copy(bzEntryInfo, confirmBzEntry,BusTravelCheckBillConstant.COPY_IGNOREFILED);
            }
        }

        // 补助未涵盖反写确认单
        DynamicObjectCollection supEntryCol = dataEntity.getDynamicObjectCollection(BusTravelCheckBillConstant.NCKD_BZ_SUPDATA.ENTITYID);
        // 通过商旅对账ID反写

        DynamicObjectCollection confirmSupEntryCol = confirmBillInfo.getDynamicObjectCollection(BusTravelCheckBillConstant.NCKD_BZ_SUPDATA.ENTITYID);
        // 删除来源确认单的数据
        confirmSupEntryCol.removeIf(r -> r.getLong(BusTravelCheckBillConstant.NCKD_BZ_SUPDATA.NCKD_SRCCHECKID) == checkBillId);
        for(DynamicObject supEntry : supEntryCol){
            DynamicObject confirmSupEntry = confirmSupEntryCol.addNew();
            DynamicObjectUtils.copy(supEntry, confirmSupEntry,BusTravelCheckBillConstant.COPY_IGNOREFILED);
            confirmSupEntry.set(BusTravelCheckBillConstant.NCKD_BZ_SUPDATA.NCKD_SRCCHECKID, checkBillId);
        }

        DynamicObjectCollection slSrcEntryCol = dataEntity.getDynamicObjectCollection(FinanceBillConfirmConstant.NCKD_SL_ENTRY.ENTITYID);
        Map<Long, DynamicObject> slSrcEntryMap = slSrcEntryCol.stream().collect(Collectors.toMap(slEntry -> slEntry.getLong(FinanceBillConfirmConstant.NCKD_SL_ENTRY.NCKD_SL_SRCENTRYID), slEntry -> slEntry));
        DynamicObjectCollection confirmSlEntryCol = confirmBillInfo.getDynamicObjectCollection(FinanceBillConfirmConstant.NCKD_SL_ENTRY.ENTITYID);
        for(DynamicObject confirmSlEntry : confirmSlEntryCol){
            if(slSrcEntryMap.containsKey(confirmSlEntry.getPkValue())){
                DynamicObject slEntryInfo = slSrcEntryMap.get(confirmSlEntry.getPkValue());
                DynamicObjectUtils.copy(slEntryInfo, confirmSlEntry,BusTravelCheckBillConstant.COPY_IGNOREFILED);
            }
        }

        DynamicObjectCollection ycSrcEntryCol = dataEntity.getDynamicObjectCollection(FinanceBillConfirmConstant.NCKD_YC_ENTRY.ENTITYID);
        Map<Long, DynamicObject> ycSrcEntryMap = ycSrcEntryCol.stream().collect(Collectors.toMap(ycEntry -> ycEntry.getLong(FinanceBillConfirmConstant.NCKD_YC_ENTRY.NCKD_YC_SRCENTRYID), ycEntry -> ycEntry));
        DynamicObjectCollection confirmYcEntryCol = confirmBillInfo.getDynamicObjectCollection(FinanceBillConfirmConstant.NCKD_YC_ENTRY.ENTITYID);
        for(DynamicObject confirmYcEntry : confirmYcEntryCol){
            if(ycSrcEntryMap.containsKey(confirmYcEntry.getPkValue())){
                DynamicObject ycEntryInfo = ycSrcEntryMap.get(confirmYcEntry.getPkValue());
                DynamicObjectUtils.copy(ycEntryInfo, confirmYcEntry,BusTravelCheckBillConstant.COPY_IGNOREFILED);
            }
        }


        DynamicObjectCollection cbSrcEntryCol = dataEntity.getDynamicObjectCollection(FinanceBillConfirmConstant.NCKD_CB_ENTRY.ENTITYID);
        Map<Long, DynamicObject> cbSrcEntryMap = cbSrcEntryCol.stream().collect(Collectors.toMap(cbEntry -> cbEntry.getLong(FinanceBillConfirmConstant.NCKD_CB_ENTRY.NCKD_CB_SRCENTRYID), cbEntry -> cbEntry));
        DynamicObjectCollection confirmCbEntryCol = confirmBillInfo.getDynamicObjectCollection(FinanceBillConfirmConstant.NCKD_CB_ENTRY.ENTITYID);
        for(DynamicObject confirmCbEntry : confirmCbEntryCol){
            if(cbSrcEntryMap.containsKey(confirmCbEntry.getPkValue())){
                DynamicObject cbEntryInfo = cbSrcEntryMap.get(confirmCbEntry.getPkValue());
                DynamicObjectUtils.copy(cbEntryInfo, confirmCbEntry,BusTravelCheckBillConstant.COPY_IGNOREFILED);
            }
        }

        DynamicObjectCollection tgSrcEntryCol = dataEntity.getDynamicObjectCollection(FinanceBillConfirmConstant.NCKD_TG_ENTRY.ENTITYID);
        Map<Long, DynamicObject> tgSrcEntryMap = tgSrcEntryCol.stream().collect(Collectors.toMap(tgEntry -> tgEntry.getLong(FinanceBillConfirmConstant.NCKD_TG_ENTRY.NCKD_TG_SRCENTRYID), tgEntry -> tgEntry));
        DynamicObjectCollection confirmTgEntryCol = confirmBillInfo.getDynamicObjectCollection(FinanceBillConfirmConstant.NCKD_TG_ENTRY.ENTITYID);
        for(DynamicObject confirmTgEntry : confirmTgEntryCol){
            if(tgSrcEntryMap.containsKey(confirmTgEntry.getPkValue())){
                DynamicObject tgEntryInfo = tgSrcEntryMap.get(confirmTgEntry.getPkValue());
                DynamicObjectUtils.copy(tgEntryInfo, confirmTgEntry,BusTravelCheckBillConstant.COPY_IGNOREFILED);
            }
        }

        DynamicObjectCollection zsSrcEntryCol = dataEntity.getDynamicObjectCollection(FinanceBillConfirmConstant.NCKD_ZS_ENTRY.ENTITYID);
        Map<Long, DynamicObject> zsSrcEntryMap = zsSrcEntryCol.stream().collect(Collectors.toMap(zsEntry -> zsEntry.getLong(FinanceBillConfirmConstant.NCKD_ZS_ENTRY.NCKD_ZS_SRCENTRYID), zsEntry -> zsEntry));
        DynamicObjectCollection confirmZsEntryCol = confirmBillInfo.getDynamicObjectCollection(FinanceBillConfirmConstant.NCKD_ZS_ENTRY.ENTITYID);
        for(DynamicObject confirmZsEntry : confirmZsEntryCol){
            if(zsSrcEntryMap.containsKey(confirmZsEntry.getPkValue())){
                DynamicObject zsEntryInfo = zsSrcEntryMap.get(confirmZsEntry.getPkValue());
                DynamicObjectUtils.copy(zsEntryInfo, confirmZsEntry,BusTravelCheckBillConstant.COPY_IGNOREFILED);
            }
        }
        SaveServiceHelper.save(new DynamicObject[]{ confirmBillInfo});
    }
}
