import { IServiceContainer } from '@stock-bot/di';
import { ModeManager } from './core/ModeManager';
import { MarketDataService } from './services/MarketDataService';
import { ExecutionService } from './services/ExecutionService';
import { AnalyticsService } from './services/AnalyticsService';
import { StorageService } from './services/StorageService';
import { StrategyManager } from './strategies/StrategyManager';
import { BacktestEngine } from './backtest/BacktestEngine';
import { PaperTradingManager } from './paper/PaperTradingManager';

/**
 * Register orchestrator-specific services in the DI container
 */
export async function registerOrchestratorServices(container: any): Promise<void> {
  // Create a service adapter that provides the expected interface
  const services: IServiceContainer = {
    logger: container.cradle.logger,
    cache: container.cradle.cache,
    globalCache: container.cradle.globalCache,
    mongodb: container.cradle.mongoClient,
    postgres: container.cradle.postgresClient,
    questdb: container.cradle.questdbClient,
    browser: container.cradle.browser,
    proxy: container.cradle.proxyManager,
    queueManager: container.cradle.queueManager,
    queue: undefined, // Will be set if needed
    custom: {}
  };
  
  // Create storage service first as it's needed by other services
  const storageService = new StorageService(
    services,
    services.mongodb!,
    services.postgres!,
    services.questdb || null
  );
  
  // Create other services
  const marketDataService = new MarketDataService(services);
  const executionService = new ExecutionService(services, storageService);
  const analyticsService = new AnalyticsService(services, storageService);
  const strategyManager = new StrategyManager(services);
  const backtestEngine = new BacktestEngine(services, storageService, strategyManager);
  const paperTradingManager = new PaperTradingManager(
    services,
    storageService,
    marketDataService,
    executionService
  );
  const modeManager = new ModeManager(
    services,
    marketDataService,
    executionService,
    storageService
  );
  
  // Store custom services
  services.custom = {
    StorageService: storageService,
    MarketDataService: marketDataService,
    ExecutionService: executionService,
    AnalyticsService: analyticsService,
    StrategyManager: strategyManager,
    BacktestEngine: backtestEngine,
    PaperTradingManager: paperTradingManager,
    ModeManager: modeManager
  };
  
  // Register services in the Awilix container for resolution
  container.register({
    StorageService: { value: storageService },
    MarketDataService: { value: marketDataService },
    ExecutionService: { value: executionService },
    AnalyticsService: { value: analyticsService },
    StrategyManager: { value: strategyManager },
    BacktestEngine: { value: backtestEngine },
    PaperTradingManager: { value: paperTradingManager },
    ModeManager: { value: modeManager },
    orchestratorServices: { value: services }
  });
  
  // Update the serviceContainer to include our custom services
  const serviceContainer = container.cradle.serviceContainer;
  if (serviceContainer && serviceContainer.custom) {
    Object.assign(serviceContainer.custom, services.custom);
  }
  
  // Setup event listeners after all services are registered
  strategyManager.setupEventListeners();
  
  // Initialize mode manager with default paper trading mode
  await modeManager.initializeMode({
    mode: 'paper',
    startingCapital: 100000
  });
}

// For backward compatibility, export a container getter
export function getContainer(): IServiceContainer {
  throw new Error('Container should be accessed through ServiceApplication. Update your code to use dependency injection.');
}