import { asFunction, asValue, type AwilixContainer } from 'awilix';
import { MongoDBClient } from '@stock-bot/mongodb';
import { PostgreSQLClient } from '@stock-bot/postgres';
import { QuestDBClient } from '@stock-bot/questdb';
import type { AppConfig } from '../config/schemas/index';
import type { ServiceDefinitions } from '../container/types';

export function registerDatabaseServices(
  container: AwilixContainer<ServiceDefinitions>,
  config: AppConfig
): void {
  // MongoDB
  if (config.mongodb?.enabled) {
    container.register({
      mongoClient: asFunction(({ logger }) => {
        // Parse MongoDB URI to extract components
        const uriMatch = config.mongodb.uri.match(
          /mongodb:\/\/(?:([^:]+):([^@]+)@)?([^:/]+):(\d+)\/([^?]+)(?:\?authSource=(.+))?/
        );
        const mongoConfig = {
          host: uriMatch?.[3] || 'localhost',
          port: parseInt(uriMatch?.[4] || '27017'),
          database: config.mongodb.database,
          username: uriMatch?.[1],
          password: uriMatch?.[2] ? String(uriMatch?.[2]) : undefined,
          authSource: uriMatch?.[6] || 'admin',
          uri: config.mongodb.uri,
        };
        return new MongoDBClient(mongoConfig, logger);
      }).singleton(),
    });
  } else {
    container.register({
      mongoClient: asValue(null),
    });
  }

  // PostgreSQL
  if (config.postgres?.enabled) {
    container.register({
      postgresClient: asFunction(({ logger }) => {
        const pgConfig = {
          host: config.postgres.host,
          port: config.postgres.port,
          database: config.postgres.database,
          username: config.postgres.user,
          password: String(config.postgres.password), // Ensure password is a string
        };

        logger.debug('PostgreSQL config:', {
          ...pgConfig,
          password: pgConfig.password ? '***' : 'NO_PASSWORD',
        });
        return new PostgreSQLClient(pgConfig, logger);
      }).singleton(),
    });
  } else {
    container.register({
      postgresClient: asValue(null),
    });
  }

  // QuestDB
  if (config.questdb?.enabled) {
    container.register({
      questdbClient: asFunction(({ logger }) => {
        return new QuestDBClient(
          {
            host: config.questdb!.host,
            httpPort: config.questdb!.httpPort,
            pgPort: config.questdb!.pgPort,
            influxPort: config.questdb!.influxPort,
            database: config.questdb!.database,
          },
          logger
        );
      }).singleton(),
    });
  } else {
    container.register({
      questdbClient: asValue(null),
    });
  }
}
