import * as React from 'react';
import { Telemetry, TelemetryConfig, LogContext, Logger, Span } from '../logger/index.js';
export { LogContext, LogLevel, LogRecord, Logger, Span, SpanRecord, Telemetry, TelemetryConfig, TelemetryEnv, TelemetrySink, createConsoleSink, createFaroSink, createTelemetry } from '../logger/index.js';

interface TelemetryContextValue {
    /** The root telemetry instance (a logger bound to the empty root context). */
    telemetry: Telemetry;
}
interface TelemetryProviderProps extends TelemetryConfig {
    children: React.ReactNode;
}
/**
 * TelemetryProvider — wraps your app with telemetry context.
 *
 * ```tsx
 * <TelemetryProvider app="interview-service" env="production">
 *   <App />
 * </TelemetryProvider>
 * ```
 */
declare function TelemetryProvider({ children, ...config }: TelemetryProviderProps): React.FunctionComponentElement<React.ProviderProps<TelemetryContextValue | null>>;
/**
 * useTelemetry — access the root telemetry instance.
 *
 * If called outside a <TelemetryProvider> it does NOT throw: it returns a
 * shared no-op telemetry (a dev-only warn-once hint is emitted so the missing
 * provider is discoverable). This lets components instrumented with
 * useLogger/useSpan/useTelemetry render safely without a provider.
 */
declare function useTelemetry(): Telemetry;
/**
 * useLogger — derive a scoped child logger with bound context (e.g.
 * `{ sessionId, interviewId, turnId }`). The logger is memoized so it stays
 * stable across renders for the same scope. With no scope, the root telemetry
 * logger is returned.
 *
 * Must be used within <TelemetryProvider>.
 */
declare function useLogger(scope?: LogContext): Logger;

interface UseSpanAPI {
    /**
     * Begin a span tied to the provider's telemetry instance. Returns the
     * {@link Span}; call {@link Span.end} (or {@link UseSpanAPI.end}) to record
     * its duration. Starting a new span while one is active ends the previous
     * one first so a single hook owns at most one in-flight span.
     */
    start: (name: string, attributes?: LogContext) => Span;
    /** End the active span (no-op if none is in flight). Idempotent per span. */
    end: (opts?: {
        error?: unknown;
        attributes?: LogContext;
    }) => void;
    /** Whether a span started by this hook is currently in flight. */
    isActive: boolean;
}
/**
 * useSpan — start/end a telemetry span tied to the provider's telemetry
 * instance. The active span is cleaned up automatically on unmount.
 *
 * ```tsx
 * const span = useSpan()
 * useEffect(() => {
 *   span.start('llm-call', { model: 'gpt' })
 *   return () => span.end()
 * }, [])
 * ```
 *
 * Must be used within <TelemetryProvider>.
 */
declare function useSpan(): UseSpanAPI;

interface TelemetryErrorBoundaryProps {
    children: React.ReactNode;
    /**
     * Fallback UI rendered after an error is caught. May be a node or a render
     * function receiving the captured error and a reset callback.
     */
    fallback?: React.ReactNode | ((error: Error, reset: () => void) => React.ReactNode);
    /** Extra bound context attached to the reported error record. */
    context?: LogContext;
    /** Invoked after the error has been reported to the telemetry sink. */
    onError?: (error: Error, info: React.ErrorInfo) => void;
}
interface TelemetryErrorBoundaryState {
    error: Error | null;
}
/**
 * TelemetryErrorBoundary — a React error boundary that reports caught render
 * errors to the provider's telemetry sink (at `error` level) before showing
 * an optional fallback.
 *
 * ```tsx
 * <TelemetryErrorBoundary fallback={<p>Something broke.</p>}>
 *   <App />
 * </TelemetryErrorBoundary>
 * ```
 *
 * Must be used within <TelemetryProvider>.
 */
declare class TelemetryErrorBoundary extends React.Component<TelemetryErrorBoundaryProps, TelemetryErrorBoundaryState> {
    static contextType: React.Context<TelemetryContextValue | null>;
    context: TelemetryContextValue | null;
    state: TelemetryErrorBoundaryState;
    static getDerivedStateFromError(error: Error): TelemetryErrorBoundaryState;
    componentDidCatch(error: Error, info: React.ErrorInfo): void;
    reset: () => void;
    render(): React.ReactNode;
}

export { type TelemetryContextValue, TelemetryErrorBoundary, type TelemetryErrorBoundaryProps, TelemetryProvider, type TelemetryProviderProps, type UseSpanAPI, useLogger, useSpan, useTelemetry };
