import { asClass, asFunction, asValue, type AwilixContainer } from 'awilix';
import { Browser } from '@stock-bot/browser';
import { ProxyManager } from '@stock-bot/proxy';
import { NamespacedCache } from '@stock-bot/cache';
import type { AppConfig } from '../config/schemas';
import type { ServiceDefinitions } from '../container/types';

export function registerApplicationServices(
  container: AwilixContainer<ServiceDefinitions>,
  config: AppConfig
): void {
  // Browser
  if (config.browser) {
    container.register({
      browser: asClass(Browser)
        .singleton()
        .inject(() => ({
          options: {
            headless: config.browser!.headless,
            timeout: config.browser!.timeout,
          },
        })),
    });
  } else {
    container.register({
      browser: asValue(null as any), // Required field
    });
  }

  // Proxy Manager
  if (config.proxy && config.redis.enabled) {
    container.register({
      proxyManager: asFunction(({ cache, logger }) => {
        if (!cache) {return null;}
        
        const proxyCache = new NamespacedCache(cache, 'proxy');
        const proxyManager = new ProxyManager(proxyCache, config.proxy, logger);
        
        // Note: Initialization will be handled by the lifecycle manager
        return proxyManager;
      }).singleton(),
    });
  } else {
    container.register({
      proxyManager: asValue(null),
    });
  }

  // Queue Manager
  if (config.queue?.enabled && config.redis.enabled) {
    container.register({
      queueManager: asFunction(({ logger }) => {
        const { SmartQueueManager } = require('@stock-bot/queue');
        const queueConfig = {
          serviceName: config.service?.serviceName || config.service?.name || 'unknown',
          redis: {
            host: config.redis.host,
            port: config.redis.port,
            password: config.redis.password,
            db: config.redis.db,
          },
          defaultQueueOptions: {
            workers: config.queue!.workers || 1,
            concurrency: config.queue!.concurrency || 1,
            defaultJobOptions: config.queue!.defaultJobOptions,
          },
          enableScheduledJobs: config.queue!.enableScheduledJobs ?? true,
          delayWorkerStart: config.queue!.delayWorkerStart ?? false,
          autoDiscoverHandlers: true,
        };
        return new SmartQueueManager(queueConfig, logger);
      }).singleton(),
    });
  } else {
    container.register({
      queueManager: asValue(null),
    });
  }
}