/**
 * Calendar context for timezone-aware date operations.
 * Controls how dates are interpreted, grouped, and displayed.
 */
declare type CalendarContext = {
    /**
     * IANA timezone identifier.
     * @example 'America/Chicago', 'Europe/London', 'Asia/Tokyo', 'UTC'
     * @see https://en.wikipedia.org/wiki/List_of_tz_database_time_zones
     */
    tz: string;
    /**
     * Day the week starts on.
     * 0 = Sunday (US, Canada, Japan)
     * 1 = Monday (ISO standard, most of Europe)
     * 6 = Saturday (Middle East)
     * @default 1 (Monday) for backward compatibility
     */
    weekStart: WeekStart;
    /**
     * Date anchor for relative date calculations.
     * - 'now': Use current time (default, live dashboards)
     * - { iso: string }: Fixed ISO 8601 date for reproducible views
     */
    anchor: 'now' | {
        iso: string;
    };
};

export declare function normalizeSemaphorAnalysisQueryOptions(value: unknown, options?: {
    pathPrefix?: string;
    validateTimezone?: SemaphorAnalysisTimezoneValidator;
}): SemaphorAnalysisQueryOptionsValidationResult;

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

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 SemaphorAnalysisDriverMode = 'absolute_delta' | 'largest_negative' | 'largest_positive' | 'positive_and_negative' | 'all';

declare type SemaphorAnalysisQueryDefinition = SemaphorAnalysisQuerySpec & {
    queryKind: 'analysis';
};

export declare type SemaphorAnalysisQueryOptions = {
    chartTitle?: string;
    chartType?: string;
    driverMode?: SemaphorAnalysisDriverMode;
    includePopulation?: boolean;
    calendarContext?: CalendarContext;
};

export declare type SemaphorAnalysisQueryOptionsValidationIssue = {
    code: 'invalid_analysis_option';
    message: string;
    path: string;
};

export declare type SemaphorAnalysisQueryOptionsValidationResult = {
    ok: true;
    analysisOptions?: SemaphorAnalysisQueryOptions;
} | {
    ok: false;
    issues: SemaphorAnalysisQueryOptionsValidationIssue[];
};

declare type SemaphorAnalysisQuerySpec = SemaphorMetricQuerySpec & SemaphorAnalysisQueryOptions & {
    analysis?: SemaphorMetricIntent['analysis'];
    timeWindow?: SemaphorMetricIntent['timeWindow'];
    filters?: SemaphorAnalyticsFilter[];
};

export declare type SemaphorAnalysisTimezoneValidator = (tz: string) => string | null;

declare type SemaphorAnalyticsExecutionResult = {
    intentId?: string;
    queryId?: string;
    status: SemaphorAnalyticsExecutionStatus;
    resultShape?: SemaphorAnalyticsResult['kind'] | 'period_change';
    intent?: SemaphorAnalyticsIntent;
    compiledQuery?: SemaphorCompiledQuery;
    fieldsUsed?: SemaphorExecutionFieldRef[];
    result?: SemaphorAnalyticsResult;
    validation: SemaphorAnalyticsValidationResult;
    coverage?: {
        answeredObligations: string[];
        missingObligations: string[];
        warnings?: SemaphorAnalyticsValidationIssue[];
    };
    missingFields?: string[];
    warnings?: string[];
    relationshipDiagnostics?: SemaphorRelationshipDiagnostics;
    population?: SemaphorAnalyticsPopulation;
    metadata?: Record<string, unknown>;
};

declare type SemaphorAnalyticsExecutionStatus = 'answered' | 'partial' | 'failed';

declare type SemaphorAnalyticsFieldRole = 'metric' | 'dateField' | 'dimension' | 'input' | 'source' | 'sql';

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 SemaphorAnalyticsPopulation = {
    scope: 'filtered_query';
    metrics: Record<string, number | string | null>;
};

