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

import kd.bos.dataentity.OperateOption;
import kd.bos.dataentity.entity.DynamicObject;
import kd.bos.dataentity.entity.DynamicObjectCollection;
import kd.bos.dataentity.resource.ResManager;
import kd.bos.entity.ExtendedDataEntity;
import kd.bos.entity.operate.result.OperateErrorInfo;
import kd.bos.entity.operate.result.OperationResult;
import kd.bos.entity.plugin.AbstractOperationServicePlugIn;
import kd.bos.entity.plugin.AddValidatorsEventArgs;
import kd.bos.entity.plugin.PreparePropertysEventArgs;
import kd.bos.entity.plugin.args.EndOperationTransactionArgs;
import kd.bos.entity.validate.AbstractValidator;
import kd.bos.exception.KDException;
import kd.bos.logging.Log;
import kd.bos.logging.LogFactory;
import kd.bos.servicehelper.operation.OperationServiceHelper;
import kd.bos.servicehelper.operation.SaveServiceHelper;
import kd.fi.er.common.ErBillStatusEnum;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 外办申请，撤销变更
 */
public class DailyVehicleBillInvokeOpPlugin extends AbstractOperationServicePlugIn {
    private static final Log logger = LogFactory.getLog(DailyVehicleBillInvokeOpPlugin.class);

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

        List<String> fieldKeys = e.getFieldKeys();

        fieldKeys.add("billstatus");
        fieldKeys.add("applier");
        fieldKeys.add("startdate");
        fieldKeys.add("enddate");
        fieldKeys.add("nckd_ischange");
        fieldKeys.add("vehiclecity");

        fieldKeys.add("nckd_historyentry");
        fieldKeys.add("nckd_historyentry.nckd_historystartdate");
        fieldKeys.add("nckd_historyentry.nckd_historyenddate");
        fieldKeys.add("nckd_historyentry.nckd_historycity");
        fieldKeys.add("nckd_historyentry.nckd_changetime");
    }

    public void onAddValidators(AddValidatorsEventArgs e) {
        this.addDailyVehicleInvokeValidator(e);
    }

    public void endOperationTransaction(EndOperationTransactionArgs e) {
        DynamicObject[] bills = e.getDataEntities();
        if (bills.length > 0) {
            this.doRevoke(bills);
            SaveServiceHelper.save(bills);
            Object[] ids = new Object[bills.length];

            for(int index = 0; index < bills.length; ++index) {
                ids[index] = bills[index].getPkValue();
            }

            OperateOption op = OperateOption.create();
            op.setVariableValue("WF", String.valueOf(true));
            OperationResult res = OperationServiceHelper.executeOperate("audit", "er_dailyvehiclebill", ids, op);

            if (!res.isSuccess()) {
                StringBuilder tips = this.buildErrorInfoBuilder(res);
                throw new KDException(String.format(ResManager.loadKDString("行程撤销失败：%1$s", "TripEntryInfoRevokeOP_0", "fi-er-opplugin", new Object[0]), tips.toString()));
            }
        }
    }

    private StringBuilder buildErrorInfoBuilder(OperationResult res) {
        StringBuilder tips = new StringBuilder();
        if (null != res.getMessage()) {
            tips.append(res.getMessage());
        }

        if (null != res.getAllErrorInfo() && res.getAllErrorInfo().size() > 0) {
            List<OperateErrorInfo> list = res.getAllErrorInfo();
            list.stream().forEach((p) -> {
                tips.append(p.getMessage());
            });
        }

        return tips;
    }

    private void doRevoke(DynamicObject[] bills) {
        DynamicObject bill = bills[0];
        DynamicObjectCollection historyEntities = bill.getDynamicObjectCollection("nckd_historyentry");

        if (historyEntities.size() != 0) {
            Optional<DynamicObject> optional = historyEntities.stream().max(Comparator.comparing((e) -> {
                return e.getDate("nckd_changetime");
            }));
            Date maxDate;
            if (optional.isPresent()) {
                maxDate = new Date(((DynamicObject)optional.get()).getDate("nckd_changetime").getTime());
            } else {
                maxDate = new Date(((DynamicObject)historyEntities.get(0)).getDate("nckd_changetime").getTime());
            }

            List<DynamicObject> upToDates = (List)historyEntities.stream().filter((v) -> {
                return v.getDate("nckd_changetime").compareTo(maxDate) == 0;
            }).collect(Collectors.toList());

            if(upToDates.size() > 0){
                DynamicObject upToDate = upToDates.get(0);

                bill.set("vehiclecity", upToDate.getDynamicObject("nckd_historycity"));
                bill.set("startdate", upToDate.getDate("nckd_historystartdate"));
                bill.set("enddate", upToDate.getDate("nckd_historyenddate"));
            }
            bill.set("billstatus", "B");

            historyEntities.removeAll(upToDates);
        }
    }

    protected void addDailyVehicleInvokeValidator(AddValidatorsEventArgs e) {
        e.addValidator(new DailyVehicleInfoInvokeValiator());
    }

    private static class DailyVehicleInfoInvokeValiator extends AbstractValidator {
        private DailyVehicleInfoInvokeValiator() {
        }

        public void validate() {
            ExtendedDataEntity[] dataEntities = this.getDataEntities();
            ExtendedDataEntity[] var2 = dataEntities;
            int var3 = dataEntities.length;

            for(int var4 = 0; var4 < var3; ++var4) {
                ExtendedDataEntity dataEntity = var2[var4];
                DynamicObject billObj = dataEntity.getDataEntity();

                if (!billObj.getString("billstatus").equals(ErBillStatusEnum.A.name())) {
                    this.addErrorMessage(dataEntity, ResManager.loadKDString("只有单据状态为“暂存”的单据才允许撤销变更。", "TripEntryInfoRevokeOP_1", "fi-er-opplugin", new Object[0]));
                }

            }

        }
    }
}
