/**
 * Generador de módulos ERP
 * - module: bounded context (carpeta en modules/)
 * - name: agregado principal (usa placeholders en plantillas)
 * - plural: rutas/tabla (override del plural generado)
 */

import {
  camelCase,
  capitalCase,
  constantCase,
  dotCase,
  kebabCase,
  pascalCase,
  snakeCase,
} from "change-case";

/**
 * Generador de módulos ERP
 * @remarks
 * - `module`  -> bounded context (carpeta en `modules/`)
 * - `name`    -> agregado principal (singular)
 * - `plural`  -> plural del agregado para rutas/tablas (override manual si hace falta)
 * - Helpers   -> registrados con los nombres usados en las plantillas (.hbs)
 */
export default function (plop) {
  /** Helpers de casing para usar en hbs */
  plop.setHelper("kebabCase", (s) => kebabCase(String(s || "")));
  plop.setHelper("camelCase", (s) => camelCase(String(s || "")));
  plop.setHelper("pascalCase", (s) => pascalCase(String(s || "")));
  plop.setHelper("snakeCase", (s) => snakeCase(String(s || "")));
  plop.setHelper("constantCase", (s) => constantCase(String(s || "")));
  plop.setHelper("capitalCase", (s) => capitalCase(String(s || "")));
  plop.setHelper("dotCase", (s) => dotCase(String(s || "")));

  /** Validadores simples */
  const isKebab = (v) =>
    (!!v && /^[a-z][a-z0-9]*(?:-[a-z0-9]+)*$/.test(v)) ||
    "Usa kebab-case (empieza por letra; letras/números/guiones).";

  plop.setGenerator("module", {
    description: "Crea un nuevo módulo (bounded context) con un agregado principal",
    prompts: [
      {
        type: "input",
        name: "module",
        message: "Bounded context (kebab-case, p.ej. 'customer-payments'):",
        validate: isKebab,
        filter: (v) => kebabCase(v),
      },
      {
        type: "input",
        name: "name",
        message: "Agregado principal (kebab-case, p.ej. 'customer-payment'):",
        validate: isKebab,
        filter: (v) => kebabCase(v),
      },
      {
        type: "input",
        name: "plural",
        message: "Plural del agregado (kebab-case) — ENTER para sufijo 's':",
        filter: (v, answers) => (v?.trim() ? kebabCase(v) : `${kebabCase(answers.name)}s`),
        validate: isKebab,
      },
    ],
    actions: (answers) => {
      const dest = `modules/${kebabCase(answers.module)}`;
      /**
       * addMany copiará la plantilla completa en la carpeta del bounded context
       * usando los placeholders de las plantillas existentes (name/plural).
       */
      const actions = [
        {
          type: "addMany",
          destination: dest,
          base: "templates/new-module",
          templateFiles: "templates/new-module/**",
          abortOnFail: true,
        },
      ];
      return actions;
    },
  });
}
