import type { PacificaConfig } from "./adapter";
import { PacificaAdapter } from "./adapter";
import type { PositionSnapshot } from "../../../domain/src/types";

export interface RegisteredAdapter {
  id: string;
  role?: "maker" | "hedger" | string;
  adapter: PacificaAdapter;
}

export class AdapterRegistry {
  private readonly adapters = new Map<string, RegisteredAdapter>();

  constructor(initial: Array<{ id: string; role?: string; config: PacificaConfig }> = []) {
    initial.forEach(entry => this.register(entry.id, entry.config, entry.role));
  }

  register(id: string, config: PacificaConfig, role?: string): RegisteredAdapter {
    const adapter = new PacificaAdapter(config);
    adapter.setAccountId(id);
    const entry: RegisteredAdapter = { id, role, adapter };
    this.adapters.set(id, entry);
    return entry;
  }

  attach(id: string, adapter: PacificaAdapter, role?: string): RegisteredAdapter {
    if (typeof adapter.setAccountId === "function") {
      adapter.setAccountId(id);
    }
    const entry: RegisteredAdapter = { id, role, adapter };
    this.adapters.set(id, entry);
    return entry;
  }

  get(id: string): PacificaAdapter {
    const entry = this.adapters.get(id);
    if (!entry) {
      throw new Error(`Adapter ${id} is not registered`);
    }
    return entry.adapter;
  }

  findByRole(role: string): PacificaAdapter | undefined {
    for (const entry of this.adapters.values()) {
      if (entry.role === role) return entry.adapter;
    }
    return undefined;
  }

  findEntryByRole(role: string): RegisteredAdapter | undefined {
    for (const entry of this.adapters.values()) {
      if (entry.role === role) return entry;
    }
    return undefined;
  }

  list(): RegisteredAdapter[] {
    return Array.from(this.adapters.values());
  }

  async collectPositions(
    symbol: string
  ): Promise<Array<PositionSnapshot & { accountId: string }>> {
    const snapshots: Array<PositionSnapshot & { accountId: string }> = [];
    for (const entry of this.adapters.values()) {
      const snapshot = await entry.adapter.getPosition(symbol);
      const accountId = snapshot.accountId ?? entry.id;
      snapshots.push({ ...snapshot, accountId });
    }
    return snapshots;
  }
}
