import { IModuleServer, ModuleParams } from "@erp/core";
import { logger } from "../logger";
import { initModels, registerModels } from "./model-loader";
import { registerService } from "./service-registry";

const registeredModules: Map<string, IModuleServer> = new Map();
const initializedModules = new Set<string>();

export function registerModule(pkg: IModuleServer) {
  if (registeredModules.has(pkg.metadata.name)) {
    throw new Error(`❌ Paquete "${pkg.metadata.name}" ya registrado.`);
  }
  registeredModules.set(pkg.metadata.name, pkg);
}

export async function initModules(params: ModuleParams) {
  registeredModules.forEach((_, name) => {
    loadModule(name, params);
  });
  await initModels(params);
}

const loadModule = (name: string, params: ModuleParams) => {
  if (initializedModules.has(name)) return;

  const pkg = registeredModules.get(name);
  if (!pkg) throw new Error(`❌ Paquete "${name}" no encontrado.`);

  // Resolver dependencias primero
  const deps = pkg.metadata.dependencies || [];
  deps.forEach((dep) => loadModule(dep, params));

  // Inicializar el module
  pkg.init(params);

  const pkgApi = pkg.registerDependencies?.(params);

  // Registrar modelos de Sequelize, si los expone
  if (pkgApi?.models) {
    registerModels(pkgApi.models, params);
  }

  // Registrar sus servicios, si los expone
  if (pkgApi?.services) {
    const services = pkgApi.services;
    if (services && typeof services === "object") {
      registerService(pkg.metadata.name, services);
    }
  }

  initializedModules.add(name);
  logger.info(`✅ Module "${name}" registered`, { label: "loadModule" });
};
