import { Context } from 'react';
import { JSX } from 'react/jsx-runtime';
import { ReactNode } from 'react';

export declare function createSemaphorQueryExecutor(): SemaphorQueryExecutor;

export declare function hasSemaphorInputValue(value: unknown): boolean;

export declare function normalizeSemaphorInputOptions(options?: Array<{
    label: string;
    value: SemaphorOptionValue;
} | SemaphorOptionValue>): {
    label: string;
    value: SemaphorOptionValue;
}[];

export declare function readWindowRuntime(): SemaphorDataAppWindowRuntime | undefined;

declare type SemaphorAbsoluteTimeWindow = {
    kind: 'absolute';
    start: string;
    end: string;
};

export declare type SemaphorActiveInput<TValue extends SemaphorInputValue = SemaphorInputValue> = SemaphorInputBinding & {
    kind: 'filter' | 'control';
    label?: string;
    value?: TValue;
    isActive: boolean;
    operator?: SemaphorInputOperator;
    controlRole?: SemaphorControlRole;
};

declare type SemaphorAggregateFunction = 'SUM' | 'COUNT' | 'AVG' | 'MIN' | 'MAX' | 'MEDIAN' | 'DISTINCT';

declare type SemaphorAnalyticsFilter = SemaphorAnalyticsValueFilter | SemaphorAnalyticsNullFilter;

declare type SemaphorAnalyticsFilterBase = {
    id?: string;
    field: SemaphorFieldRef;
    /**
     * Controls where the filter is applied in an aggregate query.
     *
     * `row` means pre-aggregation filtering (`WHERE`).
     * `aggregate` means post-aggregation filtering (`HAVING`) and is valid only
     * for measure fields the execution engine can aggregate safely.
     */
    scope?: 'row' | 'aggregate';
};

declare type SemaphorAnalyticsFilterOperator = SemaphorInputOperator | 'not_contains' | 'is_null' | 'is_not_null';

declare type SemaphorAnalyticsIntent = SemaphorMetricIntent | SemaphorRecordsIntent | SemaphorInputOptionsIntent | SemaphorSqlIntent;

declare type SemaphorAnalyticsNullFilter = SemaphorAnalyticsFilterBase & {
    operator: SemaphorAnalyticsNullFilterOperator;
    values?: never;
};

declare type SemaphorAnalyticsNullFilterOperator = 'is_null' | 'is_not_null';

declare type SemaphorAnalyticsValueFilter = SemaphorAnalyticsFilterBase & {
    operator?: SemaphorAnalyticsValueFilterOperator;
    values: unknown[];
};

declare type SemaphorAnalyticsValueFilterOperator = Exclude<SemaphorAnalyticsFilterOperator, 'is_null' | 'is_not_null'>;

export declare type SemaphorControlInputSpec<TValue extends SemaphorInputValue = SemaphorInputValue> = SemaphorInputBase<TValue> & {
    kind: 'control';
    role: SemaphorControlRole;
};

export declare type SemaphorControlRole = 'grain' | 'metric' | 'dimension' | 'aggregation' | 'sqlParam';

export declare const SemaphorDataAppContext: Context<SemaphorDataAppRuntime>;

export declare function SemaphorDataAppProvider({ token, apiBaseUrl, executor, children, }: SemaphorDataAppProviderProps): JSX.Element;

export declare type SemaphorDataAppProviderProps = SemaphorQueryExecutorContext & {
    executor?: SemaphorQueryExecutor;
    children: ReactNode;
};

export declare type SemaphorDataAppRuntime = SemaphorQueryExecutorContext & {
    executor?: SemaphorQueryExecutor;
};

declare type SemaphorDataAppWindowRuntime = {
    apiBaseUrl?: string;
    dataApiBaseUrl?: string;
    authToken?: null | {
        accessToken?: string;
    };
};

declare type SemaphorDialect = 'postgres' | 'mysql' | 'mssql' | 'snowflake' | 'clickhouse' | 'bigquery' | 'redshift' | 'duckdb' | 'sqlite' | 'unknown';

declare type SemaphorFieldRef = {
    name: string;
    label?: string;
    role?: 'dimension' | 'measure' | 'date' | 'id' | 'unknown';
    dataType?: 'string' | 'number' | 'boolean' | 'date' | 'datetime' | 'unknown';
    source?: SemaphorSourceRef;
    aggregate?: SemaphorAggregateFunction;
};

