import { default as default_2 } from 'react';
import { Edge } from 'reactflow';
import { Field } from 'react-querybuilder';
import { JSX as JSX_2 } from 'react/jsx-runtime';
import { Node as Node_2 } from 'reactflow';
import { OnEdgesChange } from 'reactflow';
import { OnNodesChange } from 'reactflow';
import { OnNodesDelete } from 'reactflow';
import { ReactNode } from 'react';

export declare type AggregationFunctions = "SUM" | "COUNT" | "AVG" | "MAX" | "MIN";

export declare type AggregationNodeData = NodeData<NodeTypes.AGGREGATION>;

export declare interface BaseNodeData {
    id: string;
    name: string;
    label: string;
    type: NodeTypes;
}

export declare type DataType = "string" | "boolean" | "integer" | "float" | "datetime";

export declare const DraggableNode: React.FC<DraggableNodeProps>;

declare interface DraggableNodeProps {
    type: NodeTypes;
    label: string;
    children: React.ReactNode;
}

export declare interface DragItem {
    id: string;
    type: NodeTypes;
    name: string;
}

declare type GraphUpdateListener = () => void;

export declare type GroupByNodeData = NodeData<NodeTypes.GROUP_BY>;

export declare type HavingNodeData = NodeData<NodeTypes.HAVING>;

export declare type JoinNodeData = NodeData<NodeTypes.JOIN>;

export declare enum JoinTypes {
    INNER_JOIN = "INNER JOIN",
    LEFT_JOIN = "LEFT JOIN",
    RIGHT_JOIN = "RIGHT JOIN",
    FULL_JOIN = "FULL JOIN"
}

export declare type LimitNodeData = NodeData<NodeTypes.LIMIT>;

export declare interface NodeData<T extends NodeTypes = NodeTypes> extends BaseNodeData {
    type: T;
}

export declare enum NodeTypes {
    SELECT = "select",
    WHERE = "where",
    JOIN = "join",
    GROUP_BY = "group_by",
    ORDER_BY = "order_by",
    HAVING = "having",
    FIELD_ALIAS = "field_alias",
    TABLE_ALIAS = "table_alias",
    AGGREGATION = "aggregation",
    DISTINCT = "distinct",
    LIMIT = "limit",
    OFFSET = "offset"
}

export declare type Nullable<T> = {
    [P in keyof T]: T[P] | null;
};

export declare type OffsetNodeData = NodeData<NodeTypes.OFFSET>;

export declare type OrderByNodeData = NodeData<NodeTypes.ORDER_BY>;

declare class QueryGraph {
    private tables;
    private nodes;
    private edges;
    private listeners;
    private query;
    constructor(nodes: Array<Node_2<NodeData>>, edges: Array<Edge>);
    getTables(nodeId: string): Array<TableWithType>;
    addTable(nodeId: string, newTable: TableWithType): void;
    removeTable(nodeId: string): void;
    getNodes(): Array<Node_2<NodeData>>;
    setNodes(nodes: Array<Node_2<NodeData>>): void;
    getEdges(): Array<Edge>;
    setEdges(edges: Array<Edge>): void;
    subscribe(listener: GraphUpdateListener): void;
    unsubscribe(listener: GraphUpdateListener): void;
    isNodeConnected(nodeId: string): boolean;
    private notifyListeners;
    processSqlQuery(nodeType: SqlNode, queryString: string | number, nodeId?: string): void;
    getSqlQuery(): string;
    getFieldData(fieldName: string): TableField | null;
}

export declare type SelectNodeData = NodeData<NodeTypes.SELECT>;

export declare type SqlNode = "select" | "join" | "where" | "groupBy" | "having" | "orderBy" | "limit" | "offset";

export declare const SqlNodeToolBar: default_2.FC<SqlNodeToolBarProps>;

declare interface SqlNodeToolBarProps {
    variant: "horizontal" | "vertical";
}

export declare interface SqlQuery {
    select: string;
    join: Map<string, string>;
    where: string;
    groupBy: string;
    having: string;
    orderBy: string;
    limit: number;
    offset: number;
}

export declare const SQLQueryBuilder: () => JSX_2.Element;

declare interface SQLQueryBuilderContextType {
    tables: Array<Table>;
    nodes: Array<Node_2<NodeData>>;
    edges: Array<Edge>;
    setEdges: default_2.Dispatch<default_2.SetStateAction<Array<Edge>>>;
    handleEdgeChanges: OnEdgesChange;
    addNode: (newNode: Node_2<NodeData>) => void;
    removeNode: (nodeId: string) => void;
    onNodesChange: OnNodesChange;
    handleNodeChange: OnNodesChange;
    handleNodeDelete: OnNodesDelete;
    queryGraph: QueryGraph;
}

export declare const SQLQueryBuilderProvider: default_2.FC<SQLQueryBuilderProviderProps>;

declare interface SQLQueryBuilderProviderProps {
    children: ReactNode;
    tables?: Array<Table>;
    nodes?: Array<Node_2<NodeData>>;
    edges?: Array<Edge>;
}

export declare type Table = {
    name: string;
    label: string;
    fields: TableField[];
    alias?: string;
};

export declare type TableField = Field & {
    name: string;
    value: string;
    label: string;
    dataType: DataType;
    isDistinct: boolean;
    alias?: string;
    aggregation?: AggregationFunctions | null;
};

export declare type TableWithType = Table & {
    type: NodeTypes;
};

export declare const useSQLQueryBuilderContext: () => SQLQueryBuilderContextType;

export declare type WhereNodeData = NodeData<NodeTypes.WHERE>;

export { }
