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

import kd.bos.bill.AbstractBillPlugIn;
import kd.bos.dataentity.entity.DynamicObject;
import kd.bos.dataentity.entity.DynamicObjectCollection;
import kd.bos.entity.datamodel.events.PropertyChangedArgs;
import kd.bos.form.events.BeforeDoOperationEventArgs;
import kd.bos.form.field.BasedataEdit;
import kd.bos.form.field.events.BeforeF7SelectEvent;
import kd.bos.form.field.events.BeforeF7SelectListener;
import kd.bos.form.operate.FormOperate;
import kd.bos.list.ListShowParameter;
import kd.bos.orm.query.QFilter;
import nckd.jimin.jyyy.fi.common.constant.travelcheck.BusTravelCheckBillConstant;
import nckd.jimin.jyyy.fi.common.constant.travelcheck.TripReqBillConstant;
import nckd.jimin.jyyy.fi.common.util.CommonUtils;

import java.math.BigDecimal;
import java.util.Date;
import java.util.EventObject;
import java.util.List;
import java.util.stream.Collectors;

public class BusTravelCheckBillEdit extends AbstractBillPlugIn implements BusTravelCheckBillConstant, BeforeF7SelectListener {


    @Override
    public void registerListener(EventObject e) {
        super.registerListener(e);
        BasedataEdit tripReqBillEdit = this.getControl(NCKD_BZ_SUPDATA.NCKD_TRIPREQBILL);
        tripReqBillEdit.addBeforeF7SelectListener(this);
    }

    @Override
    public void beforeBindData(EventObject e) {
        super.beforeBindData(e);
    }

    @Override
    public void beforeDoOperation(BeforeDoOperationEventArgs args) {
        super.beforeDoOperation(args);
        FormOperate operate = (FormOperate)args.getSource();
        String operateKey = operate.getOperateKey();
    }