export declare type SemaphorFilterInputSpec<TValue extends SemaphorInputValue = SemaphorInputValue> = SemaphorInputBase<TValue> & {
    kind: 'filter';
    field: SemaphorQueryField;
    operator?: SemaphorInputOperator;
    multi?: boolean;
};

declare type SemaphorInputBase<TValue extends SemaphorInputValue> = {
    id: string;
    label?: string;
    value?: TValue;
    defaultValue?: TValue;
    onValueChange?: (value: TValue | undefined) => void;
    options?: Array<SemaphorInputOption | SemaphorOptionValue>;
};

declare type SemaphorInputBinding = {
    inputId: string;
    field?: SemaphorFieldRef;
};

export declare type SemaphorInputHandle<TValue extends SemaphorInputValue = SemaphorInputValue> = {
    id: string;
    kind: 'filter' | 'control';
    label?: string;
    field?: SemaphorFieldRef;
    operator?: SemaphorInputOperator;
    controlRole?: SemaphorControlRole;
    value: TValue | undefined;
    options: SemaphorInputOption[];
    isActive: boolean;
    setValue(value: TValue | undefined): void;
    clear(): void;
    toAnalyticsInput(): SemaphorActiveInput<TValue>;
};

declare type SemaphorInputOperator = '=' | '!=' | 'in' | 'not_in' | 'contains' | 'between' | 'not_between' | '>' | '>=' | '<' | '<=';

export declare type SemaphorInputOption = {
    label: string;
    value: SemaphorOptionValue;
    count?: number;
};

declare type SemaphorInputOptionsIntent = {
    kind: 'inputOptions';
    version?: SemaphorProtocolVersion;
    id?: string;
    label?: string;
    source: SemaphorSourceRef;
    field: SemaphorFieldRef;
    search?: string;
    limit?: number;
};

export declare type SemaphorInputOptionsPayload = {
    options: SemaphorInputOption[];
};

export declare type SemaphorInputOptionsQueryResult = SemaphorQueryState & SemaphorInputOptionsPayload & {
    id?: string;
    intent?: Extract<SemaphorAnalyticsIntent, {
        kind: 'inputOptions';
    }>;
};

export declare type SemaphorInputOptionsQuerySpec = SemaphorQuerySourceSpec & {
    id?: string;
    label?: string;
    field: SemaphorQueryField;
    search?: string;
    limit?: number;
};

export declare type SemaphorInputReference = SemaphorInputBinding | SemaphorActiveInput | SemaphorInputHandle;

export declare type SemaphorInputSpec<TValue extends SemaphorInputValue = SemaphorInputValue> = SemaphorFilterInputSpec<TValue> | SemaphorControlInputSpec<TValue>;

export declare type SemaphorInputValue = SemaphorScalar | SemaphorScalar[];

declare type SemaphorMetricAnalysis = {
    kind: 'period_change';
    orderBy?: 'absolute_change' | 'positive_change' | 'negative_change' | 'period';
    direction?: 'increase' | 'decrease' | 'both';
    timeWindow?: SemaphorTimeWindow;
};

export declare type SemaphorMetricComparison = {
    kind: 'previous_period' | 'previous_year' | 'target';
    targetValue?: number;
};

declare type SemaphorMetricIntent = {
    kind: 'metric';
    version?: SemaphorProtocolVersion;
    id?: string;
    source: SemaphorSourceRef;
    metrics: SemaphorFieldRef[];
    primaryMetric?: SemaphorFieldRef;
    label?: string;
    dateField?: SemaphorFieldRef;
    timeGrain?: SemaphorTimeGrain;
    timeWindow?: SemaphorTimeWindow;
    dimensions?: SemaphorFieldRef[];
    filters?: SemaphorAnalyticsFilter[];
    comparison?: {
        kind: 'previous_period' | 'previous_year' | 'target';
        targetValue?: number;
    };
    analysis?: SemaphorMetricAnalysis;
    orderBy?: {
        field: SemaphorFieldRef;
        direction: 'asc' | 'desc';
    };
    inputs?: SemaphorInputBinding[];
    limit?: number;
};