declare type SemaphorAnalyticsRepairHint = {
    code: SemaphorAnalyticsValidationCode | string;
    message?: string;
    invalidField?: string;
    fieldRole?: SemaphorAnalyticsFieldRole;
    validMetricCandidates?: string[];
    validDateCandidates?: string[];
    validDimensionCandidates?: string[];
    recommendedNextStep: string;
};

declare type SemaphorAnalyticsResult = SemaphorMetricResult | SemaphorRecordsResult | SemaphorInputOptionsResult | SemaphorSqlResult;

declare type SemaphorAnalyticsResultBase = {
    intentId?: string;
    queryPath: SemaphorQueryPath;
    warnings?: string[];
    rowCount?: number;
    rowLimitExceeded?: boolean;
    limit?: number;
    pagination?: SemaphorPaginationMetadata;
};

declare type SemaphorAnalyticsValidationCode = 'missing_source' | 'invalid_source_kind' | 'missing_semantic_domain' | 'missing_dataset_name' | 'missing_connection_id' | 'missing_table_name' | 'missing_sql' | 'missing_metric' | 'missing_record_fields' | 'missing_input_options_field' | 'invalid_metric' | 'invalid_metric_list' | 'invalid_date_field' | 'invalid_dimension' | 'invalid_metric_dimensions' | 'conflicting_sql' | 'sql_policy_violation' | 'unsupported_intent_for_adapter' | 'invalid_analytics_kind' | 'invalid_analytics_intent';

declare type SemaphorAnalyticsValidationIssue = SemaphorProtocolIssue & {
    code: SemaphorAnalyticsValidationCode | string;
    fieldRole?: SemaphorAnalyticsFieldRole;
    repairHint?: SemaphorAnalyticsRepairHint;
};

declare type SemaphorAnalyticsValidationResult = {
    ok: boolean;
    errors: SemaphorAnalyticsValidationIssue[];
    warnings: SemaphorAnalyticsValidationIssue[];
    repairHints: SemaphorAnalyticsRepairHint[];
};

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

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

declare type SemaphorCompiledQuery = {
    kind: 'config';
    queryId: string;
    source: SemaphorSourceRef;
    cardType: string;
    connectionId: string;
    cardConfig: unknown;
    cardDataSource: unknown;
    activeFilters?: SemaphorAnalyticsFilter[];
    rowLimit: number;
    analyticsIntent?: SemaphorAnalyticsIntent;
} | {
    kind: 'sql';
    queryId: string;
    source: Extract<SemaphorSourceRef, {
        kind: 'sql';
    }>;
    connectionId: string;
    dialect: SemaphorDialect;
    sql: string;
    parameters?: Record<string, unknown>;
    pythonCode?: string;
    activeFilters?: SemaphorAnalyticsFilter[];
    rowLimit: number;
    analyticsIntent?: SemaphorAnalyticsIntent;
};

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

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

export declare type SemaphorDataAppFieldCatalog = {
    source: SemaphorSourceRef;
    sourceAliases?: SemaphorSourceRef[];
    fields: SemaphorFieldRef[];
};

export declare type SemaphorDataAppQuerySpecEnvelope = {
    queryHook: 'useSemaphorQuery';
    spec: SemaphorQueryDefinition;
};

export declare type SemaphorDataAppQueryValidation = {
    queryHook: SemaphorDataAppQuerySpecEnvelope['queryHook'];
    queryId?: string;
    intent?: SemaphorAnalyticsIntent;
    diagnostics: SemaphorDataAppValidationDiagnostic[];
    executionResult: SemaphorAnalyticsExecutionResult;
};

export declare type SemaphorDataAppValidationDiagnostic = {
    severity: 'error' | 'warning';
    code: 'invalid_query_spec' | 'invalid_analytics_intent' | 'invalid_source_ref' | 'missing_field' | 'unsupported_input_filter_composition' | string;
    message: string;
    path?: string;
    queryHook?: SemaphorDataAppQuerySpecEnvelope['queryHook'];
    queryId?: string;
    intentId?: string;
    source?: SemaphorSourceRef;
    field?: SemaphorFieldRef;
};

