/**
 * Reparent quirúrgico de un submódulo a otro módulo del catálogo de seguridad.
 *
 * A diferencia del seed-cli (que bootstrapea TODO el AppModule y se cuelga/OOMea),
 * este script instancia SOLO PrismaClient → corre en ~2s. Usalo para movidas de
 * catálogo puntuales sin levantar la app.
 *
 * Qué hace (idempotente, no borra nada, no toca asignaciones que referencian por id):
 *   1. submodulos.modulo_id (del submódulo) = id del módulo destino.
 *   2. perfiles_privilegios.modulo_id (de los privilegios del submódulo) = id destino
 *      (columna legacy que /auth/me usa como fallback; se mantiene consistente).
 *
 * Uso:
 *   pnpm reparent:submodulo -- --submodulo=TES_GASTOS --modulo=COMPRAS
 *   pnpm reparent:submodulo -- --submodulo=TES_GASTOS --modulo=COMPRAS --dry
 *
 * NOTA: el seed de arranque (SeguridadSeedBootstrap → runCatalogoMaestro) también
 * reparenta según seguridad.seed-data.ts en cada boot. Este script sirve para
 * aplicarlo YA, sin reiniciar el backend, o en entornos donde no corre el bootstrap.
 */
import 'dotenv/config';
import { PrismaClient } from '@prisma/client';

const prisma = new PrismaClient();

type Args = { submodulo?: string; modulo?: string; dry: boolean };

function parseArgs(argv: string[]): Args {
  const out: Args = { dry: false };
  for (const a of argv.slice(2)) {
    if (a === '--dry') out.dry = true;
    else if (a.startsWith('--submodulo=')) out.submodulo = a.split('=')[1]?.trim();
    else if (a.startsWith('--modulo=')) out.modulo = a.split('=')[1]?.trim();
  }
  return out;
}

async function main() {
  const { submodulo: subCodigo, modulo: modCodigo, dry } = parseArgs(process.argv);

  if (!subCodigo || !modCodigo) {
    console.error('Uso: --submodulo=<CODIGO_SUBMODULO> --modulo=<CODIGO_MODULO_DESTINO> [--dry]');
    process.exit(1);
  }

  const modDestino = await prisma.modulos.findFirst({
    where: { codigo: modCodigo },
    select: { id: true, codigo: true },
  });
  if (!modDestino) throw new Error(`No existe el módulo destino "${modCodigo}"`);

  const sub = await prisma.submodulos.findUnique({
    where: { codigo: subCodigo },
    select: { id: true, modulo_id: true, modulos: { select: { codigo: true } } },
  });
  if (!sub) throw new Error(`No existe el submódulo "${subCodigo}"`);

  console.log(
    `Submódulo ${subCodigo}: módulo actual = ${sub.modulos?.codigo ?? sub.modulo_id} → destino = ${modDestino.codigo}`,
  );

  const privs = await prisma.privilegios.findMany({
    where: { submodulo_id: sub.id },
    select: { id: true, codigo: true },
  });
  const privIds = privs.map((p) => p.id);

  if (dry) {
    const pendientes = await prisma.perfiles_privilegios.count({
      where: { privilegio_id: { in: privIds }, NOT: { modulo_id: modDestino.id } },
    });
    console.log('— DRY RUN —');
    console.log(`  submodulos.modulo_id ${sub.modulo_id === modDestino.id ? 'ya está en destino' : 'se actualizaría'}`);
    console.log(`  perfiles_privilegios a backfillear: ${pendientes} (privilegios: ${privs.map((p) => p.codigo).join(', ')})`);
    return;
  }

  if (sub.modulo_id === modDestino.id) {
    console.log('✔ submodulos.modulo_id ya estaba en el destino.');
  } else {
    await prisma.submodulos.update({ where: { id: sub.id }, data: { modulo_id: modDestino.id } });
    console.log(`✅ submodulos.modulo_id → ${modDestino.codigo}`);
  }

  const upd = await prisma.perfiles_privilegios.updateMany({
    where: { privilegio_id: { in: privIds }, NOT: { modulo_id: modDestino.id } },
    data: { modulo_id: modDestino.id },
  });
  console.log(`✅ perfiles_privilegios backfilled: ${upd.count} filas (${privs.map((p) => p.codigo).join(', ')})`);

  const check = await prisma.submodulos.findUnique({
    where: { codigo: subCodigo },
    select: { modulos: { select: { codigo: true } } },
  });
  console.log(`🔎 ${subCodigo} ahora cuelga de módulo: ${check?.modulos?.codigo}`);
}

main()
  .then(() => prisma.$disconnect())
  .catch(async (e) => {
    console.error('❌ Falló el reparent:', e);
    await prisma.$disconnect();
    process.exit(1);
  });
