import {
  IDatabaseAdapter,
  DatabaseConfig,
  SqliteConfig,
  PostgresConfig,
  MysqlConfig,
} from "../interfaces/database.interface";
import { MongoAdapter } from "../adapters/mongodb.adapter";
import { SqliteAdapter } from "../adapters/sqlite.adapter";
import { MysqlAdapter } from "../adapters/mysql.adapter";
import { PostgresAdapter } from "../adapters/postgresql.adapter";

export class DatabaseFactory {
  static createAdapter(config: DatabaseConfig): IDatabaseAdapter {
    switch (config.type) {
      case "mongodb":
        if (!config.connectionString) {
          throw new Error("MongoDB connection string is required");
        }
        return new MongoAdapter({
          mongoUri: config.connectionString,
          maxRetries: config.maxRetries,
          retryDelay: config.retryDelay,
          collectionName: config.collectionName,
        });

      case "sqlite":
        if (!config.database) {
          throw new Error("SQLite database path is required");
        }
        return new SqliteAdapter({
          database: config.database,
          maxRetries: config.maxRetries,
          retryDelay: config.retryDelay,
          tableName: config.tableName,
        });

      case "postgresql":
        if (
          !config.host ||
          !config.database ||
          !config.username ||
          !config.password
        ) {
          throw new Error(
            "PostgreSQL host, database, username, and password are required"
          );
        }
        return new PostgresAdapter({
          host: config.host,
          port: config.port || 5432,
          database: config.database,
          username: config.username,
          password: config.password,
          maxRetries: config.maxRetries,
          retryDelay: config.retryDelay,
          tableName: config.tableName,
        });

      case "mysql":
        if (
          !config.host ||
          !config.database ||
          !config.username ||
          !config.password
        ) {
          throw new Error(
            "MySQL host, database, username, and password are required"
          );
        }
        return new MysqlAdapter({
          host: config.host,
          port: config.port || 3306,
          database: config.database,
          username: config.username,
          password: config.password,
          maxRetries: config.maxRetries,
          retryDelay: config.retryDelay,
          tableName: config.tableName,
        });

      default:
        throw new Error(`Unsupported database type: ${config.type}`);
    }
  }

  // Convenience methods for common configurations
  static createMongoAdapter(
    mongoUri: string,
    options?: {
      maxRetries?: number;
      retryDelay?: number;
      collectionName?: string;
    }
  ): IDatabaseAdapter {
    return new MongoAdapter({
      mongoUri,
      maxRetries: options?.maxRetries,
      retryDelay: options?.retryDelay,
      collectionName: options?.collectionName,
    });
  }

  static createSqliteAdapter(
    database: string,
    options?: { maxRetries?: number; retryDelay?: number; tableName?: string }
  ): IDatabaseAdapter {
    return new SqliteAdapter({
      database,
      maxRetries: options?.maxRetries,
      retryDelay: options?.retryDelay,
      tableName: options?.tableName,
    });
  }

  static createMysqlAdapter(config: MysqlConfig): IDatabaseAdapter {
    return new MysqlAdapter(config);
  }

  static createPostgresAdapter(config: PostgresConfig): IDatabaseAdapter {
    return new PostgresAdapter(config);
  }
}
