package com.yem.wm.utils.groupfunc;


import com.yem.wm.utils.YEM;
import kd.bos.dataentity.entity.DynamicObjectCollection;
import kd.bos.dataentity.entity.LocaleString;
import kd.bos.dataentity.metadata.IDataEntityProperty;
import kd.bos.dataentity.metadata.dynamicobject.DynamicProperty;
import kd.bos.entity.MainEntityType;
import kd.bos.entity.datamodel.IDataModel;
import kd.bos.entity.property.BasedataProp;
import kd.bos.entity.property.FieldProp;
import kd.bos.entity.property.MulBasedataProp;
import kd.bos.entity.report.FilterInfo;
import kd.bos.entity.report.ReportQueryParam;
import kd.bos.form.container.Container;
import kd.bos.form.control.Control;
import kd.bos.form.field.BasedataEdit;
import kd.bos.form.field.DateRangeEdit;
import kd.bos.form.field.events.BeforeF7SelectEvent;
import kd.bos.form.field.events.BeforeF7SelectListener;
import kd.bos.list.ListShowParameter;
import kd.bos.orm.query.QCP;
import kd.bos.orm.query.QFilter;
import kd.bos.report.IReportView;
import kd.bos.report.plugin.AbstractReportFormPlugin;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.EventObject;
import java.util.List;

/**
 * 报表-表单插件-通用插件
 *
 * @author longh
 * @description 1、过滤面板组织按登录用户组织权限过滤 2、必录字段查询时必填校验
 * @date 2023年7月3日
 */
public class CommonRptEdit extends AbstractReportFormPlugin implements BeforeF7SelectListener {
    private static final String KEY_FILTERAP = "reportcommfilterpanelap";

    @Override
    public void registerListener(EventObject e) {
        super.registerListener(e);
        List<String> keys = getRptFilterCtrls(BasedataEdit.class);
        for (String key : keys) {
            BasedataEdit basedataEdit = this.getControl(key);
            if (basedataEdit != null) {
                basedataEdit.addBeforeF7SelectListener(this);
            }
        }

    }

    @Override
    public void beforeF7Select(BeforeF7SelectEvent evt) {
        if (isOrg(evt.getProperty())) {
            QFilter qFilter = new QFilter("id", QCP.in, YEM.getUserChangeAbleOrgIds());
            ListShowParameter listShowParameter = (ListShowParameter) evt.getFormShowParameter();
            listShowParameter.getTreeFilterParameter().getQFilters().add(qFilter);
            listShowParameter.getListFilterParameter().getQFilters().add(qFilter);
        }
    }

    @Override
    public void afterCreateNewData(EventObject e) {
        super.afterCreateNewData(e);
        IDataModel model = this.getModel();
        MainEntityType dataEntityType = model.getDataEntityType();
        long orgId = YEM.requestContext().getOrgId();
        List<String> keys = getRptFilterCtrls(BasedataEdit.class);
        for (String key : keys) {
            DynamicProperty property = dataEntityType.getProperty(key);
            if (isOrg(property)) {
                if (property instanceof BasedataProp) {
                    model.setValue(key, orgId);
                } else if (property instanceof MulBasedataProp) {
                    model.setValue(key, new Object[]{orgId});
                }
            }
        }
    }

    @Override
    public boolean verifyQuery(ReportQueryParam queryParam) {
        IReportView view = this.getView();
        IDataModel model = this.getModel();
        FilterInfo filterInfo = queryParam.getFilter();
        MainEntityType dataEntityType = model.getDataEntityType();
        List<String> fieldNames = new ArrayList<>();
        List<String> keys = getRptFilterCtrls();
        for (String key : keys) {
            DynamicProperty iProperty = dataEntityType.getProperty(key);
            if (isMustInput(iProperty) || isOrg(iProperty)) {
                if (isNotInput(filterInfo.getValue(key))) {
                    LocaleString displayName = iProperty.getDisplayName();
                    fieldNames.add(displayName == null ? "" : displayName.getLocaleValue());
                }
            }
        }
        if (fieldNames.size() > 0) {
            view.showTipNotification(String.format("请先选择%s。", String.join("、", fieldNames)));
            return false;
        }
        return super.verifyQuery(queryParam);
    }

    private boolean isOrg(IDataEntityProperty iProperty) {
        if (iProperty == null) {
            return false;
        }
        String baseEntityId = "";
        if (iProperty instanceof BasedataProp) {
            BasedataProp property = (BasedataProp) iProperty;
            baseEntityId = property.getBaseEntityId();
        } else if (iProperty instanceof MulBasedataProp) {
            MulBasedataProp property = (MulBasedataProp) iProperty;
            baseEntityId = property.getBaseEntityId();
        }
        return "bos_org".equals(baseEntityId)/* || "bos_adminorg".equals(baseEntityId) */;
    }

    private List<String> getRptFilterCtrls() {
        return getRptFilterCtrls(Object.class);
    }

    private <T> List<String> getRptFilterCtrls(Class<T> myClass) {
        List<String> keys = new ArrayList<>();
        IReportView view = this.getView();
        Container reportcommfilterpanelap = view.getControl(KEY_FILTERAP);
        List<Control> items = reportcommfilterpanelap.getItems();
        getRptFilterCtrls(myClass, keys, items);
        return keys;
    }

    private <T> void getRptFilterCtrls(Class<T> myClass, List<String> keys, List<Control> items) {
        for (Control item : items) {
            String key = item.getKey();
            if (myClass.isInstance(item)) {
                if(item instanceof DateRangeEdit){
                    DateRangeEdit newItem = (DateRangeEdit)item;
                    keys.add(newItem.getStartDateFieldKey());
                    keys.add(newItem.getEndDateFieldKey());
                    continue;
                }
                keys.add(key);
            }
            //kd.bos.form.field.DateRangeEdit
            if (item instanceof Container) {
                getRptFilterCtrls(myClass, keys, ((Container) item).getItems());
            }
        }
    }

    private boolean isMustInput(DynamicProperty iProperty) {
        if (iProperty instanceof FieldProp) {
            FieldProp property = (FieldProp) iProperty;
            return property.isMustInput();
        } else if (iProperty instanceof BasedataProp) {
            BasedataProp property = (BasedataProp) iProperty;
            return property.isMustInput();
        } else if (iProperty instanceof MulBasedataProp) {
            MulBasedataProp property = (MulBasedataProp) iProperty;
            return property.isMustInput();
        }
        return false;
    }

    private boolean isNotInput(Object propValue) {
        if (propValue == null) {
            return true;
        } else if (propValue instanceof BigDecimal && ((BigDecimal) propValue).compareTo(BigDecimal.ZERO) == 0) {
            return true;
        } else if (propValue instanceof String && ((String) propValue).isEmpty()) {
            return true;
        } else if (propValue instanceof Integer && ((Integer) propValue).intValue() == 0) {
            return true;
        } else if (propValue instanceof Long && ((Long) propValue).longValue() == 0L) {
            return true;
        } else if (propValue instanceof DynamicObjectCollection && ((DynamicObjectCollection) propValue).size() == 0) {
            return true;
        }
        return false;
    }
}
