import {
  init,
  loadRemote,
  registerRemotes,
} from "@module-federation/enhanced/runtime";

export interface RemoteModuleRef<T = unknown> {
  name: string;
  module: string;
  /** Phantom marker to preserve the generic parameter through the type system. */
  readonly __type?: T;
}

export interface RemoteEntry {
  name: string;
  entry: string;
}

let initialized = false;
const HOST_NAME = "aeroflot_flights_host" as const;

/**
 * Registers a remote with the MF runtime. On the first call, this also calls
 * `init()` to bootstrap the MF runtime with the host identity. Subsequent
 * calls use `registerRemotes()` to add remotes without re-initializing.
 */
export function registerRemote(entry: RemoteEntry): void {
  if (!initialized) {
    init({
      name: HOST_NAME,
      remotes: [entry],
    });
    initialized = true;
    return;
  }
  registerRemotes([entry]);
}

/**
 * Loads an exposed module from a previously registered remote. The `name` +
 * `module` fields are concatenated into MF's `remote/module` lookup key.
 *
 * Throws if the runtime returns a null/undefined module, which usually means
 * the remote manifest does not actually expose the requested path.
 */
export async function loadRemoteModule<T>(ref: RemoteModuleRef<T>): Promise<T> {
  const key = `${ref.name}/${ref.module.replace(/^\.\//, "")}`;
  const result = await loadRemote<T>(key);
  if (result === null || result === undefined) {
    throw new Error(`Remote module ${key} loaded as null/undefined`);
  }
  return result;
}

/** Test-only: resets the one-shot init flag. */
export function __resetRemoteLoaderForTests(): void {
  initialized = false;
}