    @Override
    public void propertyChanged(PropertyChangedArgs e) {
        super.propertyChanged(e);
        String name = e.getProperty().getName();
        int rowIndex = e.getChangeSet()[0].getRowIndex();
        Object oldValue = e.getChangeSet()[0].getOldValue();
        Object newValue = e.getChangeSet()[0].getNewValue();
        // 出差申请单号
        if (NCKD_BZ_SUPDATA.NCKD_TRIPREQBILL.equals(name)) {
            tripReqBillChanged(oldValue, newValue, rowIndex);
        }
        // 财务核定出差天数
        if (NCKD_BZ_SUPDATA.NCKD_CHECKSUPDAYS.equals(name)) {
            // 计算补助金额
            Integer checkSupDay = (Integer) getModel().getValue(NCKD_BZ_SUPDATA.NCKD_CHECKSUPDAYS, rowIndex);
            DynamicObject tripReqBill = (DynamicObject)getModel().getValue(NCKD_BZ_SUPDATA.NCKD_TRIPREQBILL, rowIndex);
            BigDecimal bzAmount = CommonUtils.getBzAmount(tripReqBill.getDynamicObject(TripReqBillConstant.APPLIER));
            getModel().setValue(NCKD_BZ_SUPDATA.NCKD_SUAPMT, bzAmount.multiply(new BigDecimal(checkSupDay)), rowIndex);
            updateBzEntryFromUnCoveredData(rowIndex);
        }
        //监听单据内设置字段的值改变，用于计算新的日期范围控件的最早可选日期
        if (NCKD_BZ_SUPDATA.NCKD_BZDATERANGE_RSTARTDATE.equals(name)){
            DynamicObject entryRow = getModel().getEntryRowEntity(NCKD_BZ_SUPDATA.ENTITYID, rowIndex);
            Date startDate = entryRow.getDate(NCKD_BZ_SUPDATA.NCKD_BZDATERANGE_RSTARTDATE);
            Date tripStartDate = new Date(entryRow.getDynamicObject(NCKD_BZ_SUPDATA.NCKD_TRIPREQBILL).getDate(TripReqBillConstant.RSTARTDATE).getTime());
            if(startDate != null && tripStartDate != null){
                tripStartDate = CommonUtils.getStartOfDay(tripStartDate);
                if(startDate.before(tripStartDate)){
                    getView().showTipNotification("未涵盖日期范围不能早于行程开始时间。");
                    entryRow.set(NCKD_BZ_SUPDATA.NCKD_BZDATERANGE_RSTARTDATE,null);
                    entryRow.set(NCKD_BZ_SUPDATA.NCKD_BZDATERANGE_RENDDATE,null);
                    return;
                }
            }
        }
        if(NCKD_BZ_SUPDATA.NCKD_BZDATERANGE_RENDDATE.equals(name)){
            DynamicObject entryRow = getModel().getEntryRowEntity(NCKD_BZ_SUPDATA.ENTITYID, rowIndex);
            Date endDate = entryRow.getDate(NCKD_BZ_SUPDATA.NCKD_BZDATERANGE_RENDDATE);
            Date tripEndDate = new Date(entryRow.getDynamicObject(NCKD_BZ_SUPDATA.NCKD_TRIPREQBILL).getDate(TripReqBillConstant.RENDDATE).getTime());
            if(endDate != null && tripEndDate != null){
                tripEndDate = CommonUtils.getStartOfDay(tripEndDate);
                if(endDate.after(tripEndDate)){
                    getView().showTipNotification("未涵盖日期范围不能晚于行程结束时间。");
                    entryRow.set(NCKD_BZ_SUPDATA.NCKD_BZDATERANGE_RSTARTDATE,null);
                    entryRow.set(NCKD_BZ_SUPDATA.NCKD_BZDATERANGE_RENDDATE,null);
                    return;
                }
            }
        }
        if (NCKD_BZ_SUPDATA.NCKD_BZDATERANGE_RSTARTDATE.equals(name) ||
                NCKD_BZ_SUPDATA.NCKD_BZDATERANGE_RENDDATE.equals(name)) {
            DynamicObject entryRow = getModel().getEntryRowEntity(NCKD_BZ_SUPDATA.ENTITYID, rowIndex);
            Date startDate = entryRow.getDate(NCKD_BZ_SUPDATA.NCKD_BZDATERANGE_RSTARTDATE);
            Date endDate = entryRow.getDate(NCKD_BZ_SUPDATA.NCKD_BZDATERANGE_RENDDATE);

            if (startDate != null && endDate != null) {
                DynamicObject applierCpmpany = entryRow.getDynamicObject(NCKD_BZ_SUPDATA.NCKD_TRIPREQBILL).getDynamicObject(TripReqBillConstant.COMPANY);
                int days = CommonUtils.getDaysByWorkCalandar(startDate, endDate, applierCpmpany);
                getModel().setValue(NCKD_BZ_SUPDATA.NCKD_SUPDAYS, days, rowIndex);
                getModel().setValue(NCKD_BZ_SUPDATA.NCKD_CHECKSUPDAYS, days, rowIndex);
            } else {
                getModel().setValue(NCKD_BZ_SUPDATA.NCKD_SUPDAYS, 0, rowIndex);
                getModel().setValue(NCKD_BZ_SUPDATA.NCKD_CHECKSUPDAYS, 0, rowIndex);
            }
        }
    }
    protected void tripReqBillChanged(Object oldValue , Object newValue, int rowIndex){
        if(oldValue != null){
            DynamicObject tripReqBill = (DynamicObject) oldValue;
            int deleteRow = getApplierBzEntryRow(tripReqBill.getDynamicObject(TripReqBillConstant.APPLIER).getLong(TripReqBillConstant.ID));
            if(deleteRow >= 0){
                getModel().setValue(NCKD_BZ_ENTRY.NCKD_BZ_SUPDAYS, deleteRow , rowIndex);
                getModel().setValue(NCKD_BZ_ENTRY.NCKD_BZ_ADJAMOUNT, deleteRow , rowIndex);
            }
        }
        updateBzEntryFromUnCoveredData(rowIndex);
    }

