import { asClass, asFunction, asValue, type AwilixContainer } from 'awilix';
import { Browser } from '@stock-bot/browser';
import { ProxyManager } from '@stock-bot/proxy';
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(({ logger }) => {
        // Create a separate cache instance for proxy with global prefix
        const { createCache } = require('@stock-bot/cache');
        const proxyCache = createCache({
          redisConfig: {
            host: config.redis.host,
            port: config.redis.port,
            password: config.redis.password,
            db: 1, // Use cache DB (usually DB 1)
          },
          keyPrefix: 'cache:proxy:',
          ttl: 86400, // 24 hours default
          enableMetrics: true,
          logger,
        });

        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, handlerRegistry }) => {
        const { QueueManager } = 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,
          autoDiscoverHandlers: true,
        };
        return new QueueManager(queueConfig, handlerRegistry, logger);
      }).singleton(),
    });
  } else {
    container.register({
      queueManager: asValue(null),
    });
  }
}
