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

import kd.bos.dataentity.entity.DynamicObject;
import kd.bos.dataentity.entity.DynamicObjectCollection;
import kd.bos.entity.plugin.AbstractOperationServicePlugIn;
import kd.bos.entity.plugin.AddValidatorsEventArgs;
import kd.bos.entity.plugin.args.BeginOperationTransactionArgs;
import kd.bos.logging.Log;
import kd.bos.logging.LogFactory;
import kd.bos.org.utils.DynamicObjectUtils;
import kd.bos.orm.ORM;
import kd.bos.orm.query.QCP;
import kd.bos.orm.query.QFilter;
import kd.bos.servicehelper.BusinessDataServiceHelper;
import kd.bos.servicehelper.coderule.CodeRuleServiceHelper;
import kd.bos.servicehelper.operation.DeleteServiceHelper;
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.TravelFinanDraftConstant;
import nckd.jimin.jyyy.fi.common.constant.travelcheck.TripReqBillConstant;
import nckd.jimin.jyyy.fi.plugin.operate.validator.FinanceBillConfirmValidator;

import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;

public class FinanceBillConfirmOp extends AbstractOperationServicePlugIn {

    private static final Log logger = LogFactory.getLog(FinanceBillConfirmOp.class);

    @Override
    public void onAddValidators(AddValidatorsEventArgs e) {
        super.onAddValidators(e);
        e.getValidators().add(new FinanceBillConfirmValidator());
    }

    @Override
    public void beginOperationTransaction(BeginOperationTransactionArgs e) {
        super.beginOperationTransaction(e);
        String operationKey = e.getOperationKey();
        DynamicObject[] dataEntities = e.getDataEntities();
        if(FinanceBillConfirmConstant.OP_PUSHCHECKBILL.equals(operationKey)){
            Arrays.stream(dataEntities).forEach(r -> createBusTravelCheckBill(r));
        }
        if("delete".equals(operationKey)){
            Arrays.stream(dataEntities).forEach(r -> clearBillFlag(r));
        }
    }