export declare type SemaphorMetricPayload = {
    value: number | string | null;
    metrics?: Record<string, number | string | null>;
    comparisonValue?: number | string | null;
    delta?: number | null;
    deltaPercent?: number | null;
    records?: Array<Record<string, unknown>>;
};

export declare type SemaphorMetricQueryResult = SemaphorQueryState & SemaphorMetricPayload & {
    id?: string;
    intent?: SemaphorMetricIntent;
};

export declare type SemaphorMetricQuerySpec = SemaphorQuerySourceSpec & {
    id?: string;
    label?: string;
    metrics: SemaphorNonEmptyArray<SemaphorQueryField>;
    primaryMetric?: SemaphorQueryField;
    dateField?: SemaphorQueryField;
    timeGrain?: SemaphorTimeGrain;
    dimensions?: SemaphorQueryField[];
    comparison?: SemaphorMetricComparison;
    orderBy?: SemaphorQueryOrderBy;
    inputs?: SemaphorInputReference[];
    limit?: number;
};

export declare type SemaphorNonEmptyArray<T> = [T, ...T[]];

export declare type SemaphorOptionValue = string | number | boolean;

declare type SemaphorProtocolVersion = 1;

export declare type SemaphorQueryExecutor = {
    executeMetric(intent: SemaphorMetricIntent, context: SemaphorQueryExecutorContext): Promise<SemaphorMetricPayload>;
    executeRecords<TRecord extends Record<string, unknown> = Record<string, unknown>>(intent: SemaphorRecordsIntent, context: SemaphorQueryExecutorContext): Promise<SemaphorRecordsPayload<TRecord>>;
    executeInputOptions(intent: Extract<SemaphorAnalyticsIntent, {
        kind: 'inputOptions';
    }>, context: SemaphorQueryExecutorContext): Promise<SemaphorInputOptionsPayload>;
};

export declare type SemaphorQueryExecutorContext = {
    token?: string;
    apiBaseUrl?: string;
    activeInputs?: SemaphorActiveInput[];
};

export declare type SemaphorQueryField = SemaphorFieldRef;

export declare type SemaphorQueryOrderBy = {
    field: SemaphorQueryField;
    direction: 'asc' | 'desc';
};

export declare type SemaphorQuerySourceSpec = {
    source: SemaphorSourceRef;
};

export declare type SemaphorQueryState = {
    status: SemaphorQueryStatus;
    isLoading: boolean;
    error: Error | null;
};

export declare type SemaphorQueryStatus = 'idle' | 'loading' | 'success' | 'error';

declare type SemaphorRecordsBaseQuerySpec = SemaphorQuerySourceSpec & {
    id?: string;
    label?: string;
    dateField?: SemaphorQueryField;
    timeGrain?: SemaphorTimeGrain;
    orderBy?: SemaphorRecordsOrderBy;
    inputs?: SemaphorInputReference[];
    limit?: number;
};

export declare type SemaphorRecordsField = SemaphorFieldRef & {
    role: NonNullable<SemaphorFieldRef['role']>;
};

declare type SemaphorRecordsIntent = {
    kind: 'records';
    version?: SemaphorProtocolVersion;
    source: SemaphorSourceRef;
    id?: string;
    label?: string;
    fields: SemaphorFieldRef[];
    dateField?: SemaphorFieldRef;
    timeGrain?: SemaphorTimeGrain;
    limit?: number;
    orderBy?: {
        field: SemaphorFieldRef;
        direction: 'asc' | 'desc';
    };
    inputs?: SemaphorInputBinding[];
};

export declare type SemaphorRecordsOrderBy = SemaphorQueryOrderBy;

export declare type SemaphorRecordsPayload<TRecord extends Record<string, unknown> = Record<string, unknown>> = {
    records: TRecord[];
    columns?: SemaphorResultColumn[];
    rowCount?: number;
};

export declare type SemaphorRecordsQueryResult<TRecord extends Record<string, unknown> = Record<string, unknown>> = SemaphorQueryState & SemaphorRecordsPayload<TRecord> & {
    id?: string;
    intent?: SemaphorRecordsIntent;
};

export declare type SemaphorRecordsQuerySpec = SemaphorRecordsBaseQuerySpec & SemaphorRecordsSelectorSpec;

