import 'dotenv/config';
import { PrismaClient } from '@prisma/client';

/**
 * Limpia la marca de reversion de notas de credito que terminaron aprobadas.
 *
 * Cuando SIFEN rechaza una NC, el sistema la reversa y la marca con
 * `rec_aplicacion_reversada = true` + `rec_saldo_disponible = 0`. Si despues se corrige
 * el problema -- tipico: el certificado de firma -- y se reenvia, SIFEN la aprueba, pero
 * la marca quedaba puesta. La NC queda valida y aprobada pero invisible: el wizard de
 * cobros filtra por esos dos campos, asi que no se puede aplicar nunca mas.
 *
 * Solo toca NC aprobadas y no anuladas. El saldo vuelve a NULL en vez de a un monto
 * fijo, porque el sistema lo deriva de los subtotales de la NC cuando esta en NULL.
 *
 * Uso:
 *   pnpm restaurar:nc -- --empresa=<uuid> --dry
 *   pnpm restaurar:nc -- --empresa=<uuid>
 */

const prisma = new PrismaClient();
const arg = (n: string) => process.argv.slice(2).find((a) => a.startsWith(`--${n}=`))?.split('=').slice(1).join('=');
const DRY = process.argv.includes('--dry');

async function main() {
  const empresaId = arg('empresa');
  if (!empresaId) throw new Error('Falta --empresa=<uuid>');

  const afectadas = await prisma.nota_credito_cab.findMany({
    where: {
      empresa_id: empresaId,
      rec_aplicacion_reversada: true,
      estado: { notIn: ['Anulado', 'Anulada'] },
      OR: [{ estado_sifen: null }, { estado_sifen: { notIn: ['Rechazado', 'Cancelado', 'Inutilizado'] } }],
    },
    select: {
      id: true, dest: true, dpunexp: true, dnumdoc: true, dfeemide: true,
      rec_modo_aplicacion: true, estado_sifen: true,
      nota_credito_subtotal: { select: { dtotgralope: true } },
    },
  });

  console.log(`NC aprobadas con marca de reversion: ${afectadas.length}`);
  if (afectadas.length === 0) return;
  console.log(`Modo: ${DRY ? 'DRY-RUN' : 'REAL'}\n`);

  for (const n of afectadas) {
    const monto = Number(n.nota_credito_subtotal?.[0]?.dtotgralope ?? 0);
    console.log(
      `${n.dest}-${n.dpunexp}-${n.dnumdoc}  ${n.dfeemide?.toISOString().slice(0, 10) ?? ''}` +
      `  ${monto.toLocaleString('es-PY')}  ${n.rec_modo_aplicacion}  (${n.estado_sifen ?? 's/estado'})`,
    );
  }

  if (!DRY) {
    const r = await prisma.nota_credito_cab.updateMany({
      where: { id: { in: afectadas.map((n) => n.id) } },
      data: { rec_saldo_disponible: null, rec_aplicacion_reversada: false },
    });
    console.log(`\nRestauradas: ${r.count}`);
  } else {
    console.log(`\nRestauradas: ${afectadas.length} (simulado)`);
  }

  const estrictas = afectadas.filter((n) => n.rec_modo_aplicacion === 'ESTRICTO');
  if (estrictas.length > 0) {
    // La reversion tambien deshizo la aplicacion contra las cuotas de la factura. No se
    // re-aplica sola: hay que hacerlo desde un recibo, que deja rastro.
    console.log(`\n⚠ ${estrictas.length} en modo ESTRICTO: quedan disponibles, pero su aplicacion`);
    console.log('  contra las cuotas de la factura hay que rehacerla desde un recibo.');
  }
}

main()
  .then(() => prisma.$disconnect())
  .catch(async (e) => { console.error(e.message ?? e); await prisma.$disconnect(); process.exit(1); });
