/**
 * One-shot: desactiva las cuentas del plan default paraguayo para una empresa
 * que ya migró su propio plan.
 *
 * Contexto: cuando una empresa importa su plan de cuentas custom (ej. DOBA con
 * migrate-doba-plan-cuentas.ts), el seed default paraguayo puede haber quedado
 * conviviendo, generando árboles duplicados en la UI y confusión al buscar
 * cuentas (aparecen versiones custom + default del mismo concepto).
 *
 * Estrategia:
 *   1. Identifica cuentas del plan default (matching contra los códigos del seed).
 *   2. Para cada una:
 *      - Chequea si está en uso: mapeo (cont_mapeo_cuentas) o líneas de asientos.
 *      - Si NO está en uso → active=false + acepta_movimientos=false (mantiene código).
 *      - Si está en uso → **NO tocarla**, listar warning para revisión manual.
 *   3. NOTA: no renombramos el código a OLD-* (a diferencia del script de migración)
 *      porque no vamos a reinsertar cuentas con esos códigos y renombrar chocaría
 *      con la unique constraint (empresa_id, codigo) cuando ya existen OLD-* previos.
 *
 * Uso:
 *   npx ts-node scripts/desactivar-plan-default.ts \
 *     --empresa=40539a9d-ffcc-48c7-b932-5bb08b0828ac \
 *     [--dry-run]
 *
 * Con --dry-run muestra qué se haría sin persistir cambios.
 */
import { PrismaClient } from '@prisma/client';
import { PLAN_CUENTAS_PARAGUAY } from '../src/contabilidad/seeds/plan-cuentas-paraguay.seed';

function parseArgs(): { empresa: string; dryRun: boolean } {
  const out: { empresa?: string; dryRun: boolean } = { dryRun: false };
  for (const arg of process.argv.slice(2)) {
    if (arg === '--dry-run') out.dryRun = true;
    else if (arg.startsWith('--empresa=')) out.empresa = arg.slice('--empresa='.length);
  }
  if (!out.empresa) {
    throw new Error('Falta --empresa=<uuid>');
  }
  return { empresa: out.empresa, dryRun: out.dryRun };
}

async function main() {
  const { empresa, dryRun } = parseArgs();
  const prisma = new PrismaClient();
  try {
    // 1. Set de códigos del plan default paraguayo (single source of truth: el seed).
    const codigosDefault = new Set(PLAN_CUENTAS_PARAGUAY.map((c) => c.codigo));
    console.log(`Códigos del seed default paraguayo: ${codigosDefault.size}`);

    // 2. Traer cuentas de la empresa que coincidan con esos códigos.
    const cuentasDefault = await prisma.cont_plan_cuentas.findMany({
      where: {
        empresa_id: empresa,
        active: true,
        codigo: { in: Array.from(codigosDefault) },
      },
      select: {
        id: true,
        codigo: true,
        descripcion: true,
        acepta_movimientos: true,
      },
    });
    console.log(`Cuentas del default encontradas activas: ${cuentasDefault.length}`);

    if (cuentasDefault.length === 0) {
      console.log('✅ No hay cuentas del default activas. Nada para hacer.');
      return;
    }

    // 3. Para cada una, verificar si está en uso.
    const enUso: Array<{
      id: string;
      codigo: string;
      descripcion: string;
      mapeos: number;
      lineas: number;
    }> = [];
    const paraDesactivar: Array<{ id: string; codigo: string; descripcion: string }> = [];

    for (const c of cuentasDefault) {
      const [mapeos, lineas] = await Promise.all([
        prisma.cont_mapeo_cuentas.count({
          where: { cuenta_id: c.id, empresa_id: empresa },
        }),
        prisma.cont_asientos_det.count({
          where: { cuenta_id: c.id, asiento: { empresa_id: empresa } },
        }),
      ]);

      if (mapeos > 0 || lineas > 0) {
        enUso.push({ ...c, mapeos, lineas });
      } else {
        paraDesactivar.push({ id: c.id, codigo: c.codigo, descripcion: c.descripcion });
      }
    }

    console.log('');
    console.log(`Para desactivar (sin uso): ${paraDesactivar.length}`);
    console.log(`En uso (NO se tocan): ${enUso.length}`);

    if (enUso.length > 0) {
      console.log('');
      console.log('⚠️  Cuentas del default EN USO — no se desactivan:');
      for (const c of enUso) {
        console.log(
          `   ${c.codigo.padEnd(12)} ${c.descripcion.padEnd(40)}  mapeos=${c.mapeos}  lineas=${c.lineas}`,
        );
      }
      console.log('');
      console.log(
        '  → Recomendación: repuntar el mapeo/línea a la cuenta equivalente del plan del cliente,',
      );
      console.log('    y luego re-ejecutar este script para desactivar el remanente.');
    }

    if (paraDesactivar.length > 0) {
      console.log('');
      console.log('Cuentas a desactivar (sample 20):');
      for (const c of paraDesactivar.slice(0, 20)) {
        console.log(`   ${c.codigo.padEnd(12)} ${c.descripcion}`);
      }
      if (paraDesactivar.length > 20) {
        console.log(`   ... y ${paraDesactivar.length - 20} más.`);
      }
    }

    if (dryRun) {
      console.log('');
      console.log('--- DRY RUN: nada se persiste ---');
      return;
    }

    if (paraDesactivar.length === 0) {
      console.log('');
      console.log('No hay cuentas para desactivar (todas en uso o ya inactivas).');
      return;
    }

    // 4. Soft-delete en transacción.
    //
    // NO renombramos el código a OLD-* como hace el script de migración porque
    // acá no vamos a insertar cuentas nuevas que necesiten reutilizar esos
    // códigos (el cliente ya trajo su propia numeración, distinta del default).
    // Renombrar solo generaría choques con la unique constraint (empresa_id, codigo)
    // cuando ya existían OLD-* de una corrida previa del script de migración.
    // Con active=false y acepta_movimientos=false alcanza para sacarlas del
    // árbol y de los autocompletes.
    console.log('');
    console.log(`Desactivando ${paraDesactivar.length} cuentas...`);
    await prisma.$transaction(
      async (tx) => {
        for (const c of paraDesactivar) {
          await tx.cont_plan_cuentas.update({
            where: { id: c.id },
            data: {
              active: false,
              acepta_movimientos: false,
              is_sistema: false,
            },
          });
        }
      },
      { timeout: 60_000 },
    );

    console.log(`✅ Desactivadas ${paraDesactivar.length} cuentas del plan default.`);
    console.log('   (código conservado — solo active=false. Filtrá "Mostrar inactivas" para verlas.)');
  } finally {
    await prisma.$disconnect();
  }
}

main().catch((err) => {
  console.error('❌ Error:', err);
  process.exit(1);
});
