// createAskFeature.ts
import path from 'path';
import OpenAI from 'openai';

import { Config } from '../config/config'; // wherever your Config.ts lives
import { DbManager } from '../db/db-manager';
import { SHAPES } from '../shapes/shapes';
import { EmbeddingsStore } from '../embeddings/embeddings-store';
import { HybridSearchService } from '../search/hybrid-search-service';
import { AiService } from '../ai/ai-service';
import { AskController } from './ask-controller';

export type AskFeature = {
  askController: AskController;
  warmup: () => Promise<void>;
  shutdown: () => Promise<void>;
};

export const createAskFeature = (): AskFeature => {
  const config = new Config().validate();

  const openai = new OpenAI({ apiKey: config.openAiKey });

  const embDir = path.join(process.cwd(), 'embeddings');
  const embeddingsStore = new EmbeddingsStore(embDir);
  embeddingsStore.startWatching({ debounceMs: 200 });

  const dbManager = new DbManager(config.mongoUri);

  const hybridSearchService = new HybridSearchService({
    dbManager,
    openai,
    embedModel: config.embedModel,
    embeddingsStore,
    shapes: SHAPES,
  });

  const aiService = new AiService({
    openai,
    chatModel: config.chatModel,
    shapes: SHAPES,
  });

  const askController = new AskController({
    hybridSearchService,
    aiService,
    shapes: SHAPES,
    activeCollections: embeddingsStore.getActive(),
  });

  const warmup = async (): Promise<void> => {
    await dbManager.getDb().catch(() => {});
  };

  const shutdown = async (): Promise<void> => {
    embeddingsStore.stopWatching();
    await dbManager.close();
  };

  return { askController, warmup, shutdown };
};
