import { Logger } from './logger.cjs';
import { EventSubscriber, EventAttributes, FunnelStatus, OutcomeStatus, EventAttributesInput } from './event-subscriber.cjs';
import { EventCollector } from './event-testing.cjs';
import 'pino';

/**
 * Events API for product events platforms
 *
 * Track user behavior, business events, and critical actions.
 * Sends to product events platforms (PostHog, Mixpanel, Amplitude) via subscribers.
 * For business people who think in events/funnels.
 *
 * For OpenTelemetry metrics (Prometheus/Grafana), use the Metrics class instead.
 *
 * @example Recommended: Configure subscribers in init(), use track() function
 * ```typescript
 * import { init, track } from 'autotel';
 * import { PostHogSubscriber } from 'autotel-subscribers/posthog';
 *
 * init({
 *   service: 'my-app',
 *   subscribers: [new PostHogSubscriber({ apiKey: 'phc_...' })]
 * });
 *
 * // Track events - uses subscribers from init()
 * track('application.submitted', { jobId: '123', userId: '456' });
 * ```
 *
 * @example Create Event instance (inherits subscribers from init)
 * ```typescript
 * import { Event } from 'autotel/event';
 *
 * // Uses subscribers configured in init()
 * const event = new Event('job-application');
 * event.trackEvent('application.submitted', { jobId: '123' });
 * ```
 *
 * @example Override subscribers for specific Event instance
 * ```typescript
 * import { Event } from 'autotel/event';
 * import { PostHogSubscriber } from 'autotel-subscribers/posthog';
 *
 * // Override: use different subscribers for this instance
 * const event = new Event('job-application', {
 *   subscribers: [new PostHogSubscriber({ apiKey: 'phc_different_project' })]
 * });
 *
 * event.trackEvent('application.submitted', { jobId: '123' });
 * ```
 */

/**
 * Events class for tracking user behavior and product events
 *
 * Track critical indicators such as:
 * - User events (signups, purchases, feature usage)
 * - Conversion funnels (signup → activation → purchase)
 * - Business outcomes (success/failure rates)
 * - Product metrics (revenue, engagement, retention)
 *
 * All events are sent to events platforms via subscribers (PostHog, Mixpanel, etc.).
 * For OpenTelemetry metrics, use the Metrics class instead.
 */
/**
 * Events options
 */
