/**
 * Reprocesa la contabilización de facturas que fueron firmadas en SIFEN pero
 * no tienen asiento contable generado (por ejemplo, por el bug de FK que
 * existió en integracion.service hasta que se corrigió).
 *
 * Idempotente: usa la misma lógica que el flujo normal — si la factura ya
 * tiene cont_documentos asociado, se saltea.
 *
 * Uso:
 *   pnpm exec ts-node scripts/reprocesar-asientos-facturas.ts [--empresa=<id>] [--desde=YYYY-MM-DD] [--hasta=YYYY-MM-DD] [--dry]
 */
import 'dotenv/config';
import { NestFactory } from '@nestjs/core';
import { AppModule } from '../src/app.module';
import { PrismaService } from '../src/prisma/prisma.service';
import { ContabilidadIntegracionService } from '../src/contabilidad/services/integracion.service';

type Args = {
  empresaId?: string;
  desde?: Date;
  hasta?: Date;
  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('--empresa=')) out.empresaId = a.split('=')[1];
    else if (a.startsWith('--desde=')) out.desde = new Date(a.split('=')[1]);
    else if (a.startsWith('--hasta=')) out.hasta = new Date(a.split('=')[1]);
  }
  return out;
}

async function main() {
  const args = parseArgs(process.argv);
  const app = await NestFactory.createApplicationContext(AppModule, { logger: ['error', 'warn', 'log'] });
  const prisma = app.get(PrismaService);
  const integracion = app.get(ContabilidadIntegracionService);

  // Buscar facturas firmadas en SIFEN sin documento contable asociado
  const where: any = {
    estado_sifen: 'Aprobado',
  };
  if (args.empresaId) where.empresa_id = args.empresaId;
  if (args.desde || args.hasta) {
    where.dfeemide = {};
    if (args.desde) where.dfeemide.gte = args.desde;
    if (args.hasta) where.dfeemide.lte = args.hasta;
  }

  const facturas = await prisma.factura_cab.findMany({
    where,
    select: { id: true, empresa_id: true, dest: true, dpunexp: true, dnumdoc: true, dfeemide: true },
    orderBy: { dfeemide: 'asc' },
  });

  const candidatas: typeof facturas = [];
  for (const f of facturas) {
    const doc = await prisma.cont_documentos.findFirst({
      where: { empresa_id: f.empresa_id as string, origen_tipo: 'factura_cab', origen_id: f.id },
      select: { id: true },
    });
    if (!doc) candidatas.push(f);
  }

  console.log(`Facturas firmadas: ${facturas.length}`);
  console.log(`Sin asiento contable: ${candidatas.length}`);

  if (args.dry) {
    candidatas.forEach((f) =>
      console.log(`  [dry] ${f.dest}-${f.dpunexp}-${f.dnumdoc} (${f.dfeemide?.toISOString().slice(0, 10)}) id=${f.id}`),
    );
    await app.close();
    return;
  }

  let ok = 0;
  let fail = 0;
  for (const f of candidatas) {
    const nro = `${f.dest}-${f.dpunexp}-${f.dnumdoc}`;
    try {
      await integracion.integrarFacturaVenta(f.id);
      ok++;
      console.log(`OK   ${nro}`);
    } catch (e: any) {
      fail++;
      console.error(`FAIL ${nro}: ${e.message}`);
    }
  }

  console.log(`\nResultado: ${ok} OK, ${fail} con error`);
  await app.close();
}

main().catch((e) => {
  console.error(e);
  process.exit(1);
});
