import { Id64String } from "@itwin/core-bentley";
import { GenericInstanceFilter } from "@itwin/core-common";
import { ECClassHierarchyInspector, ECSchemaProvider, IInstanceLabelSelectClauseFactory } from "@itwin/presentation-shared";
import { HierarchyNodeAutoExpandProp } from "./IModelHierarchyNode.js";
/**
 * Column names of the SELECT clause created by `NodeSelectClauseFactory`. Order of the names matches the order of columns
 * created by the factory.
 *
 * @public
 */
export declare enum NodeSelectClauseColumnNames {
    /** Full class name of the instance the node represents. Type: `string` in format `{schema name}:{class name}`. */
    FullClassName = "FullClassName",
    /** ECInstance ID of the instance the node represents. Type: `Id64String`. */
    ECInstanceId = "ECInstanceId",
    /** Display label. Type: `string`. */
    DisplayLabel = "DisplayLabel",
    /**
     * A flag indicating if the node has children. Type: `boolean`. Values:
     * - `false` - node never has children.
     * - `true` - node always has children.
     * - NULL - unknown, needs to be determined by requesting children for the node.
     */
    HasChildren = "HasChildren",
    /** A flag indicating that a node should be hidden if it has no children. Type: `boolean`. */
    HideIfNoChildren = "HideIfNoChildren",
    /** A flag indicating that a node should be hidden and its children should be displayed instead. Type: `boolean`. */
    HideNodeInHierarchy = "HideNodeInHierarchy",
    /** A serialized JSON object for providing grouping information. */
    Grouping = "Grouping",
    /** A serialized JSON object for associating a node with additional data. */
    ExtendedData = "ExtendedData",
    /** A flag indicating the node should be auto-expanded when it's loaded. */
    AutoExpand = "AutoExpand",
    /** A flag indicating the node supports child hierarchy level filtering. */
    SupportsFiltering = "SupportsFiltering"
}
/**
 * A data structure for defining an ECSQL value selector.
 * @public
 */
interface ECSqlValueSelector {
    selector: string;
}
/**
 * Props for `NodeSelectClauseFactory.createSelectClause`.
 * @public
 */
interface NodeSelectClauseProps {
    ecClassId: ECSqlValueSelector;
    ecInstanceId: ECSqlValueSelector;
    nodeLabel: string | ECSqlValueSelector;
    extendedData?: {
        [key: string]: Id64String | string | number | boolean | ECSqlValueSelector;
    };
    autoExpand?: boolean | ECSqlValueSelector;
    supportsFiltering?: boolean | ECSqlValueSelector;
    hasChildren?: boolean | ECSqlValueSelector;
    hideNodeInHierarchy?: boolean | ECSqlValueSelector;
    hideIfNoChildren?: boolean | ECSqlValueSelector;
    grouping?: ECSqlSelectClauseGroupingParams;
}
/**
 * A data structure for defining nodes' grouping requirements.
 * @public
 */
interface ECSqlSelectClauseGroupingParams {
    byLabel?: ECSqlSelectClauseLabelGroupingParams;
    byClass?: boolean | ECSqlSelectClauseGroupingParamsBase | ECSqlValueSelector;
    byBaseClasses?: ECSqlSelectClauseBaseClassGroupingParams;
    byProperties?: ECSqlSelectClausePropertiesGroupingParams;
}
/**
 * A data structure for defining label grouping params.
 * @public
 */
interface ECSqlSelectClauseLabelGroupingBaseParams {
    /** Label grouping option that determines whether to group nodes or to merge them. Defaults to "group".*/
    action?: "group" | "merge";
    /** Id that needs to match for nodes to be grouped or merged.*/
    groupId?: string | ECSqlValueSelector;
}
/**
 * A data structure for defining label merging.
 * @public
 */
interface ECSqlSelectClauseLabelGroupingMergeParams extends ECSqlSelectClauseLabelGroupingBaseParams {
    action: "merge";
}
/**
 * A data structure for defining label grouping.
 * @public
 */
interface ECSqlSelectClauseLabelGroupingGroupParams extends ECSqlSelectClauseLabelGroupingBaseParams, ECSqlSelectClauseGroupingParamsBase {
    action?: "group";
}
/**
 * A data structure for defining possible label grouping types.
 * @public
 */
type ECSqlSelectClauseLabelGroupingParams = boolean | ECSqlValueSelector | ECSqlSelectClauseLabelGroupingMergeParams | ECSqlSelectClauseLabelGroupingGroupParams;
/**
 * A data structure for defining base grouping parameters shared across all types of grouping.
 * @public
 */
