import { AnalyticsSink, AnalyticsEvent } from '../analytics/index.js';

interface PostHogHttpSinkOptions {
    /** PostHog project API key (the public, write-only key). */
    apiKey: string;
    /**
     * Ingestion host. Default `https://us.i.posthog.com`. Use
     * `https://eu.i.posthog.com`, a self-hosted host, or — recommended for
     * production — your own reverse-proxy/relay path.
     */
    host?: string;
    /** Sink name. Default `posthog`. */
    name?: string;
    /** Consent categories this sink requires. Default `['analytics']`. */
    consentCategories?: string[];
    /** Max retries for 429/5xx (exponential backoff). Default 3. */
    maxRetries?: number;
    /** Base backoff delay in ms. Default 500. */
    backoffBaseMs?: number;
    /** Injected fetch (defaults to global fetch). */
    fetchImpl?: typeof fetch;
    /** Injected sendBeacon (defaults to navigator.sendBeacon). */
    beaconImpl?: (url: string, body: string) => boolean;
    /** Soft per-batch byte cap. PostHog limit ≈ 20MB; default 1MB. */
    maxBatchBytes?: number;
    /** Soft per-event byte cap. Default 32KB. */
    maxEventBytes?: number;
}
/**
 * Create the PostHog `http`-mode sink (default). Pure protocol adapter —
 * no `posthog-js`, safe in Node and the browser.
 */
declare function createPostHogHttpSink(options: PostHogHttpSinkOptions): AnalyticsSink;

/**
 * PostHog `client-sdk` sink — OPTIONAL, opt-in mode.
 *
 * For client-exclusive PostHog features (autocapture, feature flags,
 * surveys, web experiments) that the protocol API alone cannot drive.
 * `posthog-js` is loaded **lazily via dynamic `import()`** the first time the
 * sink delivers, so a consumer who only uses the default `http` sink never
 * pays the browser-library cost and `posthog-js` stays a fully optional peer.
 *
 * Session replay is deliberately NOT touched here — it lives in the separate
 * `@refraction-ui/analytics-sink-posthog/replay` module so it is never on the
 * event path and tree-shakes out unless explicitly enabled.
 */
/** Minimal structural type for the bits of `posthog-js` we use. */
interface PostHogJs {
    init(apiKey: string, options: Record<string, unknown>): void;
    capture(event: string, properties?: Record<string, unknown>): void;
    identify(distinctId: string, set?: Record<string, unknown>): void;
    alias(alias: string, original?: string): void;
    group(groupType: string, groupKey: string, properties?: Record<string, unknown>): void;
    reset(): void;
}
interface PostHogClientSdkSinkOptions {
    /** PostHog project API key. */
    apiKey: string;
    /** PostHog API host. Default `https://us.i.posthog.com`. */
    host?: string;
    /** Sink name. Default `posthog`. */
    name?: string;
    /** Consent categories this sink requires. Default `['analytics']`. */
    consentCategories?: string[];
    /**
     * Extra `posthog-js` init options. `autocapture`, `capture_pageview`, and
     * `session_recording` default to OFF — the canonical router owns the event
     * path; replay is opt-in via the separate module.
     */
    posthogOptions?: Record<string, unknown>;
    /**
     * Injected loader (testing / custom bundling). Defaults to a lazy
     * `import('posthog-js')`.
     */
    loadPostHog?: () => Promise<{
        default: PostHogJs;
    } | PostHogJs>;
}
/**
 * Create the OPTIONAL PostHog `client-sdk`-mode sink. `posthog-js` is
 * dynamically imported on first use, never at module load.
 */
declare function createPostHogClientSdkSink(options: PostHogClientSdkSinkOptions): AnalyticsSink;

/** PostHog fan-out mode. `http` is the default (no browser library). */
type PostHogSinkMode = 'http' | 'client-sdk';
type PostHogSinkOptions = ({
    mode?: 'http';
} & PostHogHttpSinkOptions) | ({
    mode: 'client-sdk';
} & PostHogClientSdkSinkOptions);
/**
 * Create a PostHog `AnalyticsSink`.
 *
 * - `mode: 'http'` (DEFAULT) — pure protocol adapter against PostHog's
 *   `/capture` + `/batch` API. No `posthog-js`. Server-relay friendly.
 * - `mode: 'client-sdk'` — OPTIONAL. Lazily dynamic-imports `posthog-js`
 *   for client-exclusive features. Only loaded if this mode is selected.
 *
 * Session replay is NOT configurable here — import the separate
 * `@refraction-ui/analytics-sink-posthog/replay` module to opt in. It is
 * never on the event path and tree-shakes away when unused.
 */
declare function createPostHogSink(options: PostHogSinkOptions): AnalyticsSink;

/**
 * Canonical envelope → PostHog event mapping.
 *
 * This module is pure (no I/O, no transport) so the http sink and the
 * client-sdk sink share exactly one mapping definition and it can be unit
 * tested in isolation against a mock transport.
 *
 * PostHog identity model:
 *   - `distinct_id` is the single id PostHog buckets a person under.
 *   - Before `identify`, the anonymous visitor is keyed by `anonymousId`.
 *   - `identify` upgrades the person to the opaque app `userId`, sending
 *     `$set` traits and an `$anon_distinct_id` so PostHog stitches the
 *     pre-identify anonymous history onto the identified person.
 *   - `alias` emits PostHog's `$create_alias` linking `previousId` (alias)
 *     to the canonical `userId`/`anonymousId` (distinct_id).
 *   - `group` emits a `$groupidentify` event with `$group_set` traits.
 *
 * See https://posthog.com/docs/api/capture for the event shape.
 */
/** A single PostHog capture event (the `/capture` and `/batch` item shape). */
interface PostHogEvent {
    /** PostHog event name (Segment names map to `$pageview`/`$screen`/etc.). */
    event: string;
    /** The person bucket id. */
    distinct_id: string;
    /** Event + person/group properties. */
    properties: Record<string, unknown>;
    /** ISO-8601 client timestamp (PostHog corrects for skew server-side). */
    timestamp: string;
    /** Idempotency key — PostHog dedupes on this. Mirrors `messageId`. */
    uuid: string;
}
/** Resolve the PostHog `distinct_id` for an envelope. */
declare function distinctId(ev: AnalyticsEvent): string;
/**
 * Map one canonical envelope to one PostHog event.
 *
 * `track`    → the event name verbatim, `properties` passed through.
 * `page`     → `$pageview` (PostHog's built-in pageview).
 * `screen`   → `$screen` with `$screen_name`.
 * `identify` → `$identify` with `$set` traits + `$anon_distinct_id` stitch.
 * `group`    → `$groupidentify` with `$group_set` traits.
 * `alias`    → `$create_alias` linking `previousId` → distinct id.
 */
declare function toPostHogEvent(ev: AnalyticsEvent): PostHogEvent;
/** Map a batch of canonical envelopes to PostHog events. */
declare function toPostHogBatch(batch: AnalyticsEvent[]): PostHogEvent[];

export { type PostHogClientSdkSinkOptions, type PostHogEvent, type PostHogHttpSinkOptions, type PostHogSinkMode, type PostHogSinkOptions, createPostHogClientSdkSink, createPostHogHttpSink, createPostHogSink, distinctId, toPostHogBatch, toPostHogEvent };