declare type SemaphorRecordsSelectorSpec = {
    fields: SemaphorNonEmptyArray<SemaphorRecordsField>;
};

declare type SemaphorRelativeTimeWindow = {
    kind?: 'relative';
    unit: 'second' | 'minute' | 'hour' | 'day' | 'week' | 'month' | 'quarter' | 'year';
    value: number;
    anchor?: 'now' | 'latest_available';
    completeness?: 'include_partial' | 'complete_periods';
};

export declare type SemaphorResultColumn = {
    /**
     * Stable row accessor for this result. Consumers should read values with
     * `row[column.key]`; labels are display-only and may change.
     */
    key: string;
    /**
     * Semantic/source field name before result-key disambiguation.
     */
    name: string;
    /**
     * Human-facing display label.
     */
    label: string;
    role?: SemaphorFieldRef['role'];
    dataType?: SemaphorFieldRef['dataType'];
    aggregate?: SemaphorFieldRef['aggregate'];
    source?: SemaphorFieldRef['source'];
};

export declare type SemaphorScalar = string | number | boolean | null;

declare type SemaphorSourceRef = {
    kind: 'semantic';
    domainId: string;
    datasetName: string;
    datasetId?: string;
    label?: string;
    connectionId?: string;
} | {
    kind: 'physical';
    connectionId: string;
    connectionType?: string;
    tableName: string;
    databaseName?: string;
    schemaName?: string;
    label?: string;
    dialect?: SemaphorDialect;
} | {
    kind: 'sql';
    connectionId: string;
    dialect?: SemaphorDialect;
    label?: string;
};

declare type SemaphorSqlIntent = {
    kind: 'sql';
    version?: SemaphorProtocolVersion;
    id?: string;
    label?: string;
    source: Extract<SemaphorSourceRef, {
        kind: 'sql';
    }>;
    sql: string;
    parameters?: Record<string, unknown>;
    pythonCode?: string;
    limit?: number;
    rationale?: string;
    fields?: SemaphorFieldRef[];
    inputs?: SemaphorInputBinding[];
};

declare type SemaphorTimeGrain = 'hour' | 'day' | 'week' | 'month' | 'quarter' | 'year';

declare type SemaphorTimeWindow = SemaphorRelativeTimeWindow | SemaphorAbsoluteTimeWindow;

export declare function toSemaphorActiveInputSnapshots(inputs: SemaphorInputReference[] | undefined): SemaphorActiveInput[];

export declare function toSemaphorInputBinding(input: SemaphorInputReference): SemaphorInputBinding;

export declare function toSemaphorInputBindings(inputs: SemaphorInputReference[] | undefined): SemaphorInputBinding[] | undefined;

export declare function toSemaphorInputOptionsIntent(spec: SemaphorInputOptionsQuerySpec): Extract<SemaphorAnalyticsIntent, {
    kind: 'inputOptions';
}>;

export declare function toSemaphorInputSnapshots(inputs: SemaphorInputReference[] | undefined): SemaphorActiveInput[];

export declare function toSemaphorInputSpec<TValue extends SemaphorInputValue = SemaphorInputValue>(spec: SemaphorInputSpec<TValue>): SemaphorInputBinding & {
    kind: SemaphorInputSpec['kind'];
    label?: string;
    field?: SemaphorFieldRef;
    operator?: SemaphorInputOperator;
};

export declare function toSemaphorMetricIntent(spec: SemaphorMetricQuerySpec): SemaphorMetricIntent;

export declare function toSemaphorRecordsIntent(spec: SemaphorRecordsQuerySpec): SemaphorRecordsIntent;

export declare function useSemaphorDataAppRuntime(): SemaphorDataAppRuntime;

export declare function useSemaphorInput<TValue extends SemaphorInputValue = SemaphorInputValue>(spec: SemaphorInputSpec<TValue>): SemaphorInputHandle;

export declare function useSemaphorInputOptions(spec: SemaphorInputOptionsQuerySpec): SemaphorInputOptionsQueryResult;

export declare function useSemaphorMetric(spec: SemaphorMetricQuerySpec): SemaphorMetricQueryResult;

export declare function useSemaphorRecords<TRecord extends Record<string, unknown> = Record<string, unknown>>(spec: SemaphorRecordsQuerySpec): SemaphorRecordsQueryResult<TRecord>;

export { }
