import { EventEmitter } from 'events';

// Add explicit Node.js Buffer type
/// <reference types="node" />

// Request types
export interface CompletionsRequestOptions {
  messages: string;
  sessionId?: string;
  userId?: string;
  fileData?: string | Buffer;
  stream?: boolean;
  reasoningFormat?: string;
}

// Response types
export interface CompletionsResponse {
  requestId: string;
  response: string;
  processingTimeMs: number;
}

export interface StreamChunk {
  chunk: string;
  requestId: string;
}

export interface ProcessingError {
  error: string;
  requestId: string;
  code: string;
  processingTimeMs: number;
}

export type NeuraResponse = CompletionsResponse | ProcessingError;

// SDK Configuration
export interface NeuraSDKConfig {
  baseUrl: string;
  apiKey: string;
  maxRetries?: number;
  retryDelay?: number;
  requestsPerMinute?: number;
  enableCache?: boolean;
  cacheTTL?: number; // in milliseconds
}

// Cache types
export interface CacheOptions {
  ttl: number; // Time to live in milliseconds
}

export interface CacheEntry<T> {
  value: T;
  expires: number;
}

export interface CacheInterface {
  get<T>(key: string): T | undefined;
  set<T>(key: string, value: T, options?: Partial<CacheOptions>): void;
  has(key: string): boolean;
  delete(key: string): boolean;
  clear(): void;
}

// Stream events
export interface NeuraStreamEvents {
  chunk: (chunk: StreamChunk) => void;
  done: () => void;
  error: (error: Error | ProcessingError) => void;
}

export interface NeuraStream extends EventEmitter {
  on<E extends keyof NeuraStreamEvents>(event: E, listener: NeuraStreamEvents[E]): this;
  once<E extends keyof NeuraStreamEvents>(event: E, listener: NeuraStreamEvents[E]): this;
  emit<E extends keyof NeuraStreamEvents>(
    event: E,
    ...args: Parameters<NeuraStreamEvents[E]>
  ): boolean;
}