    protected void clearBillFlag(DynamicObject confirmBillInfo){
        Object confirmBillId = confirmBillInfo.getPkValue();
        // 删除商旅对账底稿
        DeleteServiceHelper.delete(TravelFinanDraftConstant.ENTITYID, new QFilter[]{
            new QFilter(FinanceBillConfirmConstant.NCKD_BZ_CONFRMID, QCP.equals, confirmBillId)
        });

        // 清除出差申请
        DynamicObject[] tripReqBillArray = BusinessDataServiceHelper.load(TripReqBillConstant.ENTITYID, FinanceBillConfirmConstant.NCKD_BZ_CONFRMID, new QFilter[]{
                new QFilter(FinanceBillConfirmConstant.NCKD_BZ_CONFRMID, QCP.equals, confirmBillId)
        });
        Arrays.stream(tripReqBillArray).forEach(r -> r.set(FinanceBillConfirmConstant.NCKD_BZ_CONFRMID, 0));
        SaveServiceHelper.save(tripReqBillArray);

//        // 商旅费用
//        DynamicObject[] slAllCheckingBillArray = BusinessDataServiceHelper.load("er_allcheckingbill", FinanceBillConfirmConstant.NCKD_SL_CONFRMID, new QFilter[]{
//                new QFilter(FinanceBillConfirmConstant.NCKD_SL_CONFRMID, QCP.equals, confirmBillId)
//        });
//        Arrays.stream(slAllCheckingBillArray).forEach(r -> r.set(FinanceBillConfirmConstant.NCKD_SL_CONFRMID, 0));
//        SaveServiceHelper.save(slAllCheckingBillArray);
//
//        // 用车
//        DynamicObject[] ycVehicelCheckBillArray = BusinessDataServiceHelper.load("er_vehiclecheckingbill", FinanceBillConfirmConstant.NCKD_YC_CONFRMID, new QFilter[]{
//                new QFilter(FinanceBillConfirmConstant.NCKD_YC_CONFRMID, QCP.equals, confirmBillId)
//        });
//        Arrays.stream(ycVehicelCheckBillArray).forEach(r -> r.set(FinanceBillConfirmConstant.NCKD_YC_CONFRMID, 0));
//        SaveServiceHelper.save(ycVehicelCheckBillArray);
//
//        // 超标
//        DynamicObject[] cbHotelCheckingBillArray = BusinessDataServiceHelper.load("er_hotelcheckingbill", FinanceBillConfirmConstant.NCKD_CB_CONFRMID, new QFilter[]{
//                new QFilter(FinanceBillConfirmConstant.NCKD_CB_CONFRMID, QCP.equals, confirmBillId)
//        });
//        Arrays.stream(cbHotelCheckingBillArray).forEach(r -> r.set(FinanceBillConfirmConstant.NCKD_CB_CONFRMID, 0));
//        SaveServiceHelper.save(cbHotelCheckingBillArray);
//
//        DynamicObject[] cbPlaneCheckingBillArray = BusinessDataServiceHelper.load("er_planecheckingbill", FinanceBillConfirmConstant.NCKD_CB_CONFRMID, new QFilter[]{
//                new QFilter(FinanceBillConfirmConstant.NCKD_CB_CONFRMID, QCP.equals, confirmBillId)
//        });
//        Arrays.stream(cbPlaneCheckingBillArray).forEach(r -> r.set(FinanceBillConfirmConstant.NCKD_CB_CONFRMID, 0));
//        SaveServiceHelper.save(cbPlaneCheckingBillArray);
//
//        DynamicObject[] cbTrainCheckingBillArray = BusinessDataServiceHelper.load("er_traincheckingbill", FinanceBillConfirmConstant.NCKD_CB_CONFRMID, new QFilter[]{
//                new QFilter(FinanceBillConfirmConstant.NCKD_CB_CONFRMID, QCP.equals, confirmBillId)
//        });
//        Arrays.stream(cbTrainCheckingBillArray).forEach(r -> r.set(FinanceBillConfirmConstant.NCKD_CB_CONFRMID, 0));
//        SaveServiceHelper.save(cbTrainCheckingBillArray);
//
//        DynamicObject[] cbVehicleCheckingBillArray = BusinessDataServiceHelper.load("er_vehiclecheckingbill", FinanceBillConfirmConstant.NCKD_CB_CONFRMID, new QFilter[]{
//                new QFilter(FinanceBillConfirmConstant.NCKD_CB_CONFRMID, QCP.equals, confirmBillId)
//        });
//        Arrays.stream(cbVehicleCheckingBillArray).forEach(r -> r.set(FinanceBillConfirmConstant.NCKD_CB_CONFRMID, 0));
//        SaveServiceHelper.save(cbVehicleCheckingBillArray);
//
//        // 退改
//        DynamicObject[] tgHotelCheckingBillArray = BusinessDataServiceHelper.load("er_hotelcheckingbill", FinanceBillConfirmConstant.NCKD_TG_CONFRMID, new QFilter[]{
//                new QFilter(FinanceBillConfirmConstant.NCKD_TG_CONFRMID, QCP.equals, confirmBillId)
//        });
//        Arrays.stream(tgHotelCheckingBillArray).forEach(r -> r.set(FinanceBillConfirmConstant.NCKD_TG_CONFRMID, 0));
//        SaveServiceHelper.save(tgHotelCheckingBillArray);
//
//        DynamicObject[] tgPlaneCheckingBillArray = BusinessDataServiceHelper.load("er_planecheckingbill", FinanceBillConfirmConstant.NCKD_TG_CONFRMID, new QFilter[]{
//                new QFilter(FinanceBillConfirmConstant.NCKD_TG_CONFRMID, QCP.equals, confirmBillId)
//        });
//         Arrays.stream(tgPlaneCheckingBillArray).forEach(r -> r.set(FinanceBillConfirmConstant.NCKD_TG_CONFRMID, 0));
//        SaveServiceHelper.save(tgPlaneCheckingBillArray);
//
//        DynamicObject[] tgTrainCheckingBillArray = BusinessDataServiceHelper.load("er_traincheckingbill", FinanceBillConfirmConstant.NCKD_TG_CONFRMID, new QFilter[]{
//                new QFilter(FinanceBillConfirmConstant.NCKD_TG_CONFRMID, QCP.equals, confirmBillId)
//        });
//        Arrays.stream(tgTrainCheckingBillArray).forEach(r -> r.set(FinanceBillConfirmConstant.NCKD_TG_CONFRMID, 0));
//        SaveServiceHelper.save(tgTrainCheckingBillArray);
//
//        // 住宿
//        DynamicObject[] zhHotelCheckingBillArray = BusinessDataServiceHelper.load("er_hotelcheckingbill", FinanceBillConfirmConstant.NCKD_ZS_CONFRMID, new QFilter[]{
//                new QFilter(FinanceBillConfirmConstant.NCKD_ZS_CONFRMID, QCP.equals, confirmBillId)
//        });
//        Arrays.stream(zhHotelCheckingBillArray).forEach(r -> r.set(FinanceBillConfirmConstant.NCKD_ZS_CONFRMID, 0));
//        SaveServiceHelper.save(zhHotelCheckingBillArray);
    }

