/**
 * Types for @bytelyst/feature-flag-client.
 * Browser/React Native-safe — no Node.js dependencies.
 */

// ── Evaluation types ────────────────────────────────────────────────────────

export interface EvaluationContext {
  userId?: string;
  platform?: string;
  region?: string;
  osVersion?: string;
  appVersion?: string;
  email?: string;
  custom?: Record<string, string | number | boolean>;
}

export interface EvaluationResult {
  key: string;
  value: boolean | string | number | Record<string, unknown>;
  variationKey: string;
  reason: string;
}

// ── Config ──────────────────────────────────────────────────────────────────

export interface FeatureFlagClientConfig {
  /** Platform-service base URL (e.g. "http://localhost:4003/api"). */
  baseUrl: string;

  /** Product identifier sent as x-product-id header. */
  productId: string;

  /** Platform string for the poll query (e.g. "mobile", "web"). */
  platform: string;

  /** Poll interval in milliseconds. Default: 5 minutes. */
  pollIntervalMs?: number;

  /** Optional persistent storage adapter for flag cache. */
  storage?: {
    getItem(key: string): string | null;
    setItem(key: string, value: string): void;
  };

  /** Optional storage key prefix. Default: productId. */
  storagePrefix?: string;

  /** Use SSE for real-time updates instead of polling. Default: false. */
  useStreaming?: boolean;

  /** Auth token getter for authenticated requests. */
  getAccessToken?: () => string | null;
}

// ── Client interface ────────────────────────────────────────────────────────

export interface FeatureFlagClient {
  /** Initialize the client: fetch flags immediately and start polling/streaming. */
  init(params?: { userId?: string }): Promise<void>;

  /** Check if a boolean feature flag is enabled. Returns false if not found. */
  isEnabled(key: string): boolean;

  /** Get the resolved value of a multi-variate flag. Returns defaultValue if not found. */
  getValue<T = boolean | string | number | Record<string, unknown>>(
    key: string,
    defaultValue: T
  ): T;

  /** Get the full evaluation result for a flag. Returns undefined if not found. */
  getEvaluation(key: string): EvaluationResult | undefined;

  /** Get all currently cached boolean flags (legacy format). */
  getAllFlags(): Readonly<Record<string, boolean>>;

  /** Get all evaluation results (multi-variate format). */
  getAllEvaluations(): Readonly<Record<string, EvaluationResult>>;

  /** Force a refresh of feature flags. */
  refresh(): Promise<void>;

  /** Register a listener for flag changes. Returns unsubscribe function. */
  onChange(listener: (flagKey: string) => void): () => void;

  /** Stop polling/streaming and reset state. */
  stop(): void;
}
