export type EmbeddingVector = Float32Array;

export interface ChunkMetadata {
  startOffset: number;
  endOffset: number;
  type: 'paragraph' | 'header' | 'code' | 'list' | 'blockquote';
  level?: number; // For headers
  language?: string; // For code blocks
  [key: string]: any; // Allow custom metadata
}

export interface DocumentMetadata {
  title: string;
  lastModified: string; // ISO date string
  size: number; // bytes
  author?: string;
  tags?: string[];
  version?: string;
  language?: string;
  custom?: Record<string, any>;
}

export interface RAGDocument {
  id: string;
  path: string;
  content: string;
  metadata: DocumentMetadata;
  chunks?: RAGChunk[];
  embedding?: EmbeddingVector;
}

export interface RAGChunk {
  id: string;
  documentId: string;
  content: string;
  index: number; // Position in document
  metadata: ChunkMetadata;
  embedding?: EmbeddingVector;
}

export interface RAGSearchQuery {
  query: string;
  limit?: number;
  collection?: string;
  threshold?: number; // Minimum similarity score
  filters?: Record<string, any>;
}

export interface RAGSearchResult {
  chunk: RAGChunk;
  score: number;
  document: {
    id: string;
    path: string;
    title?: string;
  };
  highlights?: Array<{
    start: number;
    end: number;
    text: string;
  }>;
}

export interface RAGCollection {
  name: string;
  description: string;
  documentCount: number;
  chunkCount: number;
  lastUpdated: string; // ISO date string
  metadata?: Record<string, any>;
}

export interface CollectionConfig {
  name: string;
  paths: string[];
  description?: string;
  metadata?: Record<string, any>;
}

export interface RAGConfig {
  enabled: boolean;
  indexPaths: string[];
  chunkSize: number;
  chunkOverlap: number;
  embeddingModel: string;
  collections: Record<string, CollectionConfig>;
  persistencePath?: string;
  autoIndex?: boolean;
  cacheEmbeddings?: boolean;
}

export interface IndexingOptions {
  forceReindex: boolean;
  updateOnly: boolean;
  collection: string;
  onProgress?: (current: number, total: number) => void;
}

export interface RAGStats {
  totalDocuments: number;
  totalChunks: number;
  totalCollections: number;
  indexSize: number; // bytes
  lastIndexed: string; // ISO date string
  collections: Record<string, {
    documentCount: number;
    chunkCount: number;
    sizeBytes: number;
  }>;
}

export interface VectorSearchOptions {
  k: number; // Number of results
  threshold?: number; // Minimum similarity
  includeVectors?: boolean;
}

export interface VectorStore {
  add(vectors: EmbeddingVector[], ids: string[]): Promise<void>;
  search(query: EmbeddingVector, options: VectorSearchOptions): Promise<Array<{ id: string; score: number }>>;
  remove(ids: string[]): Promise<void>;
  save(path: string): Promise<void>;
  load(path: string): Promise<void>;
  clear(): Promise<void>;
  size(): number;
}

export interface VectorStoreStats {
  totalChunks: number;
  totalDocuments: number;
  embeddingDimension: number;
  memoryUsage: number;
}

export interface RAGVectorStore {
  addChunk(chunk: RAGChunk): Promise<void>;
  addChunks(chunks: RAGChunk[]): Promise<void>;
  search(query: string, k: number): Promise<RAGSearchResult[]>;
  searchWithFilters(query: string, k: number, filters: Record<string, any>): Promise<RAGSearchResult[]>;
  removeDocument(documentId: string): Promise<void>;
  clear(): Promise<void>;
  size(): number;
  getStats(): VectorStoreStats;
  save(filePath: string): Promise<void>;
  load(filePath: string): Promise<void>;
}

export interface EmbeddingModel {
  embed(texts: string[]): Promise<EmbeddingVector[]>;
  embedSingle(text: string): Promise<EmbeddingVector>;
  cosineSimilarity(a: EmbeddingVector, b: EmbeddingVector): number;
  dimension: number;
  modelName: string;
}

export interface DocumentProcessor {
  parse(content: string, path: string): Promise<RAGDocument>;
  chunk(document: RAGDocument, chunkSize: number, overlap: number): Promise<RAGChunk[]>;
  extractMetadata(content: string, path: string): Promise<DocumentMetadata>;
}