import { ORIGENES_MOVIMIENTO, describirOrigen, resolverOrigenes } from './origen-movimiento';

describe('describirOrigen', () => {
  it('dice qué documento lo generó y dónde se anula', () => {
    const o = describirOrigen('CHEQUE_DEPOSITADO', null);
    expect(o).toMatchObject({ etiqueta: 'Cheque depositado', pantalla: 'Tesorería → Cheques', ruta: '/tesoreria?tab=cheques' });
  });

  it('un origen desconocido no rompe: se explica en genérico', () => {
    const o = describirOrigen('ALGO_NUEVO', null);
    expect(o.etiqueta).toBe('Documento vinculado');
    expect(o.ruta).toBeNull();
  });

  it('sin origen, el movimiento es manual y se puede anular acá', () => {
    expect(describirOrigen(null, null)).toBeNull();
  });

  it('incluye los datos del documento cuando se pudieron leer', () => {
    const o = describirOrigen('gasto_cab', { numero: '0001256', fecha: new Date(2026, 8, 18), estado: 'pagada', anulado: false });
    expect(o).toMatchObject({ numero: '0001256', estado: 'pagada', anulado: false });
  });

  it('avisa cuando el documento de origen ya está anulado', () => {
    // Si el documento ya se anuló y el movimiento sigue vivo, el usuario tiene
    // que poder resolverlo: es el único caso donde anular acá tiene sentido.
    const o = describirOrigen('gasto_cab', { numero: '7', fecha: new Date(), estado: 'anulado', anulado: true });
    expect(o!.anulado).toBe(true);
    expect(o!.permiteAnularDirecto).toBe(true);
  });
});

describe('resolverOrigenes', () => {
  it('agrupa por tipo y hace una consulta por tipo, no una por movimiento', async () => {
    const consultas: string[] = [];
    const movs = [
      { id: 'm1', origen_tipo: 'gasto_cab', origen_id: 'g1' },
      { id: 'm2', origen_tipo: 'gasto_cab', origen_id: 'g2' },
      { id: 'm3', origen_tipo: 'CHEQUE_DEPOSITADO', origen_id: 'c1' },
      { id: 'm4', origen_tipo: null, origen_id: null },
    ];
    const mapa = await resolverOrigenes(movs, async (tipo, ids) => {
      consultas.push(`${tipo}:${ids.length}`);
      return new Map(ids.map((id) => [id, { numero: `N-${id}`, fecha: new Date(2026, 0, 1), estado: 'ok', anulado: false }]));
    });
    expect(consultas.sort()).toEqual(['CHEQUE_DEPOSITADO:1', 'gasto_cab:2']);
    expect(mapa.get('m1')).toMatchObject({ etiqueta: 'Gasto', numero: 'N-g1' });
    expect(mapa.get('m4')).toBeUndefined();
  });

  it('si el documento ya no existe, igual explica de dónde vino', async () => {
    const mapa = await resolverOrigenes([{ id: 'm1', origen_tipo: 'gasto_cab', origen_id: 'borrado' }], async () => new Map());
    expect(mapa.get('m1')).toMatchObject({ etiqueta: 'Gasto', numero: null });
  });

  it('todos los orígenes del catálogo dicen dónde se anulan', () => {
    const incompletos = Object.entries(ORIGENES_MOVIMIENTO)
      .filter(([, meta]) => !meta.pantalla || !meta.etiqueta)
      .map(([tipo]) => tipo);
    expect(incompletos).toEqual([]);
  });
});
