import * as path from "path";
import { logger } from "@/core/logger";
import * as glob from "glob";
import { DataTypes, Sequelize } from "sequelize";

/**
 * 🔹 Registra todos los modelos en Sequelize
 */
export const registerModels = async (database: Sequelize) => {
  if (!database) {
    const error = new Error("❌ Database not found.");
    logger.error({
      message: error.message,
      label: "initModels",
    });
    throw error;
  }

  const cwd = path.resolve(`${__dirname}/../`);
  const models: { [key: string]: any } = {};

  // Opciones para buscar los modelos
  const globOptions = {
    cwd,
    nocase: true,
    nodir: true,
    absolute: false,
  };

  try {
    logger.info(`🔎 Searching models in: ${cwd}`);

    // Buscamos los ficheros que terminen en .model.js o .model.ts
    for (const file of glob.sync("**/*.model.{js,ts}", globOptions)) {
      logger.info({ message: `📄 File >> ${file}...`, label: "registerModels" });
      const modelFile = require(path.resolve(cwd, file));
      const modelDef = modelFile.default;
      const model = typeof modelDef === "function" ? modelDef(database, DataTypes) : false;

      if (model) {
        models[model.name] = model;
        logger.info({
          message: `🔸 Model "${model.name}" registered (sequelize)`,
          label: "registerModels",
        });
      } else {
        logger.info({ message: "🚫 No model", label: "registerModels" });
      }
    }
  } catch (error) {
    logger.error("❌ Error registering models:", error);
    process.exit(1);
  }

  // Configurar asociaciones
  for (const model of Object.values(models)) {
    if (typeof model.associate === "function") {
      model.associate(database);
    }
  }

  try {
    // Sincronizamos DB en modo desarrollo
    if (process.env.NODE_ENV !== "production") {
      await database.sync({ force: false, alter: true });
      logger.info({ message: `✔️${"  "}Database synchronized successfully.`, label: "initModels" });
    } else {
      logger.warning({
        message: "⚠️ Running in production mode - Skipping database sync.",
        label: "initModels",
      });
    }
  } catch (err) {
    const error = err as Error;
    logger.error({ message: "❌ Error synchronizing database:", error, label: "initModels" });
    throw error;
  }
};