interface EventsOptions {
    /** Optional logger for audit trail */
    logger?: Logger;
    /** Optional collector for testing (captures events in memory) */
    collector?: EventCollector;
    /**
     * Optional subscribers to send events to other platforms
     * (e.g., PostHog, Mixpanel, Amplitude)
     *
     * **Subscriber Resolution**:
     * - If provided → uses these subscribers (instance override)
     * - If not provided → falls back to subscribers from `init()` (global config)
     * - If neither → no subscribers (events logged only)
     *
     * Install `autotel-subscribers` package for ready-made subscribers
     */
    subscribers?: EventSubscriber[];
}
declare class Event {
    private serviceName;
    private logger?;
    private collector?;
    private subscribers;
    private hasSubscribers;
    private circuitBreakers;
    /**
     * Create a new Event instance
     *
     * **Note**: Most users should use `init()` + `track()` instead of creating Event instances directly.
     *
     * **Subscriber Resolution**:
     * - If `subscribers` provided in options → uses those (instance override)
     * - If `subscribers` not provided → falls back to subscribers from `init()` (global config)
     * - If neither → no subscribers (events logged only)
     *
     * @param serviceName - Service name for identifying events
     * @param options - Optional configuration (logger, collector, subscribers)
     *
     * @example Recommended: Use track() with init()
     * ```typescript
     * import { init, track } from 'autotel';
     * import { PostHogSubscriber } from 'autotel-subscribers/posthog';
     *
     * init({
     *   service: 'checkout',
     *   subscribers: [new PostHogSubscriber({ apiKey: 'phc_...' })]
     * });
     *
     * track('purchase.completed', { amount: 99.99 });
     * ```
     *
     * @example Inherit subscribers from init()
     * ```typescript
     * // Uses subscribers configured in init()
     * const event = new Event('checkout');
     * event.trackEvent('purchase.completed', { amount: 99.99 });
     * ```
     *
     * @example Override subscribers for this instance
     * ```typescript
     * import { Event } from 'autotel/event';
     * import { PostHogSubscriber } from 'autotel-subscribers/posthog';
     *
     * // Override: use different subscribers for this instance only
     * const event = new Event('checkout', {
     *   subscribers: [new PostHogSubscriber({ apiKey: 'phc_different_project' })]
     * });
     * ```
     */
    constructor(serviceName: string, options?: EventsOptions);
    /**
     * Automatically enrich attributes with all available telemetry context
     *
     * Auto-captures:
     * - Resource attributes: service.version, deployment.environment
     * - Trace context: traceId, spanId, correlationId
     * - Operation context: operation.name
     */
    private enrichWithTelemetryContext;
    /**
     * Build autotel event context for trace correlation
     *
     * Works in 4 contexts:
     * 1. Inside a span → use current span's trace_id + span_id
     * 2. Outside span but in AsyncLocalStorage context → use trace_id + correlation_id
     * 3. Totally standalone → use correlation_id + service/env/version
     * 4. Batch/fan-in (multiple linked parents) → use count + hash or full array
     *
     * @returns AutotelEventContext or undefined if trace context is disabled
     */
    private buildAutotelContext;
    /**
     * Enrich event attributes from baggage with guardrails
     *
     * @param attributes - Current event attributes
     * @returns Enriched attributes with baggage values
     */
    private enrichFromBaggage;
    /**
     * Check if a baggage key is allowed based on config
     */
    private isBaggageKeyAllowed;
    /**
     * Check if a key matches a baggage pattern
     * Supports exact matches and wildcard patterns (e.g., 'tenant.*')
     */
    private matchesBaggagePattern;
    /**
     * Track a business event
     *
     * Use this for tracking user actions, business events, product usage:
     * - "user.signup"
     * - "order.completed"
     * - "feature.used"
     *
     * Events are sent to configured subscribers (PostHog, Mixpanel, etc.).
     *
     * @example
     * ```typescript
     * // Track user signup
     * events.trackEvent('user.signup', {
     *   userId: '123',
     *   plan: 'pro'
     * })
     *
     * // Track order
     * events.trackEvent('order.completed', {
     *   orderId: 'ord_123',
     *   amount: 99.99
     * })
     * ```
     */
    trackEvent(eventName: string, attributes?: EventAttributes): void;
    /**
     * Notify all subscribers concurrently without blocking
     * Uses circuit breakers to protect against failing subscribers
     * Uses Promise.allSettled to prevent subscriber errors from affecting other subscribers
     */
    private notifySubscribers;
    /**
     * Track conversion funnel steps
     *
     * Monitor where users drop off in multi-step processes.
     *
     * @example
     * ```typescript
     * // Track signup funnel
     * events.trackFunnelStep('signup', 'started', { userId: '123' })
     * events.trackFunnelStep('signup', 'email_verified', { userId: '123' })
     * events.trackFunnelStep('signup', 'completed', { userId: '123' })
     *
     * // Track checkout flow
     * events.trackFunnelStep('checkout', 'started', { cartValue: 99.99 })
     * events.trackFunnelStep('checkout', 'payment_info', { cartValue: 99.99 })
     * events.trackFunnelStep('checkout', 'completed', { cartValue: 99.99 })
     * ```
     */
    trackFunnelStep(funnelName: string, status: FunnelStatus, attributes?: EventAttributes): void;
    /**
     * Track outcomes (success/failure/partial)
     *
     * Monitor success rates of critical operations.
     *
     * @example
     * ```typescript
     * // Track email delivery
     * events.trackOutcome('email.delivery', 'success', {
     *   recipientType: 'user',
     *   emailType: 'welcome'
     * })
     *
     * events.trackOutcome('email.delivery', 'failure', {
     *   recipientType: 'user',
     *   errorCode: 'invalid_email'
     * })
     *
     * // Track payment processing
     * events.trackOutcome('payment.process', 'success', { amount: 99.99 })
     * events.trackOutcome('payment.process', 'failure', { error: 'insufficient_funds' })
     * ```
     */
    trackOutcome(operationName: string, status: OutcomeStatus, attributes?: EventAttributes): void;
    /**
     * Track value metrics
     *
     * Record numerical values like revenue, transaction amounts,
     * item counts, processing times, engagement scores, etc.
     *
     * @example
     * ```typescript
     * // Track revenue
     * events.trackValue('order.revenue', 149.99, {
     *   currency: 'USD',
     *   productCategory: 'electronics'
     * })
     *
     * // Track items per cart
     * events.trackValue('cart.item_count', 5, {
     *   userId: '123'
     * })
     *
     * // Track processing time
     * events.trackValue('api.response_time', 250, {
     *   unit: 'ms',
     *   endpoint: '/api/checkout'
     * })
     * ```
     */
    trackValue(metricName: string, value: number, attributes?: EventAttributes): void;
    /**
     * Flush all subscribers and wait for pending events
     *
     * Call this before shutdown to ensure all events are delivered.
     *
     * @example
     * ```typescript
     * const event =new Event('app', { subscribers: [...] });
     *
     * // Before shutdown
     * await events.flush();
     * ```
     */
    flush(): Promise<void>;
    /**
     * Shutdown the Event instance and all subscribers
     *
     * Unlike `flush()`, this method:
     * - Shuts down all subscribers
     * - Prevents further event tracking (hasSubscribers becomes false)
     * - Should only be called once at application shutdown
     *
     * @example
     * ```typescript
     * // In Next.js API route with after()
     * import { after } from 'next/server';
     *
     * export async function POST(req: Request) {
     *   const event = new Event('checkout', { subscribers: [...] });
     *   event.trackEvent('order.completed', { orderId: '123' });
     *
     *   after(async () => {
     *     await event.shutdown();
     *   });
     *
     *   return Response.json({ success: true });
     * }
     * ```
     */
    shutdown(): Promise<void>;
    /**
     * Track funnel progression with custom step names
     *
     * Unlike trackFunnelStep which uses FunnelStatus enum values,
     * this method allows any string as the step name for flexible funnel tracking.
     *
     * @param funnelName - Name of the funnel (e.g., "checkout", "onboarding")
     * @param stepName - Custom step name (e.g., "cart_viewed", "payment_entered")
     * @param stepNumber - Optional numeric position in the funnel
     * @param attributes - Optional event attributes
     *
     * @example
     * ```typescript
     * // Track custom checkout steps
     * event.trackFunnelProgression('checkout', 'cart_viewed', 1);
     * event.trackFunnelProgression('checkout', 'shipping_selected', 2);
     * event.trackFunnelProgression('checkout', 'payment_entered', 3);
     * event.trackFunnelProgression('checkout', 'order_confirmed', 4);
     * ```
     */
    trackFunnelProgression(funnelName: string, stepName: string, stepNumber?: number, attributes?: EventAttributes): void;
    /**
     * Track multiple events in a batch
     *
     * Useful for bulk event tracking with consistent timestamps.
     * Events are sent to subscribers individually but processed together.
     *
     * @param events - Array of events to track
     *
     * @example
     * ```typescript
     * event.trackBatch([
     *   { name: 'item.viewed', attributes: { itemId: '1' } },
     *   { name: 'item.viewed', attributes: { itemId: '2' } },
     *   { name: 'cart.updated', attributes: { itemCount: 2 } },
     * ]);
     * ```
     */
    trackBatch(events: Array<{
        name: string;
        attributes?: EventAttributesInput;
    }>): void;
}
/**
 * Get or create an Events instance for a service
 *
 * @param serviceName - Service name for identifying events
 * @param logger - Optional logger
 * @returns Events instance
 *
 * @example
 * ```typescript
 * const event =getEvents('job-application')
 * events.trackEvent('application.submitted', { jobId: '123' })
 * ```
 */
declare function getEvents(serviceName: string, logger?: Logger): Event;
/**
 * Reset all events instances (mainly for testing)
 */
declare function resetEvents(): void;

export { Event, EventAttributes, EventAttributesInput, type EventsOptions, FunnelStatus, OutcomeStatus, getEvents, resetEvents };