export declare type SemaphorDataAppValidationResult = {
    ok: boolean;
    diagnostics: SemaphorDataAppValidationDiagnostic[];
    queries: SemaphorDataAppQueryValidation[];
    intents: SemaphorAnalyticsIntent[];
    executionResults: SemaphorAnalyticsExecutionResult[];
};

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

declare type SemaphorExecutionFieldRef = SemaphorFieldRef & {
    semanticAggregate?: SemaphorAggregateFunction;
    effectiveAggregate?: SemaphorAggregateFunction;
    aggregateSource?: SemaphorMetricAggregateSource;
};

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

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

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

declare type SemaphorInputBinding = {
    inputId: string;
    kind?: 'filter' | 'control';
    controlRole?: 'grain' | 'metric' | 'dimension' | 'aggregation' | 'sqlParam';
    operator?: SemaphorInputOperator;
    field?: SemaphorFieldRef;
};

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' | 'not_contains' | 'between' | 'not_between' | '>' | '>=' | '<' | '<=';

declare type SemaphorInputOperatorAlias = 'eq' | 'equals' | 'not_equals' | 'neq' | 'not equal' | 'not equals' | 'not in' | 'like' | 'not_contains' | 'not contains' | 'not_like' | 'not like' | 'not_between' | 'not between';

declare type SemaphorInputOperatorInput = SemaphorInputOperator | SemaphorInputOperatorAlias;

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;
};

declare type SemaphorInputOptionsQueryDefinition = SemaphorInputOptionsQuerySpec & {
    queryKind: 'inputOptions';
};

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

declare type SemaphorInputOptionsResult = SemaphorAnalyticsResultBase & {
    kind: 'inputOptions';
    options: Array<{
        label: string;
        value: unknown;
        count?: number;
    }>;
};

declare type SemaphorInputReference = SemaphorInputSpec | SemaphorInputBinding | SemaphorActiveInput | SemaphorInputHandle;

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

declare type SemaphorInputValue = SemaphorScalar | SemaphorScalar[];

declare type SemaphorMetricAggregateSource = 'semantic_model' | 'caller_override' | 'default_sum';

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

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;
};

declare type SemaphorMetricQueryDefinition = SemaphorMetricQuerySpec & {
    queryKind: 'metric';
};

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;
};

declare type SemaphorMetricResult = SemaphorAnalyticsResultBase & {
    kind: 'metric';
    value: number | string | null;
    comparison?: {
        kind: NonNullable<SemaphorMetricIntent['comparison']>['kind'];
        value?: number | string | null;
        delta?: number | null;
        deltaPercent?: number | null;
    };
};

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

declare type SemaphorOptionValue = string | number | boolean;

declare type SemaphorPaginationMetadata = {
    page: number;
    pageSize: number;
    pageCount: number;
    totalCount: number;
    hasNextPage: boolean;
    hasPrevPage: boolean;
};

declare type SemaphorPaginationRequest = {
    page: number;
    pageSize: number;
};

declare type SemaphorProtocolIssue = {
    code: string;
    message: string;
    path?: string;
};

declare type SemaphorProtocolVersion = 1;

declare type SemaphorQueryDefinition = SemaphorMetricQueryDefinition | SemaphorAnalysisQueryDefinition | SemaphorRecordsQueryDefinition | SemaphorInputOptionsQueryDefinition | SemaphorSqlQueryDefinition;

declare type SemaphorQueryField = SemaphorFieldRef;

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

declare type SemaphorQueryPath = 'query_spec' | 'sql' | 'sql_python';

