/**
 * Core types for @bytelyst/diagnostics-client
 *
 * @module types
 */

/**
 * Log severity levels (matches syslog/OpenTelemetry)
 */
export type LogLevel = 'debug' | 'info' | 'warn' | 'error' | 'fatal';

/**
 * Session status from the server
 */
export type SessionStatus = 'pending' | 'active' | 'paused' | 'completed' | 'cancelled';

/**
 * Collection level determines verbosity of captured data
 */
export type CollectionLevel = 'standard' | 'debug' | 'trace';

/**
 * Diagnostic session configuration from server
 */
export interface DiagnosticsSession {
  /** Session ID */
  id: string;
  /** Product identifier */
  productId: string;
  /** Current session status */
  status: SessionStatus;
  /** Collection verbosity level */
  collectionLevel: CollectionLevel;
  /** Whether to capture logs */
  captureLogs: boolean;
  /** Whether to capture network traces */
  captureNetwork: boolean;
  /** Whether to capture screenshots */
  captureScreenshots: boolean;
  /** Auto-capture screenshot on error */
  screenshotOnError: boolean;
  /** Maximum session duration in minutes */
  maxDurationMinutes: number;
  /** Session creation time */
  createdAt: string;
  /** Session expiry time */
  expiresAt: string;
}

/**
 * OpenTelemetry-compatible trace span
 */
export interface TraceSpan {
  /** Unique span ID */
  spanId: string;
  /** Parent span ID (null for root) */
  parentId?: string;
  /** Operation name */
  name: string;
  /** Span kind */
  kind?: 'internal' | 'server' | 'client' | 'producer' | 'consumer';
  /** Start time (ISO 8601) */
  startTime: string;
  /** End time (ISO 8601) */
  endTime?: string;
  /** Duration in milliseconds */
  durationMs?: number;
  /** Custom attributes */
  attributes: Record<string, unknown>;
  /** Status */
  status: 'ok' | 'error' | 'unset';
  /** Error message if status=error */
  statusMessage?: string;
  /** Nested events within this span */
  events?: Array<{
    name: string;
    timestamp: string;
    attributes?: Record<string, unknown>;
  }>;
}

/**
 * Structured log entry
 */
export interface LogEntry {
  /** Log level */
  level: LogLevel;
  /** Log message (PII redacted server-side) */
  message: string;
  /** Timestamp (ISO 8601) */
  timestamp: string;
  /** Module/component name */
  module: string;
  /** Source file path */
  file?: string;
  /** Line number */
  line?: number;
  /** Function name */
  function?: string;
  /** Additional context */
  context: Record<string, unknown>;
  /** Correlation ID for related operations */
  correlationId?: string;
}

/**
 * Breadcrumb for timeline navigation
 */
export interface Breadcrumb {
  /** Timestamp */
  timestamp: string;
  /** Category (e.g., 'navigation', 'user', 'error') */
  category: string;
  /** Message */
  message: string;
  /** Associated data */
  data?: Record<string, unknown>;
}

/**
 * Network request/response capture
 */
export interface NetworkRequest {
  /** Unique request ID */
  id: string;
  /** URL */
  url: string;
  /** HTTP method */
  method: string;
  /** Request headers (sanitized) */
  requestHeaders: Record<string, string>;
  /** Request body (if captured) */
  requestBody?: string;
  /** Response status */
  status?: number;
  /** Response headers */
  responseHeaders?: Record<string, string>;
  /** Response body (if captured) */
  responseBody?: string;
  /** Start timestamp */
  startTime: string;
  /** End timestamp */
  endTime?: string;
  /** Duration in milliseconds */
  durationMs?: number;
  /** Error if request failed */
  error?: string;
}

/**
 * Device state snapshot
 */
export interface DeviceState {
  /** Memory usage in MB */
  memoryMB?: number;
  /** Battery level (0-1) */
  batteryLevel?: number;
  /** Is battery charging */
  isCharging?: boolean;
  /** Available storage in MB */
  storageMB?: number;
  /** Network type (wifi, cellular, offline) */
  networkType?: string;
  /** Is device online */
  isOnline: boolean;
  /** Thermal state (nominal, fair, serious, critical) */
  thermalState?: 'nominal' | 'fair' | 'serious' | 'critical';
}

/**
 * Client configuration options
 */
export interface DiagnosticsConfig {
  /** Product ID */
  productId: string;
  /** User ID (if authenticated) */
  userId?: string;
  /** Anonymous install ID */
  anonymousInstallId: string;
  /** Platform name */
  platform: string;
  /** Platform channel */
  channel: string;
  /** OS family */
  osFamily: string;
  /** App version */
  appVersion: string;
  /** Build number */
  buildNumber: string;
  /** Release channel */
  releaseChannel: string;
  /** Server base URL */
  serverUrl: string;
  /** Auth token provider */
  getAuthToken?: () => string | Promise<string>;
  /** Polling interval in ms (default: 5000) */
  pollIntervalMs?: number;
  /** Max breadcrumbs to keep (default: 100) */
  maxBreadcrumbs?: number;
  /** Auto-capture console logs */
  captureConsole?: boolean;
  /** Auto-capture uncaught errors */
  captureErrors?: boolean;
  /** Auto-capture network requests */
  captureNetwork?: boolean;
  /** URL patterns to exclude from network capture */
  networkExcludePatterns?: RegExp[];
}

/**
 * Client state
 */
export type ClientState =
  | { type: 'idle' }
  | { type: 'polling'; session: DiagnosticsSession | null }
  | { type: 'active'; session: DiagnosticsSession }
  | { type: 'error'; error: Error };

/**
 * Ingest batch for sending to server
 */
export interface IngestBatch {
  /** Session ID */
  sessionId: string;
  /** Traces to ingest */
  traces?: TraceSpan[];
  /** Logs to ingest */
  logs?: LogEntry[];
  /** Breadcrumbs to ingest */
  breadcrumbs?: Breadcrumb[];
  /** Network requests to ingest */
  network?: NetworkRequest[];
}
