/**
 * Encuentra E que referencien directamente a una I/07 PPD vía
 * `cfdis_relacionados`. Patrón real observado: la E "ajusta" la I/07 PPD,
 * no al anticipo original. La I/07 PPD apunta al anticipo, la E apunta a
 * la I/07 PPD.
 */
import { prisma, tenantDb } from '../src/config/database.js';

const TARGET_RFC = process.argv[2];

async function main() {
  const tenants = await prisma.tenant.findMany({ select: { id: true, rfc: true, databaseName: true } });

  for (const t of tenants) {
    let pool;
    try { pool = await tenantDb.getPool(t.id, t.databaseName); } catch { continue; }
    console.log(`\n=== ${t.rfc}${TARGET_RFC ? ` (RFC=${TARGET_RFC})` : ''} ===`);

    const rfcFilter = TARGET_RFC
      ? `AND (UPPER(i.rfc_emisor) = UPPER('${TARGET_RFC}') OR UPPER(i.rfc_receptor) = UPPER('${TARGET_RFC}'))`
      : '';

    const { rows } = await pool.query(`
      SELECT
        i.uuid AS i_uuid, i.fecha_emision AS i_fecha, i.total_mxn AS i_total,
        i.iva_traslado_mxn AS i_iva, i.rfc_emisor AS i_emisor, i.rfc_receptor AS i_receptor,
        i.type AS i_type,
        e.uuid AS e_uuid, e.cfdi_tipo_relacion AS e_rel, e.metodo_pago AS e_mp,
        e.fecha_emision AS e_fecha, e.total_mxn AS e_total, e.iva_traslado_mxn AS e_iva,
        ABS(EXTRACT(EPOCH FROM (e.fecha_emision - i.fecha_emision)) / 86400)::int AS diff_dias,
        EXTRACT(YEAR FROM i.fecha_emision)::int * 12 + EXTRACT(MONTH FROM i.fecha_emision)::int AS i_periodo,
        EXTRACT(YEAR FROM e.fecha_emision)::int * 12 + EXTRACT(MONTH FROM e.fecha_emision)::int AS e_periodo
      FROM cfdis i
      JOIN cfdis e
        ON LOWER(i.uuid) = ANY(string_to_array(LOWER(e.cfdis_relacionados), '|'))
      WHERE i.cfdi_tipo_relacion = '07'
        AND i.tipo_comprobante = 'I' AND i.metodo_pago = 'PPD'
        AND i.status NOT IN ('Cancelado','0')
        AND e.tipo_comprobante = 'E'
        AND e.status NOT IN ('Cancelado','0')
        ${rfcFilter}
      ORDER BY i.fecha_emision DESC
    `);

    console.log(`Total pares: ${rows.length}`);

    const buckets = { mismoMes: 0, eDespues1: 0, eDespuesMas: 0, eAntes: 0 };
    for (const r of rows) {
      const diff = Number(r.e_periodo) - Number(r.i_periodo);
      if (diff < 0) buckets.eAntes++;
      else if (diff === 0) buckets.mismoMes++;
      else if (diff === 1) buckets.eDespues1++;
      else buckets.eDespuesMas++;
    }
    console.log(`  Mismo mes: ${buckets.mismoMes}`);
    console.log(`  E 1 mes después: ${buckets.eDespues1}`);
    console.log(`  E ≥2 meses después: ${buckets.eDespuesMas}`);
    console.log(`  E antes: ${buckets.eAntes}`);

    if (rows.length > 0) {
      console.log(`\n  Detalle (top ${Math.min(rows.length, 10)}):`);
      for (const r of rows.slice(0, 10)) {
        const fi = new Date(r.i_fecha).toISOString().slice(0, 10);
        const fe = new Date(r.e_fecha).toISOString().slice(0, 10);
        const i_base = Number(r.i_total) - Number(r.i_iva || 0);
        const e_base = Number(r.e_total) - Number(r.e_iva || 0);
        const diff = Number(r.e_periodo) - Number(r.i_periodo);
        console.log(`    I/07 PPD ${r.i_uuid.substring(0,8)} ${fi} base=${i_base.toFixed(2)} ${r.i_emisor}→${r.i_receptor} (${r.i_type})`);
        console.log(`      E/${r.e_rel ?? 'null'}/${r.e_mp || '?'} ${r.e_uuid.substring(0,8)} ${fe} base=${e_base.toFixed(2)} diffMeses=${diff} (${r.diff_dias}d)`);
      }
    }
  }
  await prisma.$disconnect();
}
main().catch(async e => { console.error(e); await prisma.$disconnect().catch(() => {}); process.exit(1); });
