/**
 * Valida la alineación dashboard ≡ impuestos tras refactor de getResumenIva.
 * Para 5 muestras aleatorias por contribuyente, compara:
 *   dashboard.calcularIvaBalancePorRegimen().total  vs
 *   impuestos.getResumenIva().resultado
 *
 * Deben coincidir céntimo por céntimo (Resultado = Trasladado − Acreditable − Retenido,
 * usando los mismos 6 buckets del dashboard).
 *
 * Uso:
 *   pnpm --filter @horux/api exec tsx scripts/validate-dashboard-impuestos.ts
 *   METRICAS_BYPASS_CACHE=1 pnpm --filter @horux/api exec tsx scripts/validate-dashboard-impuestos.ts
 */
import { prisma, tenantDb } from '../src/config/database.js';
import * as dashboard from '../src/services/dashboard.service.js';
import { getResumenIva } from '../src/services/impuestos.service.js';

const TOL = 0.01;

function cmp(a: number, b: number): boolean { return Math.abs(a - b) <= TOL; }
function fmt(n: number): string {
  return n.toLocaleString('es-MX', { minimumFractionDigits: 2, maximumFractionDigits: 2 });
}

async function main() {
  console.log('=== Validación dashboard.balance ≡ impuestos.resultado ===');
  console.log(`   BYPASS_CACHE=${process.env.METRICAS_BYPASS_CACHE === '1' ? 'YES' : 'no'}\n`);

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

  let total = 0;
  let pass = 0;
  let fail = 0;

  for (const t of tenants) {
    const pool = await tenantDb.getPool(t.id, t.databaseName);
    const { rows: contribs } = await pool.query<{ entidad_id: string; nombre: string }>(
      `SELECT c.entidad_id, eg.nombre
       FROM contribuyentes c
       JOIN entidades_gestionadas eg ON eg.id = c.entidad_id
       WHERE EXISTS (SELECT 1 FROM metricas_mensuales m WHERE m.contribuyente_id = c.entidad_id)`,
    );
    if (contribs.length === 0) continue;
    console.log(`[${t.rfc}] ${contribs.length} contribuyentes`);

    for (const c of contribs) {
      const { rows: samples } = await pool.query<{ anio: number; mes: number }>(
        `SELECT anio, mes FROM (
           SELECT DISTINCT anio, mes FROM metricas_mensuales WHERE contribuyente_id = $1
         ) t
         ORDER BY random() LIMIT 5`,
        [c.entidad_id],
      );
      console.log(`  ${c.nombre}:`);

      for (const s of samples) {
        total++;
        const fi = `${s.anio}-${String(s.mes).padStart(2, '0')}-01`;
        const lastDay = new Date(s.anio, s.mes, 0).getDate();
        const ff = `${s.anio}-${String(s.mes).padStart(2, '0')}-${String(lastDay).padStart(2, '0')}`;

        const bal = await dashboard.calcularIvaBalancePorRegimen(
          pool, t.id, fi, ff, [], undefined, false, c.entidad_id,
        );
        const resumen = await getResumenIva(pool, fi, ff, t.id, false, c.entidad_id);

        const mesLabel = `${s.anio}-${String(s.mes).padStart(2, '0')}`;
        if (cmp(bal.total, resumen.resultado)) {
          pass++;
          console.log(`    ✓ ${mesLabel}  balance=$${fmt(bal.total)}  resultado=$${fmt(resumen.resultado)}`);
        } else {
          fail++;
          const delta = bal.total - resumen.resultado;
          console.log(`    ✗ ${mesLabel}  balance=$${fmt(bal.total)}  resultado=$${fmt(resumen.resultado)}  Δ=$${fmt(delta)}`);
          console.log(`       T=$${fmt(resumen.trasladado)}  A=$${fmt(resumen.acreditable)}  R=$${fmt(resumen.retenido)}`);
        }
      }
    }
  }

  console.log(`\n=== Resumen ===`);
  console.log(`  Muestras: ${total}`);
  console.log(`  PASS:     ${pass}`);
  console.log(`  FAIL:     ${fail}`);

  await prisma.$disconnect();
  process.exit(fail > 0 ? 1 : 0);
}

main().catch(async (err) => {
  console.error('Fatal:', err);
  await prisma.$disconnect().catch(() => {});
  process.exit(1);
});
