package xyz.wbsite.dbtool.javafx.po;

import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.scene.control.TreeItem;
import xyz.wbsite.dbtool.javafx.annotation.Property;
import xyz.wbsite.dbtool.javafx.manger.ManagerFactory;
import xyz.wbsite.dbtool.javafx.manger.ProjectManager;
import xyz.wbsite.dbtool.javafx.tool.Tool;

import java.util.ArrayList;
import java.util.List;

public class Table extends TreeItem {
    private Module dBhandle;

    public Table() {
    }

    public Table(String tableName) {
        this.tableName = tableName;
        setValue(tableName);
        setExpanded(true);
    }

    public Table(String tableName, String tableComment) {
        this.tableName = tableName;
        this.tableComment = tableComment;
        setValue(tableName);
        setExpanded(true);
    }

    @Property("tableName")
    private String tableName;
    @Property("tableComment")
    private String tableComment;
    @Property("create")
    private boolean create = true;
    @Property("delete")
    private boolean delete = true;
    @Property("update")
    private boolean update = true;
    @Property("find")
    private boolean find = true;
    @Property("get")
    private boolean get = true;
    @Property("search")
    private boolean search = false;
    @Property("sys")
    private boolean sys = true;
    @Property("ajax")
    private boolean ajax = false;
    @Property("html")
    private boolean html = false;
    @Property("api")
    private boolean api = false;

    @Property("methods")
    private List<TableMethod> methods = new ArrayList<>();

    /**
     * 对象字段
     */
    private ObservableList<Field> fields = FXCollections.observableArrayList();

    public boolean has(String type) {
        for (Field field : fields) {
            if (field.getFieldType().equals(type) && !field.getIsSystem()) {
                return true;
            }
        }
        return false;
    }

    public String getImport() {
        StringBuilder sb = new StringBuilder("");
        if (has("Date")) {
            sb.append("import java.util.Date;\n");
        }
        if (has("BigDecimal")) {
            sb.append("import java.math.BigDecimal;\n");
        }

        return sb.toString();
    }

    public boolean putField(Field field) {
        fields.add(field);
        return true;
    }

    public boolean putFirstField(Field field) {
        fields.add(0, field);
        return true;
    }

    public boolean needMgr() {
        return create || delete || update || find || get || search;
    }

    public String getCName() {
        return Tool.ABB2Abb(this.tableName);
    }

    public String getFName() {
        return Tool.lineToFieldName(this.tableName);
    }

    public String getLName() {
        return Tool.lineToLPoint(this.tableName);
    }

    public String getTableName() {
        return tableName;
    }

    public void setTableName(String tableName) {
        this.tableName = tableName;
        setValue(tableName);
    }

    public String getTableComment() {
        return tableComment;
    }

    public void setTableComment(String tableComment) {
        this.tableComment = tableComment != null ? tableComment : "";
    }

    public ObservableList<Field> getFields() {
        return fields;
    }

    public Module getdBhandle() {
        return dBhandle;
    }

    public void setdBhandle(Module dBhandle) {
        this.dBhandle = dBhandle;
    }

    public boolean getCreate() {
        return create;
    }

    public void setCreate(boolean create) {
        this.create = create;
    }

    public boolean getDelete() {
        return delete;
    }

    public void setDelete(boolean delete) {
        this.delete = delete;
    }

    public boolean getUpdate() {
        return update;
    }

    public void setUpdate(boolean update) {
        this.update = update;
    }

    public boolean getFind() {
        return find;
    }

    public void setFind(boolean find) {
        this.find = find;
    }

    public boolean getGet() {
        return get;
    }

    public void setGet(boolean get) {
        this.get = get;
    }

    public boolean getSearch() {
        return search;
    }

    public void setSearch(boolean search) {
        this.search = search;
    }

    public boolean getHtml() {
        return html;
    }

    public void setHtml(boolean html) {
        this.html = html;
    }

    public boolean getSys() {
        return sys;
    }

    public void setSys(boolean sys) {
        this.sys = sys;
        ProjectManager projectManager = ManagerFactory.getProjectManager();
        if (projectManager != null) projectManager.checkSysFields(this);
    }

    public boolean getAjax() {
        return ajax;
    }

    public void setAjax(boolean ajax) {
        this.ajax = ajax;
    }

    public boolean getApi() {
        return api;
    }

    public void setApi(boolean api) {
        this.api = api;
    }

    public boolean hasPrimaryKey() {
        for (Field field : fields) {
            if (field.getIsPrimaryKey()) {
                return true;
            }
        }
        return false;
    }

    public List<Field> primaryKeyList() {
        ArrayList<Field> list = new ArrayList<>();
        for (Field field : this.fields) {
            if (field.getIsPrimaryKey()) {
                list.add(field);
            }
        }
        return list;
    }

    public List<Field> searchKeyList() {
        ArrayList<Field> list = new ArrayList<>();
        for (Field field : this.fields) {
            if (field.getIsSearch()) {
                list.add(field);
            }
        }
        return list;
    }

    public boolean hasSearchKey() {
        for (Field field : fields) {
            if (field.getIsSearch()) {
                return true;
            }
        }
        return false;
    }

    public List<TableMethod> getMethods() {
        return methods;
    }

    public void setMethods(List<TableMethod> methods) {
        this.methods = methods;
    }
}