import { BadGatewayException, PreconditionFailedException } from '@nestjs/common';
import { MarangatuSyncService } from '../marangatu-sync.service';

/**
 * Captura manual en producción devolvía un 500 pelado: el bot respondía 404
 * "Empresa no encontrada" porque la empresa de la sesión no tenía credenciales
 * cargadas (o el alta en el bot había fallado en silencio) y el error genérico
 * del fetch se propagaba tal cual.
 */
describe('MarangatuSyncService.triggerSync — errores claros y auto-registro', () => {
  const EMPRESA = { id: 'emp-1', ruc: '2009839', dv: 1, razon_social: 'Roberto Escobar' };
  const respuesta = (status: number, body: unknown) => ({
    ok: status < 400,
    status,
    json: async () => body,
    text: async () => JSON.stringify(body),
  });

  let fetchMock: jest.Mock;
  const crear = (config: unknown) => {
    const prisma: any = { empresas: { findUnique: jest.fn().mockResolvedValue(EMPRESA) } };
    const configService: any = {
      getConfig: jest.fn().mockResolvedValue(config),
      getFullConfig: jest.fn().mockResolvedValue({ username: '2009839' }),
      getPassword: jest.fn().mockResolvedValue('secreto'),
    };
    return new MarangatuSyncService(prisma, configService, null as any, null as any);
  };

  beforeEach(() => {
    fetchMock = jest.fn();
    global.fetch = fetchMock as any;
  });

  it('sin credenciales cargadas no llama al bot y explica qué falta', async () => {
    const service = crear(null);
    await expect(service.triggerSync('emp-1', 'VENTAS', { anho: 2026, mes: 4 })).rejects.toBeInstanceOf(PreconditionFailedException);
    expect(fetchMock).not.toHaveBeenCalled();
  });

  it('si el bot no conoce la empresa, la registra y reintenta', async () => {
    const service = crear({ username: '2009839' });
    fetchMock
      .mockResolvedValueOnce(respuesta(404, { message: 'Empresa no encontrada' }))
      .mockResolvedValueOnce(respuesta(201, { status: 'success' }))
      .mockResolvedValueOnce(respuesta(202, { status: 'success', message: 'Sincronización encolada' }));

    const resultado = await service.triggerSync('emp-1', 'VENTAS', { anho: 2026, mes: 4 });

    const rutas = fetchMock.mock.calls.map(([url]) => String(url).replace(/^https?:\/\/[^/]+/, ''));
    expect(rutas).toEqual(['/api/sincronizacion-documentos', '/api/empresas/alta-integrada', '/api/sincronizacion-documentos']);
    expect(resultado.message).toContain('VENTAS');
  });

  it('otros errores del bot llegan con su mensaje como 502, no como 500 genérico', async () => {
    const service = crear({ username: '2009839' });
    fetchMock.mockResolvedValueOnce(respuesta(409, { message: 'Empresa inactiva para sincronización' }));

    const err = await service.triggerSync('emp-1', 'VENTAS', { anho: 2026, mes: 4 }).catch((e) => e);
    expect(err).toBeInstanceOf(BadGatewayException);
    expect(err.message).toContain('Empresa inactiva');
  });
});