    protected void createBusTravelCheckBill(DynamicObject confirmBillInfo){
        // 根据部门秘书创建商旅对账单
        confirmBillInfo = BusinessDataServiceHelper.loadSingle(confirmBillInfo.getPkValue(),confirmBillInfo.getDynamicObjectType().getName());
        Set<Long> allSecretaryLeaderIds = new HashSet<>();
        // 补助部门秘书
        confirmBillInfo.getDynamicObjectCollection(FinanceBillConfirmConstant.NCKD_BZ_ENTRY.ENTITYID).stream()
                .filter(r -> r.getDynamicObject(FinanceBillConfirmConstant.NCKD_BZ_ENTRY.NCKD_BZ_USERLEADER) != null)
                .forEach(r -> allSecretaryLeaderIds.add(r.getDynamicObject(FinanceBillConfirmConstant.NCKD_BZ_ENTRY.NCKD_BZ_USERLEADER).getLong(FinanceBillConfirmConstant.ID)));

        confirmBillInfo.getDynamicObjectCollection(FinanceBillConfirmConstant.NCKD_SL_ENTRY.ENTITYID).stream()
                .filter(r -> r.getDynamicObject(FinanceBillConfirmConstant.NCKD_SL_ENTRY.NCKD_SL_USERLEADER) != null)
                .forEach(r -> allSecretaryLeaderIds.add(r.getDynamicObject(FinanceBillConfirmConstant.NCKD_SL_ENTRY.NCKD_SL_USERLEADER).getLong(FinanceBillConfirmConstant.ID)));

        confirmBillInfo.getDynamicObjectCollection(FinanceBillConfirmConstant.NCKD_YC_ENTRY.ENTITYID).stream()
                .filter(r -> r.getDynamicObject(FinanceBillConfirmConstant.NCKD_YC_ENTRY.NCKD_YC_USERLEADER) != null)
                .forEach(r -> allSecretaryLeaderIds.add(r.getDynamicObject(FinanceBillConfirmConstant.NCKD_YC_ENTRY.NCKD_YC_USERLEADER).getLong(FinanceBillConfirmConstant.ID)));

        confirmBillInfo.getDynamicObjectCollection(FinanceBillConfirmConstant.NCKD_CB_ENTRY.ENTITYID).stream()
                .filter(r -> r.getDynamicObject(FinanceBillConfirmConstant.NCKD_CB_ENTRY.NCKD_CB_USERLEADER) != null)
                .forEach(r -> allSecretaryLeaderIds.add(r.getDynamicObject(FinanceBillConfirmConstant.NCKD_CB_ENTRY.NCKD_CB_USERLEADER).getLong(FinanceBillConfirmConstant.ID)));

        confirmBillInfo.getDynamicObjectCollection(FinanceBillConfirmConstant.NCKD_TG_ENTRY.ENTITYID).stream()
                .filter(r -> r.getDynamicObject(FinanceBillConfirmConstant.NCKD_TG_ENTRY.NCKD_TG_USERLEADER) != null)
                .forEach(r -> allSecretaryLeaderIds.add(r.getDynamicObject(FinanceBillConfirmConstant.NCKD_TG_ENTRY.NCKD_TG_USERLEADER).getLong(FinanceBillConfirmConstant.ID)));

        confirmBillInfo.getDynamicObjectCollection(FinanceBillConfirmConstant.NCKD_ZS_ENTRY.ENTITYID).stream()
                .filter(r -> r.getDynamicObject(FinanceBillConfirmConstant.NCKD_ZS_ENTRY.NCKD_ZS_USERLEADER) != null)
                .forEach(r -> allSecretaryLeaderIds.add(r.getDynamicObject(FinanceBillConfirmConstant.NCKD_ZS_ENTRY.NCKD_ZS_USERLEADER).getLong(FinanceBillConfirmConstant.ID)));

        String checkMonth = confirmBillInfo.getString(FinanceBillConfirmConstant.NCKD_CHECKMONTH);
        DynamicObject confirmBill = confirmBillInfo;
        allSecretaryLeaderIds.forEach(r -> createCheckBill(r, checkMonth,confirmBill));
    }