    protected void updateBzEntryFromUnCoveredData(int rowIndex){
        DynamicObject tripReqBill = (DynamicObject)this.getModel().getValue(NCKD_BZ_SUPDATA.NCKD_TRIPREQBILL, rowIndex);
        // 更新补助天数
        long applierId = tripReqBill.getDynamicObject(TripReqBillConstant.APPLIER).getLong(TripReqBillConstant.ID);
        int updateRow = getApplierBzEntryRow(applierId);
        if(updateRow >= 0){
            // 更新财务核定天数到补助未涵盖天数
            DynamicObjectCollection supEntryCol = getModel().getEntryEntity(NCKD_BZ_SUPDATA.ENTITYID);

            // 合计同一出差人的补助未涵盖中的 财务核定出差天数 、补助金额
            Integer sumCheckSupDays = 0;
            BigDecimal sumSupAmount = BigDecimal.ZERO;
            for(DynamicObject supEntry : supEntryCol){
                if(supEntry.getDynamicObject(NCKD_BZ_SUPDATA.NCKD_TRIPREQBILL) != null
                    && supEntry.getDynamicObject(NCKD_BZ_SUPDATA.NCKD_TRIPREQBILL).getDynamicObject(TripReqBillConstant.APPLIER) != null
                    && supEntry.getDynamicObject(NCKD_BZ_SUPDATA.NCKD_TRIPREQBILL).getDynamicObject(TripReqBillConstant.APPLIER).getLong(TripReqBillConstant.ID) == applierId){
                    sumCheckSupDays = sumCheckSupDays + supEntry.getInt(NCKD_BZ_SUPDATA.NCKD_CHECKSUPDAYS);
                    sumSupAmount = sumSupAmount.add(supEntry.getBigDecimal(NCKD_BZ_SUPDATA.NCKD_SUAPMT));
                }
            }
            getModel().setValue(NCKD_BZ_ENTRY.NCKD_BZ_SUPDAYS, sumCheckSupDays , updateRow);
            getModel().setValue(NCKD_BZ_ENTRY.NCKD_BZ_ADJAMOUNT, sumSupAmount , updateRow);


            //出差天数合计 = 出差天数 + 补助未涵盖天数
            Integer sumDays = (Integer)getModel().getValue(NCKD_BZ_ENTRY.NCKD_BZ_TRAVELDAYS,updateRow) + (Integer)getModel().getValue(NCKD_BZ_ENTRY.NCKD_BZ_SUPDAYS,updateRow);
            getModel().setValue(NCKD_BZ_ENTRY.NCKD_BZ_SUMDAYS, sumDays, updateRow);
            BigDecimal sumAmount = CommonUtils.add((BigDecimal)getModel().getValue(NCKD_BZ_ENTRY.NCKD_BZ_AMOUNT,updateRow),(BigDecimal)getModel().getValue(NCKD_BZ_ENTRY.NCKD_BZ_ADJAMOUNT,updateRow));
            getModel().setValue(NCKD_BZ_ENTRY.NCKD_BZ_CHECKAMT, sumAmount, updateRow);
        }
    }

    protected int getApplierBzEntryRow(Long applierId){
        int entryRowCount = this.getModel().getEntryRowCount(NCKD_BZ_ENTRY.ENTITYID);
        for(int i = 0 ; i < entryRowCount ; i++){
            DynamicObject traverInfo = (DynamicObject)getModel().getValue(NCKD_BZ_ENTRY.NCKD_BZ_TRAVELER, i);
            // 通过出差人查询对应的补助分录
            if(traverInfo != null
                    && traverInfo.getLong(ID) == applierId){
                return i;
            }
        }
        return -1;
    }

    @Override
    public void beforeF7Select(BeforeF7SelectEvent event) {
        String propertyName = event.getProperty().getName();
        ListShowParameter showParameter = (ListShowParameter) event.getFormShowParameter();
        List<QFilter> filterList = showParameter.getListFilterParameter().getQFilters();
        if(NCKD_BZ_SUPDATA.NCKD_TRIPREQBILL.equals(propertyName)){
            // 过滤不为空
//            filterList.add(new QFilter(FinanceBillConfirmConstant.NCKD_BZ_CONFRMID, QFilter.equals, 0)
//                    .or(QFilter.isNull(FinanceBillConfirmConstant.NCKD_BZ_CONFRMID)));
//            filterList.add(QFilter.isNotNull(FinanceBillConfirmConstant.NCKD_SUP_CHECKID));
            DynamicObjectCollection supDataEntryCol = getModel().getEntryEntity(NCKD_BZ_SUPDATA.ENTITYID);
            // 过滤已选择的出差申请
            List<Object> selectRow = supDataEntryCol.stream()
                    .filter(entryRow -> entryRow.getDynamicObject(NCKD_BZ_SUPDATA.NCKD_TRIPREQBILL) != null)
                    .map(entryRow -> entryRow.getDynamicObject(NCKD_BZ_SUPDATA.NCKD_TRIPREQBILL).getPkValue())
                    .collect(Collectors.toList());

            DynamicObjectCollection bzEntryCol = getModel().getEntryEntity(NCKD_BZ_ENTRY.ENTITYID);
            List<Object> bzTravelIdList = bzEntryCol.stream()
                    .filter(entryRow -> entryRow.getDynamicObject(NCKD_BZ_ENTRY.NCKD_BZ_TRAVELER) != null)
                    .map(entryRow -> entryRow.getDynamicObject(NCKD_BZ_ENTRY.NCKD_BZ_TRAVELER).getPkValue())
                    .collect(Collectors.toList());
//            if(selectRow.size() > 0){
//                filterList.add(new QFilter(TripReqBillConstant.ID, QFilter.not_in, selectRow));
//            }
            if(bzTravelIdList.size() > 0){
                filterList.add(new QFilter(TripReqBillConstant.APPLIER, QFilter.in, bzTravelIdList));
            }
            filterList.addAll(filterList);
        }
    }
}
