import { aTexto, construirFila, filaVacia, normalizarEncabezado, partirRuc, sugerirMapeo } from './leads-import.util';

describe('normalizarEncabezado', () => {
  it('iguala acentos, mayúsculas y signos', () => {
    expect(normalizarEncabezado('Teléfono / Celular')).toBe('telefono celular');
    expect(normalizarEncabezado('  RUC-CI  ')).toBe('ruc ci');
    expect(normalizarEncabezado('Razón Social')).toBe('razon social');
  });
});

describe('sugerirMapeo', () => {
  it('reconoce los encabezados típicos de una planilla de contactos', () => {
    expect(sugerirMapeo(['Nombre y Apellido', 'Celular', 'Correo', 'Empresa'])).toEqual({
      nombre: 'Nombre y Apellido',
      telefono: 'Celular',
      email: 'Correo',
      empresa_nombre: 'Empresa',
    });
  });

  /** Adivinar de más es peor que preguntar: la pantalla deja completar el resto. */
  it('deja sin mapear lo que no reconoce', () => {
    const mapeo = sugerirMapeo(['Nombre', 'Observaciones', 'Zona']);
    expect(mapeo).toEqual({ nombre: 'Nombre' });
  });

  it('no asigna la misma columna a dos campos', () => {
    // "Cliente" es alias de nombre; "Razon Social" también. Gana el primero que encuentra.
    const mapeo = sugerirMapeo(['Cliente', 'Razon Social']);
    const columnas = Object.values(mapeo);
    expect(new Set(columnas).size).toBe(columnas.length);
  });

  it('una planilla vacía no rompe', () => {
    expect(sugerirMapeo([])).toEqual({});
  });
});

describe('partirRuc', () => {
  /** Casi todo el mundo escribe el RUC con el DV pegado. */
  it('separa el DV cuando viene con guion', () => {
    expect(partirRuc('80144315-6', '')).toEqual({ ruc: '80144315', dv: '6' });
  });

  it('usa el DV de su propia columna cuando no hay guion', () => {
    expect(partirRuc('80144315', '6')).toEqual({ ruc: '80144315', dv: '6' });
  });

  it('limpia puntos y espacios', () => {
    expect(partirRuc(' 80.144.315-6 ', '')).toEqual({ ruc: '80144315', dv: '6' });
  });

  it('sin RUC devuelve vacío', () => {
    expect(partirRuc('', '')).toEqual({ ruc: '', dv: '' });
  });
});

describe('aTexto', () => {
  it('convierte lo que Excel entrega como número o fecha', () => {
    expect(aTexto(981123456)).toBe('981123456');
    expect(aTexto(new Date('2026-10-06T00:00:00Z'))).toBe('2026-10-06');
    expect(aTexto(null)).toBe('');
    expect(aTexto('  hola  ')).toBe('hola');
  });
});

describe('construirFila', () => {
  const mapeo = { nombre: 'Nombre', telefono: 'Celular', ruc: 'RUC' } as const;

  it('numera la fila como la ve la persona en Excel (con encabezado)', () => {
    const f = construirFila({ Nombre: 'Ana', Celular: '0981123456', RUC: '' }, mapeo, 2);
    expect(f.fila).toBe(2);
    expect(f).toMatchObject({ nombre: 'Ana', telefono: '0981123456' });
  });

  it('las columnas sin mapear quedan undefined, no vacías', () => {
    const f = construirFila({ Nombre: 'Ana', Celular: '', RUC: '' }, mapeo, 2);
    expect(f.email).toBeUndefined();
    expect(f.telefono).toBeUndefined();
  });

  it('parte el RUC con DV pegado también desde la planilla', () => {
    const f = construirFila({ Nombre: 'DOBA', Celular: '', RUC: '80144315-6' }, mapeo, 3);
    expect(f).toMatchObject({ ruc: '80144315', dv: '6' });
  });
});

describe('filaVacia', () => {
  /** Excel arrastra cientos de filas vacías al final de cualquier planilla. */
  it('detecta la fila sin ninguna celda con contenido', () => {
    expect(filaVacia({ a: '', b: null, c: '   ' })).toBe(true);
    expect(filaVacia({ a: '', b: 'Ana' })).toBe(false);
    expect(filaVacia({ a: 0 })).toBe(false);
  });
});

describe('aTexto con celdas raras', () => {
  /** xlsx puede entregar objetos (celdas con error, hipervínculos). "[object Object]" no es un nombre. */
  it('un objeto no se convierte en texto basura', () => {
    expect(aTexto({ error: '#REF!' })).toBe('');
    expect(aTexto([1, 2])).toBe('');
  });

  it('booleanos y ceros se conservan', () => {
    expect(aTexto(false)).toBe('false');
    expect(aTexto(0)).toBe('0');
  });
});