    protected void createCheckBill(Long secretaryLeaderId, String checkMonth , DynamicObject confirmBillInfo){
        long confirmBillId = confirmBillInfo.getLong(FinanceBillConfirmConstant.ID);
        // 查询是否存在
        QFilter qFilter = new QFilter(BusTravelCheckBillConstant.NCKD_NCKD_SOURCEBILLID, QCP.equals,confirmBillId);
        qFilter.and(BusTravelCheckBillConstant.NCKD_UPAUDITOR, QCP.equals, secretaryLeaderId);
        if(ORM.create().exists(BusTravelCheckBillConstant.ENTITYID, qFilter.toArray())){
            logger.info("部门领导【{}}】已存在商旅对账单【{}}】", secretaryLeaderId, checkMonth);
            return;
        }

        // 创建
        DynamicObject busCheckBill = BusinessDataServiceHelper.newDynamicObject(BusTravelCheckBillConstant.ENTITYID);

        String number = CodeRuleServiceHelper.getNumber(BusTravelCheckBillConstant.ENTITYID, busCheckBill, null);
        busCheckBill.set(BusTravelCheckBillConstant.KEY_BILLNO, number);
        //busCheckBill.set(BusTravelCheckBillConstant.NCKD_DEPSECRETARY, secretaryId);
        busCheckBill.set(BusTravelCheckBillConstant.NCKD_UPAUDITOR, secretaryLeaderId);
        busCheckBill.set(BusTravelCheckBillConstant.NCKD_CHECKMONTH, checkMonth);
        busCheckBill.set(BusTravelCheckBillConstant.NCKD_NCKD_SOURCEBILLID, confirmBillId);
        busCheckBill.set(BusTravelCheckBillConstant.KEY_BILLSTATUS,"A");
        DynamicObject currency = BusinessDataServiceHelper.loadSingle("bd_currency", new QFilter("number", QCP.equals, "CNY").toArray());
        busCheckBill.set(FinanceBillConfirmConstant.NCKD_CURRENCY, currency);

        DynamicObjectCollection checkBzEntryCol = busCheckBill.getDynamicObjectCollection(FinanceBillConfirmConstant.NCKD_BZ_ENTRY.ENTITYID);
        DynamicObjectCollection confirmBzEntryCol = confirmBillInfo.getDynamicObjectCollection(FinanceBillConfirmConstant.NCKD_BZ_ENTRY.ENTITYID);
        for(DynamicObject confirmBzEntry : confirmBzEntryCol){
            DynamicObject depSecretary = confirmBzEntry.getDynamicObject(FinanceBillConfirmConstant.NCKD_BZ_ENTRY.NCKD_BZ_USERLEADER);
            if(depSecretary != null && depSecretary.getLong(FinanceBillConfirmConstant.ID) == secretaryLeaderId){
                DynamicObject checkEntry = checkBzEntryCol.addNew();
                checkEntry.set(FinanceBillConfirmConstant.NCKD_BZ_ENTRY.NCKD_BZ_SRCENTRYID, confirmBzEntry.getPkValue());
                DynamicObjectUtils.copy(confirmBzEntry, checkEntry, BusTravelCheckBillConstant.COPY_IGNOREFILED);
            }
        }

        DynamicObjectCollection checkSlEntryCol = busCheckBill.getDynamicObjectCollection(FinanceBillConfirmConstant.NCKD_SL_ENTRY.ENTITYID);
        DynamicObjectCollection confirmSlEntryCol = confirmBillInfo.getDynamicObjectCollection(FinanceBillConfirmConstant.NCKD_SL_ENTRY.ENTITYID);
        for(DynamicObject confirmSlEntry : confirmSlEntryCol){
            DynamicObject depSecretary = confirmSlEntry.getDynamicObject(FinanceBillConfirmConstant.NCKD_SL_ENTRY.NCKD_SL_USERLEADER);
            if(depSecretary != null && depSecretary.getLong(FinanceBillConfirmConstant.ID) == secretaryLeaderId){
                DynamicObject checkEntry = checkSlEntryCol.addNew();
                checkEntry.set(FinanceBillConfirmConstant.NCKD_SL_ENTRY.NCKD_SL_SRCENTRYID, confirmSlEntry.getPkValue());
                DynamicObjectUtils.copy(confirmSlEntry, checkEntry, BusTravelCheckBillConstant.COPY_IGNOREFILED);
            }
        }

        DynamicObjectCollection checkYcEntryCol = busCheckBill.getDynamicObjectCollection(FinanceBillConfirmConstant.NCKD_YC_ENTRY.ENTITYID);
        DynamicObjectCollection confirmYcEntryCol = confirmBillInfo.getDynamicObjectCollection(FinanceBillConfirmConstant.NCKD_YC_ENTRY.ENTITYID);
        for(DynamicObject confirmYcEntry : confirmYcEntryCol){
            DynamicObject depSecretary = confirmYcEntry.getDynamicObject(FinanceBillConfirmConstant.NCKD_YC_ENTRY.NCKD_YC_USERLEADER);
            if(depSecretary != null && depSecretary.getLong(FinanceBillConfirmConstant.ID) == secretaryLeaderId){
                DynamicObject checkEntry = checkYcEntryCol.addNew();
                checkEntry.set(FinanceBillConfirmConstant.NCKD_YC_ENTRY.NCKD_YC_SRCENTRYID, confirmYcEntry.getPkValue());
                DynamicObjectUtils.copy(confirmYcEntry, checkEntry, BusTravelCheckBillConstant.COPY_IGNOREFILED);
            }
        }

        DynamicObjectCollection checkCbEntryCol = busCheckBill.getDynamicObjectCollection(FinanceBillConfirmConstant.NCKD_CB_ENTRY.ENTITYID);
        DynamicObjectCollection confirmCbEntryCol = confirmBillInfo.getDynamicObjectCollection(FinanceBillConfirmConstant.NCKD_CB_ENTRY.ENTITYID);
        for(DynamicObject confirmCbEntry : confirmCbEntryCol){
            DynamicObject depSecretary = confirmCbEntry.getDynamicObject(FinanceBillConfirmConstant.NCKD_CB_ENTRY.NCKD_CB_USERLEADER);
            if(depSecretary != null && depSecretary.getLong(FinanceBillConfirmConstant.ID) == secretaryLeaderId){
                DynamicObject checkEntry = checkCbEntryCol.addNew();
                checkEntry.set(FinanceBillConfirmConstant.NCKD_CB_ENTRY.NCKD_CB_SRCENTRYID, confirmCbEntry.getPkValue());
                DynamicObjectUtils.copy(confirmCbEntry, checkEntry, BusTravelCheckBillConstant.COPY_IGNOREFILED);
            }
        }

        DynamicObjectCollection checkTgEntryCol = busCheckBill.getDynamicObjectCollection(FinanceBillConfirmConstant.NCKD_TG_ENTRY.ENTITYID);
        DynamicObjectCollection confirmTgEntryCol = confirmBillInfo.getDynamicObjectCollection(FinanceBillConfirmConstant.NCKD_TG_ENTRY.ENTITYID);
        for(DynamicObject confirmTgEntry : confirmTgEntryCol){
            DynamicObject depSecretary = confirmTgEntry.getDynamicObject(FinanceBillConfirmConstant.NCKD_TG_ENTRY.NCKD_TG_USERLEADER);
            if(depSecretary != null && depSecretary.getLong(FinanceBillConfirmConstant.ID) == secretaryLeaderId){
                DynamicObject checkEntry = checkTgEntryCol.addNew();
                checkEntry.set(FinanceBillConfirmConstant.NCKD_TG_ENTRY.NCKD_TG_SRCENTRYID, confirmTgEntry.getPkValue());
                DynamicObjectUtils.copy(confirmTgEntry, checkEntry, BusTravelCheckBillConstant.COPY_IGNOREFILED);
            }
        }

        DynamicObjectCollection checkZsEntryCol = busCheckBill.getDynamicObjectCollection(FinanceBillConfirmConstant.NCKD_ZS_ENTRY.ENTITYID);
        DynamicObjectCollection confirmZsEntryCol = confirmBillInfo.getDynamicObjectCollection(FinanceBillConfirmConstant.NCKD_ZS_ENTRY.ENTITYID);
        for(DynamicObject confirmZsEntry : confirmZsEntryCol){
            DynamicObject depSecretary = confirmZsEntry.getDynamicObject(FinanceBillConfirmConstant.NCKD_ZS_ENTRY.NCKD_ZS_USERLEADER);
            if(depSecretary != null && depSecretary.getLong(FinanceBillConfirmConstant.ID) == secretaryLeaderId){
                DynamicObject checkEntry = checkZsEntryCol.addNew();
                checkEntry.set(FinanceBillConfirmConstant.NCKD_ZS_ENTRY.NCKD_ZS_SRCENTRYID, confirmZsEntry.getPkValue());
                DynamicObjectUtils.copy(confirmZsEntry, checkEntry, BusTravelCheckBillConstant.COPY_IGNOREFILED);
            }
        }

        SaveServiceHelper.save(new DynamicObject[]{ busCheckBill});
    }
}