declare type SemaphorQuerySourceSpec = {
    source: SemaphorSourceRef;
};

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

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;
    timeWindow?: SemaphorTimeWindow;
    filters?: SemaphorAnalyticsFilter[];
    limit?: number;
    pagination?: SemaphorPaginationRequest;
    orderBy?: {
        field: SemaphorFieldRef;
        direction: 'asc' | 'desc';
    };
    inputs?: SemaphorInputBinding[];
};

declare type SemaphorRecordsOrderBy = SemaphorQueryOrderBy;

declare type SemaphorRecordsQueryDefinition = SemaphorRecordsQuerySpec & {
    queryKind: 'records';
};

declare type SemaphorRecordsQuerySpec = SemaphorRecordsBaseQuerySpec & SemaphorRecordsSelectorSpec;

declare type SemaphorRecordsResult = SemaphorAnalyticsResultBase & {
    kind: 'records';
    columns: SemaphorResultColumn[];
    records: Array<Record<string, unknown>>;
};

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

declare type SemaphorRelationshipDiagnostics = {
    status: SemaphorRelationshipDiagnosticStatus;
    requiredSources?: SemaphorSourceRef[];
    relationshipsUsed?: string[];
    missingSources?: string[];
    warnings?: string[];
    message?: string;
    recommendedNextStep?: string;
    joinPlanSummary?: {
        baseSource?: SemaphorSourceRef;
        joinedSources?: SemaphorSourceRef[];
        joinCount?: number;
    };
    fanoutRisk?: {
        status: 'none' | 'warning' | 'error' | 'unknown';
        message?: string;
    };
};

declare type SemaphorRelationshipDiagnosticStatus = 'not_required' | 'resolved' | 'missing' | 'ambiguous' | 'fanout_risk' | 'unknown';

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';
};

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'];
};

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;
    defaultParameters?: Record<string, unknown>;
    pythonCode?: string;
    limit?: number;
    pagination?: SemaphorPaginationRequest;
    rationale?: string;
    fields?: SemaphorFieldRef[];
    inputs?: SemaphorInputBinding[];
};

declare type SemaphorSqlParameterValue = SemaphorScalar | SemaphorScalar[];

declare type SemaphorSqlQueryDefinition = SemaphorSqlQuerySpec & {
    queryKind: 'sql';
};

declare type SemaphorSqlQuerySpec = SemaphorSqlSourceSpec & {
    id?: string;
    label?: string;
    sql: string;
    defaultParameters?: Record<string, SemaphorSqlParameterValue>;
    pythonCode?: string;
    fields?: SemaphorFieldRef[];
    inputs?: SemaphorInputReference[];
    limit?: number;
    pagination?: SemaphorPaginationRequest;
    rationale?: string;
};

declare type SemaphorSqlResult = SemaphorAnalyticsResultBase & {
    kind: 'sql';
    columns: SemaphorRecordsResult['columns'];
    records: SemaphorRecordsResult['records'];
    sqlShape?: {
        statementType?: string;
        explicitLimit?: number;
        hasPythonCode?: boolean;
    };
};

declare type SemaphorSqlSourceSpec = {
    source: Extract<SemaphorSourceRef, {
        kind: 'sql';
    }>;
};

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

declare type SemaphorTimeWindow = SemaphorRelativeTimeWindow | SemaphorAbsoluteTimeWindow;

export declare function validateSemaphorDataAppQuerySpecs(input: {
    queries: SemaphorDataAppQuerySpecEnvelope[];
    fieldCatalogs?: SemaphorDataAppFieldCatalog[];
    requireFieldCatalog?: boolean;
    validateTimezone?: SemaphorAnalysisTimezoneValidator;
}): SemaphorDataAppValidationResult;

/**
 * Week start day type.
 * 0 = Sunday (US, Canada, Japan)
 * 1 = Monday (ISO standard, most of Europe)
 * 6 = Saturday (Middle East)
 */
declare type WeekStart = 0 | 1 | 2 | 3 | 4 | 5 | 6;

export { }
