import { createDatabaseManager, type DatabaseManager } from "./database";

interface EdgeRegion {
  region: string;
  url: string;
  authToken?: string;
  isPrimary?: boolean;
}

interface EdgeConfig {
  primaryRegion: EdgeRegion;
  edgeReplicas: EdgeRegion[];
  fallbackRegion?: string;
}

export class EdgeDatabaseManager {
  private primaryManager: DatabaseManager;
  private edgeManagers: Map<string, DatabaseManager>;
  private config: EdgeConfig;

  constructor(config: EdgeConfig) {
    this.config = config;
    this.edgeManagers = new Map();

    this.primaryManager = createDatabaseManager({
      url: config.primaryRegion.url,
      authToken: config.primaryRegion.authToken,
    });

    config.edgeReplicas.forEach((replica) => {
      this.edgeManagers.set(replica.region, createDatabaseManager({
        url: replica.url,
        authToken: replica.authToken,
      }));
    });
  }

  getPrimary(): DatabaseManager {
    return this.primaryManager;
  }

  getEdge(region: string): DatabaseManager {
    const manager = this.edgeManagers.get(region);
    if (!manager) {
      throw new Error(`Edge region ${region} not found`);
    }
    return manager;
  }

  getDefaultEdge(): DatabaseManager {
    if (this.config.edgeReplicas.length > 0 && this.config.edgeReplicas[0]) {
      const region = this.config.edgeReplicas[0].region;
      const manager = this.edgeManagers.get(region);
      if (manager) {
        return manager;
      }
    }
    return this.primaryManager;
  }

  async close(): Promise<void> {
    await this.primaryManager.close();
    for (const manager of this.edgeManagers.values()) {
      await manager.close();
    }
  }

  async executeOnPrimary(query: string, params?: unknown[]): Promise<void> {
    await this.primaryManager.execute(query, params);
  }

  async queryOnEdge<T>(region: string, query: string, params?: unknown[]): Promise<T[]> {
    const manager = this.getEdge(region);
    return manager.query<T>(query, params);
  }

  async queryOnDefaultEdge<T>(query: string, params?: unknown[]): Promise<T[]> {
    const manager = this.getDefaultEdge();
    return manager.query<T>(query, params);
  }
}

export function createEdgeDatabaseManager(config: EdgeConfig): EdgeDatabaseManager {
  return new EdgeDatabaseManager(config);
}
