/**
 * Reproduce el cálculo de deducciones para Husberto en agosto 2025 con
 * considerarActivos=true vs false, y muestra la diferencia esperada.
 * Apunta directo al SQL para descartar bugs de wire/cache/UI.
 */
import { prisma, tenantDb } from '../src/config/database.js';

async function main() {
  const t = await prisma.tenant.findFirst({ where: { rfc: 'DESPACHO_MO3NI6U8_B9VGG' } });
  if (!t) { console.log('Patito tenant not found'); return; }
  const pool = await tenantDb.getPool(t.id, t.databaseName);

  const RFC = 'TOAH680201RA2';
  const FI = '2025-08-01';
  const FF = '2025-08-31';

  console.log(`Husberto (${RFC}), agosto 2025\n`);

  // 0) Lista TODOS los P recibidos en el período (sin filtros)
  const all = await pool.query(`
    SELECT uuid, monto_pago_mxn, forma_pago, fecha_pago_p, uuid_relacionado
    FROM cfdis
    WHERE UPPER(rfc_receptor) = $1
      AND tipo_comprobante = 'P'
      AND status NOT IN ('Cancelado','0')
      AND fecha_pago_p >= $2::date AND fecha_pago_p < ($3::date + interval '1 day')
    ORDER BY monto_pago_mxn DESC
  `, [RFC, FI, FF]);
  console.log(`Total P recibidos en agosto 2025 (sin filtros): ${all.rows.length}`);
  for (const r of all.rows) {
    console.log(`  ${r.uuid} | $${r.monto_pago_mxn} | forma_pago=${r.forma_pago} | uuid_rel=${r.uuid_relacionado}`);
  }
  console.log();

  // 1) Suma de P recibidos sin filtro extra
  const sinFiltro = await pool.query(`
    SELECT COUNT(*)::int as n,
           COALESCE(SUM(COALESCE(monto_pago_mxn,0)),0)::numeric(14,2) as bruto,
           COALESCE(SUM(COALESCE(monto_pago_mxn,0) - LEAST(COALESCE(iva_traslado_pago_mxn,0), COALESCE(monto_pago_mxn,0)*0.16) - COALESCE(ieps_traslado_pago_mxn,0)),0)::numeric(14,2) as neto
    FROM cfdis
    WHERE UPPER(rfc_receptor) = $1
      AND tipo_comprobante = 'P'
      AND status NOT IN ('Cancelado','0')
      AND fecha_pago_p >= $2::date AND fecha_pago_p < ($3::date + interval '1 day')
      AND NOT (COALESCE(forma_pago, '') = '01' AND COALESCE(monto_pago_mxn, 0) > 2000)
  `, [RFC, FI, FF]);
  console.log(`P recibidos SIN filtro activos (CON filtro no-deducible): n=${sinFiltro.rows[0].n}, bruto=$${sinFiltro.rows[0].bruto}, neto=$${sinFiltro.rows[0].neto}`);

  // 2) Misma query CON el filtro de activos (regla 2: P paga I de activo)
  const ACTIVOS = "('I01','I02','I03','I04','I05','I06','I07','I08')";
  const conFiltro = await pool.query(`
    SELECT COUNT(*)::int as n,
           COALESCE(SUM(COALESCE(monto_pago_mxn,0)),0)::numeric(14,2) as bruto,
           COALESCE(SUM(COALESCE(monto_pago_mxn,0) - LEAST(COALESCE(iva_traslado_pago_mxn,0), COALESCE(monto_pago_mxn,0)*0.16) - COALESCE(ieps_traslado_pago_mxn,0)),0)::numeric(14,2) as neto
    FROM cfdis
    WHERE UPPER(rfc_receptor) = $1
      AND tipo_comprobante = 'P'
      AND status NOT IN ('Cancelado','0')
      AND fecha_pago_p >= $2::date AND fecha_pago_p < ($3::date + interval '1 day')
      AND NOT (COALESCE(forma_pago, '') = '01' AND COALESCE(monto_pago_mxn, 0) > 2000)
      AND NOT (tipo_comprobante = 'I' AND uso_cfdi IN ${ACTIVOS})
      AND NOT (tipo_comprobante = 'P' AND EXISTS (
        SELECT 1 FROM cfdis i_act
        WHERE LOWER(i_act.uuid) = LOWER(cfdis.uuid_relacionado)
          AND i_act.tipo_comprobante = 'I'
          AND i_act.uso_cfdi IN ${ACTIVOS}
      ))
      AND NOT (tipo_comprobante = 'E' AND cfdis.cfdis_relacionados IS NOT NULL AND EXISTS (
        SELECT 1 FROM cfdis r_act
        WHERE LOWER(r_act.uuid) = ANY(string_to_array(LOWER(cfdis.cfdis_relacionados), '|'))
          AND (
            (r_act.tipo_comprobante = 'I' AND r_act.uso_cfdi IN ${ACTIVOS})
            OR (r_act.tipo_comprobante = 'P' AND EXISTS (
              SELECT 1 FROM cfdis pi_act
              WHERE LOWER(pi_act.uuid) = LOWER(r_act.uuid_relacionado)
                AND pi_act.tipo_comprobante = 'I'
                AND pi_act.uso_cfdi IN ${ACTIVOS}
            ))
          )
      ))
  `, [RFC, FI, FF]);
  console.log(`P recibidos CON filtro activos:  n=${conFiltro.rows[0].n}, bruto=$${conFiltro.rows[0].bruto}, neto=$${conFiltro.rows[0].neto}`);

  console.log(`\n→ Diferencia esperada al desactivar Considerar Activos:`);
  console.log(`  Bruto: $${(Number(sinFiltro.rows[0].bruto) - Number(conFiltro.rows[0].bruto)).toLocaleString('es-MX')}`);
  console.log(`  Neto:  $${(Number(sinFiltro.rows[0].neto) - Number(conFiltro.rows[0].neto)).toLocaleString('es-MX')}`);

  // 3) Lista los P específicos que se filtran
  console.log(`\nDetalle de P que SE FILTRAN al desactivar activos:`);
  const filtrados = await pool.query(`
    SELECT uuid, monto_pago_mxn, iva_traslado_pago_mxn, uuid_relacionado, fecha_pago_p
    FROM cfdis
    WHERE UPPER(rfc_receptor) = $1
      AND tipo_comprobante = 'P'
      AND status NOT IN ('Cancelado','0')
      AND fecha_pago_p >= $2::date AND fecha_pago_p < ($3::date + interval '1 day')
      AND EXISTS (
        SELECT 1 FROM cfdis i_act
        WHERE LOWER(i_act.uuid) = LOWER(cfdis.uuid_relacionado)
          AND i_act.tipo_comprobante = 'I'
          AND i_act.uso_cfdi IN ${ACTIVOS}
      )
  `, [RFC, FI, FF]);
  for (const r of filtrados.rows) {
    console.log(`  ${r.uuid} | $${r.monto_pago_mxn} → uuid_rel: ${r.uuid_relacionado}`);
  }

  await prisma.$disconnect();
}

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