package org.example.Entity.Control.Panel;

import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
import org.example.Entity.Control.Base.Component;
import org.example.Entity.Control.Container.RowColumn;
import org.example.Entity.Control.Data.DataStore;
import org.example.Entity.Control.Fields.ComboBox;

import java.util.*;
import java.util.stream.Collectors;

@JsonInclude(JsonInclude.Include.NON_NULL)
public class GridPanel extends Panel {


    public GridPanel() {
        super();
        this.setXtype("gridpanel");
    }

    public boolean PageAble;


    @JsonInclude(JsonInclude.Include.NON_NULL) // 对应Newtonsoft.Json的NullValueHandling.Ignore
    private List<Component> _columns;

    @JsonInclude(JsonInclude.Include.NON_NULL)
    public List<Component> getColumns() {
        return _columns;
    }

    public void setColumns(List<Component> value) {
        _columns = value;

        if (value != null) {
            List<String> bandNames = new ArrayList<>();
            List<Component> cols = new ArrayList<>();

            // 筛选包含bandFields的列并处理
            List<Component> f = value.stream()
                    .filter(col -> col instanceof RowColumn)
                    .map(col -> (RowColumn) col)
                    .filter(column -> column.getBandFields() != null && column.getBandFields().length > 0)
                    .map(column -> {
                        String[] bfields = column.getBandFields();
                        Collections.addAll(bandNames, bfields);

                        // 收集关联的列
                        List<Component> relatedCols = value.stream()
                                .filter(cl -> cl instanceof RowColumn)
                                .map(cl -> (RowColumn) cl)
                                .filter(c -> Arrays.asList(bfields).contains(c.getDataIndex()))
                                .collect(Collectors.toList());
                        cols.addAll(relatedCols);

                        return (Component) column; // 转回Component类型
                    })
                    .collect(Collectors.toList());

            // 处理下拉框列的联动关系
            List<RowColumn> comboboxColumns = value.stream()
                    .filter(col -> col instanceof RowColumn)
                    .map(col -> (RowColumn) col)
                    .filter(column -> column.getEditor() != null && column.getEditor() instanceof ComboBox)
                    .collect(Collectors.toList());

            for (RowColumn column : comboboxColumns) {
                String target = "{" + column.getDataIndex() + "}";
                String[] linkNames = comboboxColumns.stream()
                        .filter(_com -> column != _com) // 排除自身
                        .filter(_com -> {
                            ComboBox comboBox = (ComboBox) _com.getEditor();
                            String dataSource = comboBox.getDataSource();
                            return dataSource != null &&
                                    dataSource.toLowerCase().contains(target.toLowerCase());
                        })
                        .map(_com -> _com.getDataIndex())
                        .toArray(String[]::new);
                column.linknames = (linkNames);
            }

            if (f.size() <= 0) {
                return;
            }

            // 添加未被bandNames包含的列
            List<Component> remainingCols = value.stream()
                    .filter(col -> col instanceof RowColumn)
                    .map(col -> (RowColumn) col)
                    .filter(c -> !bandNames.contains(c.getDataIndex()))
                    .map(c -> (Component) c) // 转回Component类型
                    .collect(Collectors.toList());
            cols.addAll(remainingCols);

            // 如需替换_columns，取消下面注释
            // _columns = cols;
        }
    }

    @JsonInclude(JsonInclude.Include.NON_NULL)
    public List<Component> CardColumns;

    @JsonInclude(JsonInclude.Include.NON_NULL)
    public Object MobileCards;

    @JsonInclude(JsonInclude.Include.NON_NULL)
    public Object data;


    private DataStore _store;

    @JsonInclude(JsonInclude.Include.NON_NULL)
    public DataStore getStore() {
        if (getColumns() != null && !getColumns().isEmpty()) {
            if (_store == null) {
                _store = new DataStore();
            }
            if (_store.fields == null) {
                _store.fields = (getColumns().stream()
                        .filter(col -> col instanceof RowColumn)
                        .map(col -> ((RowColumn) col).getStoreField())
                        .toArray(Object[]::new));
            }
        }
        return _store;
    }

    public void setStore(DataStore store) {
        this._store = store;
    }

    @JsonInclude(JsonInclude.Include.NON_NULL)
    public Object RightMenu;

    public int SHeight;

    public String IdField;

    @JsonInclude(JsonInclude.Include.NON_NULL)
    public String displayField;

    @JsonInclude(JsonInclude.Include.NON_NULL)
    public Object TbarItems;

    @JsonInclude(JsonInclude.Include.NON_NULL)
    public List<Object> BbarItems;

    @JsonInclude(JsonInclude.Include.NON_NULL)
    public Object DefaultSearchBoxData;

    @JsonInclude(JsonInclude.Include.NON_NULL)
    @JsonProperty("Calc")
    public Object getCalc() {
        if (getColumns() != null && !getColumns().isEmpty()) {
            Map<String, String> calcDict = new HashMap<>();
            getColumns().stream()
                    .filter(col -> col instanceof RowColumn && ((RowColumn) col).getCalcExpr() != null && !((RowColumn) col).getCalcExpr().isEmpty())
                    .sorted(Comparator.comparingInt(col -> ((RowColumn) col).getCalcOrder()))
                    .map(col -> (RowColumn) col)
                    .forEach(col -> {
                        if (!calcDict.containsKey(col.getFieldName())) {
                            calcDict.put(col.getFieldName(), col.getCalcExpr());
                        }
                    });
            return calcDict;
        }
        return null;
    }

    protected Boolean isSum() {
        if (getColumns() != null && !getColumns().isEmpty()) {
            return getColumns().stream()
                    .anyMatch(col -> col instanceof RowColumn && ((RowColumn) col).isIsSum());
        }
        return false;
    }

    @JsonInclude(JsonInclude.Include.NON_NULL)
    public Object ChartCfg;

    @JsonInclude(JsonInclude.Include.NON_NULL)
    public Boolean NoGridLine = null;

    private Boolean _hideColumnHeader;

    @JsonInclude(JsonInclude.Include.NON_NULL)
    public Boolean getHideColumnHeader() {
        return _hideColumnHeader != null && _hideColumnHeader ? true : null;
    }

    public void setHideColumnHeader(Boolean hideColumnHeader) {
        this._hideColumnHeader = hideColumnHeader;
    }

    private Boolean _rowNumberer = null;

    @JsonInclude(JsonInclude.Include.NON_NULL)
    public Boolean getRowNumberer() {
        return _rowNumberer != null && !_rowNumberer ? false : null;
    }

    public void setRowNumberer(Boolean rowNumberer) {
        this._rowNumberer = rowNumberer;
    }

    public Integer displayRows;

}