/**
 * Genera datos de ejemplo del motor de reglas de precio (Fase 1) para poder
 * probarlo end-to-end. Usa Comercial Kety (empresa real, sin listas de precio
 * aún) como caso de prueba: crea una lista de precios DEMO (no toca sus datos
 * reales) + 4 reglas de marcación por rango de costo, y corre un recálculo
 * acotado a 3 productos de muestra para verificar el flujo completo.
 *
 * Uso: npx ts-node --transpile-only -r tsconfig-paths/register --project tsconfig.scripts.json scripts/seed-reglas-precio-demo.ts
 */
import { PrismaService } from '../src/prisma/prisma.service';
import { AuditService } from '../src/audit/audit.service';
import { PreciosEngineService } from '../src/reglas-precio/precios-engine.service';

const EMPRESA_KETY_ID = 'c9a80e4a-f640-4588-a80e-b0c706f6cd28';

async function main() {
  const prisma = new PrismaService();
  const audit = new AuditService(prisma);
  const engine = new PreciosEngineService(prisma, audit);

  console.log('▶ Creando lista de precios DEMO para Comercial Kety...');
  const lista = await prisma.lista_precios.upsert({
    where: { unique_lista_precios_codigo: { empresa_id: EMPRESA_KETY_ID, codigo: 'DEMO-CONTADO' } },
    update: {},
    create: {
      empresa_id: EMPRESA_KETY_ID,
      codigo: 'DEMO-CONTADO',
      nombre: 'Contado (demo motor de precios)',
      descripcion: 'Lista de prueba generada para validar el motor de reglas de precio (Fase 1). No se usa en ventas reales.',
      tipo_aplicacion: 'general',
      moneda: 'PYG',
      prioridad: 99,
      usuario_creacion: 'seed-demo',
    },
  });
  console.log(`  lista_precios_id = ${lista.id}`);

  console.log('▶ Creando reglas de precio por rango de costo...');
  const tramos = [
    { nombre: 'Costo bajo (0 - 500k) +40%', desde: 0, hasta: 500_000, valor: 40 },
    { nombre: 'Costo medio (500k - 3M) +25%', desde: 500_000, hasta: 3_000_000, valor: 25 },
    { nombre: 'Costo alto (3M - 10M) +18%', desde: 3_000_000, hasta: 10_000_000, valor: 18 },
    { nombre: 'Costo muy alto (10M+) +12%', desde: 10_000_000, hasta: null, valor: 12 },
  ];

  const reglasCreadas: string[] = [];
  for (const tramo of tramos) {
    const existente = await prisma.reglas_precio.findFirst({
      where: { empresa_id: EMPRESA_KETY_ID, lista_precios_id: lista.id, nombre: tramo.nombre },
    });
    if (existente) {
      console.log(`  ya existe: ${tramo.nombre}`);
      reglasCreadas.push(existente.id);
      continue;
    }
    const regla = await engine.crear(
      {
        nombre: tramo.nombre,
        alcance: 'global',
        moneda: 'PYG',
        costoDesde: tramo.desde,
        costoHasta: tramo.hasta ?? undefined,
        metodo: 'margen_sobre_costo',
        valor: tramo.valor,
        redondeoActivo: true,
        redondeoTipo: 'superior',
        redondeoMultiplo: 1000,
        listaPreciosId: lista.id,
      },
      EMPRESA_KETY_ID,
      undefined,
    );
    console.log(`  creada: ${regla.nombre} (${regla.id})`);
    reglasCreadas.push(regla.id);
  }

  console.log('▶ Tomando 3 productos de muestra con costo relevante (>100.000 Gs) para cubrir varios tramos...');
  const candidatos = await prisma.productos.findMany({
    where: { empresa_id: EMPRESA_KETY_ID, deleted: false, precio_costo: { gt: 100_000 } },
    select: { id: true, descripcion: true, precio_costo: true, precio: true },
    orderBy: { precio_costo: 'asc' },
  });
  if (candidatos.length === 0) {
    throw new Error('No se encontraron productos con precio_costo > 100.000 para la demo.');
  }
  const elegidos = [candidatos[0], candidatos[Math.floor(candidatos.length / 2)], candidatos[candidatos.length - 1]].filter(Boolean);
  if (elegidos.length === 0) {
    throw new Error('La selección de productos de muestra quedó vacía; abortando para no disparar un recálculo masivo.');
  }

  console.log('▶ Calculando precio sugerido (solo lectura, sin escribir aún)...');
  for (const p of elegidos) {
    const calculo = await engine.calcularPrecio(p.id, lista.id, EMPRESA_KETY_ID);
    console.log(
      `  ${p.descripcion} | costo=${p.precio_costo} | precio_actual=${p.precio} | sugerido=${calculo.precioSugerido} | ${calculo.desglose}`,
    );
  }

  if (elegidos.length > 5) {
    throw new Error(`Salvaguarda: se esperaban <=5 productos de muestra, se obtuvieron ${elegidos.length}. Abortando.`);
  }
  console.log(`▶ Ejecutando recalcularLista acotado a esos ${elegidos.length} productos (escritura real, alcance limitado)...`);
  const resultado = await engine.recalcularLista(
    {
      listaPreciosId: lista.id,
      productoIds: elegidos.map((p) => p.id),
      preservarOverride: true,
      generarCuotas: true,
    },
    EMPRESA_KETY_ID,
    undefined,
  );
  console.log('  resultado:', JSON.stringify(resultado, null, 2));

  console.log('▶ Verificando lista_precios_productos escritos...');
  const escritos = await prisma.lista_precios_productos.findMany({
    where: { lista_precios_id: lista.id },
    select: { producto_id: true, precio_base: true, origen_precio: true, regla_precio_id: true },
  });
  console.log(JSON.stringify(escritos, null, 2));

  console.log('\n✅ Demo lista:', lista.id, '| Reglas:', reglasCreadas.length, '| Productos con precio calculado:', escritos.length);
  console.log('   Esto NO modificó productos.precio ni ninguna lista real de Comercial Kety — es una lista aparte para pruebas.');

  await prisma.$disconnect();
}

main()
  .then(() => process.exit(0))
  .catch((err) => {
    console.error(err);
    process.exit(1);
  });