interface ECSqlSelectClauseGroupingParamsBase {
    hideIfNoSiblings?: boolean | ECSqlValueSelector;
    hideIfOneGroupedNode?: boolean | ECSqlValueSelector;
    autoExpand?: HierarchyNodeAutoExpandProp | ECSqlValueSelector;
}
/**
 * A data structure for defining properties grouping.
 * @public
 */
interface ECSqlSelectClausePropertiesGroupingParams extends ECSqlSelectClauseGroupingParamsBase {
    /**
     * Full name of a class whose properties are used to group the node. Only has effect if the node
     * represents an instance of that class.
     *
     * Full class name format: `SchemaName.ClassName`.
     */
    propertiesClassName: string;
    /**
     * Property grouping option that determines whether to group nodes whose grouping value is not set or is set to an empty string.
     *
     * Label of the created grouping node will be `Not Specified`.
     */
    createGroupForUnspecifiedValues?: boolean | ECSqlValueSelector;
    /**
     * Property grouping option that determines whether to group nodes whose grouping value doesn't fit within any of the provided
     * ranges, or is not a numeric value.
     *
     * Label of the created grouping node will be `Other`.
     */
    createGroupForOutOfRangeValues?: boolean | ECSqlValueSelector;
    /**
     * Properties of the specified class, by which the nodes should be grouped.
     *
     * Example usage:
     * ```ts
     * propertyGroups: [
     *   {
     *     propertyName: "type",
     *     propertyClassAlias: "this"
     *   },
     *   {
     *     propertyName: "length",
     *     propertyClassAlias: "x",
     *     ranges: [
     *       { fromValue: 1, toValue: 10, rangeLabel: "Small" },
     *       { fromValue: 11, toValue: 20, rangeLabel: "Medium" }
     *     ]
     *   },
     * ]
     * ```
     */
    propertyGroups: ECSqlSelectClausePropertyGroup[];
}
/**
 * A data structure for defining specific properties' grouping params.
 * @public
 */
interface ECSqlSelectClausePropertyGroup {
    /** A string indicating the name of the property to group by. */
    propertyName: string;
    /** Alias to of the class containing the property. Used to select the property value. */
    propertyClassAlias: string;
    /** Ranges are used to group nodes by numeric properties which are within specified bounds. */
    ranges?: ECSqlSelectClausePropertyValueRange[];
}
/**
 * A data structure for defining boundaries for a value.
 * @public
 */
interface ECSqlSelectClausePropertyValueRange {
    /** Defines the lower bound of the range. */
    fromValue: number | ECSqlValueSelector;
    /** Defines the upper bound of the range. */
    toValue: number | ECSqlValueSelector;
    /** Defines the range label. Will be used as grouping node's display label. */
    rangeLabel?: string | ECSqlValueSelector;
}
/**
 * A data structure for defining base class grouping.
 * @public
 */
interface ECSqlSelectClauseBaseClassGroupingParams extends ECSqlSelectClauseGroupingParamsBase {
    fullClassNames: string[] | ECSqlValueSelector[];
}
/**
 * An interface of a factory that knows how to create nodes' select ECSQL query.
 * @public
 */
export interface NodesQueryClauseFactory {
    /** Create a SELECT clause in a format understood by nodes query parser used by `HierarchyProvider`. */
    createSelectClause(props: NodeSelectClauseProps): Promise<string>;
    /**
     * Creates the necessary ECSQL snippets to create an instance filter described by the given `GenericInstanceFilter` argument.
     * - `from` is set to either the `contentClass.fullName` or one of `filter.propertyClassNames`, depending on which is more specific.
     * - `joins` is set to a number of `JOIN` clauses required to join all relationships described by `filter.relatedInstances`.
     * - `where` is set to a `WHERE` clause (without the `WHERE` keyword) that filters instances by classes on
     * `filter.filterClassNames` and by properties as described by `filter.rules`.
     *
     * Special cases:
     * - If `filter` is `undefined`, `joins` and `where` are set to empty strings and `from` is set to `contentClass.fullName`.
     * - If the provided content class doesn't intersect with the property class in provided filter, a special result
     * is returned to make sure the resulting query is valid and doesn't return anything.
     */
    createFilterClauses(props: {
        contentClass: {
            fullName: string;
            alias: string;
        };
        filter: GenericInstanceFilter | undefined;
    }): Promise<{
        from: string;
        where: string;
        joins: string;
    }>;
}
/**
 * Creates an instance of `NodeSelectQueryFactory`.
 * @public
 */
export declare function createNodesQueryClauseFactory(props: {
    imodelAccess: ECSchemaProvider & ECClassHierarchyInspector;
    instanceLabelSelectClauseFactory: IInstanceLabelSelectClauseFactory;
}): NodesQueryClauseFactory;
export {};
//# sourceMappingURL=NodeSelectQueryFactory.d.ts.map