import { componerFiltroReferencial, componerPendiente, wherePendiente } from './pendientes';

describe('wherePendiente', () => {
  it('sin campo devuelve un fragmento vacío', () => {
    expect(wherePendiente(undefined)).toEqual({});
  });

  it('costo: null o cero cuentan como pendiente', () => {
    expect(wherePendiente('costo')).toEqual({
      OR: [{ precio_costo: null }, { precio_costo: 0 }],
    });
  });

  it('precio: null o cero cuentan como pendiente', () => {
    expect(wherePendiente('precio')).toEqual({
      OR: [{ precio: null }, { precio: 0 }],
    });
  });

  it('categoria: solo null cuenta como pendiente', () => {
    expect(wherePendiente('categoria')).toEqual({ categoria_id: null });
  });

  it('marca: solo null cuenta como pendiente', () => {
    expect(wherePendiente('marca')).toEqual({ marca_id: null });
  });

  it('un campo desconocido no filtra nada en vez de romper', () => {
    expect(wherePendiente('inventado' as any)).toEqual({});
  });
});

describe('componerPendiente', () => {
  it('no pisa un OR existente: lo compone bajo AND', () => {
    // `findAll` ya usa `whereClause.OR` para la búsqueda por texto. Si el
    // fragmento de pendientes se spreadeara, el segundo OR pisaría al primero
    // y la búsqueda dejaría de filtrar en silencio.
    const where: any = {
      deleted: false,
      empresa_id: 'emp-1',
      OR: [{ descripcion: { contains: 'olla' } }],
    };

    componerPendiente(where, 'costo');

    expect(where.OR).toEqual([{ descripcion: { contains: 'olla' } }]);
    expect(where.AND).toEqual([{ OR: [{ precio_costo: null }, { precio_costo: 0 }] }]);
  });

  it('sin campo pendiente no toca el where', () => {
    const where: any = { deleted: false, empresa_id: 'emp-1' };
    componerPendiente(where, undefined);
    expect(where).toEqual({ deleted: false, empresa_id: 'emp-1' });
  });

  it('acumula sobre un AND preexistente en vez de reemplazarlo', () => {
    const where: any = { AND: [{ active: true }] };
    componerPendiente(where, 'categoria');
    expect(where.AND).toEqual([{ active: true }, { categoria_id: null }]);
  });
});

describe('componerFiltroReferencial', () => {
  const UUID_A = '11111111-1111-1111-1111-111111111111';
  const UUID_B = '22222222-2222-2222-2222-222222222222';

  it('solo "sin" filtra los que no tienen categoría', () => {
    const where: Record<string, any> = {};
    componerFiltroReferencial(where, 'categoria_id', 'sin');
    expect(where.AND).toEqual([{ categoria_id: null }]);
  });

  it('"sin" + un id trae los sin categoría MÁS los de esa categoría', () => {
    const where: Record<string, any> = {};
    componerFiltroReferencial(where, 'categoria_id', `sin,${UUID_A}`);
    expect(where.AND).toEqual([{ OR: [{ categoria_id: null }, { categoria_id: UUID_A }] }]);
  });

  it('sin "sin" mantiene el filtro por ids de siempre', () => {
    const where: Record<string, any> = {};
    componerFiltroReferencial(where, 'marca_id', `${UUID_A},${UUID_B}`);
    expect(where.AND).toEqual([{ marca_id: { in: [UUID_A, UUID_B] } }]);
  });

  it('nunca manda "sin" a Postgres como si fuera un uuid', () => {
    const where: Record<string, any> = {};
    componerFiltroReferencial(where, 'categoria_id', `${UUID_A},sin,${UUID_B}`);
    expect(JSON.stringify(where)).not.toContain('"sin"');
  });

  it('no pisa el OR de la búsqueda por texto', () => {
    const where: Record<string, any> = { OR: [{ descripcion: { contains: 'x' } }] };
    componerFiltroReferencial(where, 'categoria_id', `sin,${UUID_A}`);
    expect(where.OR).toEqual([{ descripcion: { contains: 'x' } }]);
    expect(where.AND).toHaveLength(1);
  });

  it('categoría y marca a la vez se combinan con Y', () => {
    const where: Record<string, any> = {};
    componerFiltroReferencial(where, 'categoria_id', 'sin');
    componerFiltroReferencial(where, 'marca_id', 'sin');
    expect(where.AND).toEqual([{ categoria_id: null }, { marca_id: null }]);
  });

  it('lista vacía o undefined no agrega nada', () => {
    const where: Record<string, any> = {};
    componerFiltroReferencial(where, 'categoria_id', undefined);
    componerFiltroReferencial(where, 'categoria_id', ' , ');
    expect(where.AND).toBeUndefined();
  });
});
