import logger from '@zenvia/logger';
import { ZenviaLogger } from './zenvia-logger';

jest.mock('@zenvia/logger');

describe('ZenviaLogger', () => {
  let errorMock: jest.Mock;
  let warnMock: jest.Mock;
  let infoMock: jest.Mock;
  let debugMock: jest.Mock;

  beforeAll(() => {
    errorMock = jest.fn();
    logger.error = errorMock;

    warnMock = jest.fn();
    logger.warn = warnMock;

    infoMock = jest.fn();
    logger.info = infoMock;

    debugMock = jest.fn();
    logger.debug = debugMock;
  });

  // Log an error message successfully
  it('should log an error message successfully', async () => {
    const zenviaLogger = new ZenviaLogger();

    await zenviaLogger.error('Error message');

    expect(errorMock).toHaveBeenCalledWith('Error message');
  });

  // Log a warning message successfully
  it('should log a warning message successfully', async () => {
    const zenviaLogger = new ZenviaLogger();

    await zenviaLogger.warn('Warning message');

    expect(warnMock).toHaveBeenCalledWith('Warning message');
  });

  // Log an info message successfully
  it('should log an info message successfully', async () => {
    const zenviaLogger = new ZenviaLogger();

    await zenviaLogger.info('Info message');

    expect(infoMock).toHaveBeenCalledWith('Info message');
  });

  // Log an info message with additional parameters
  it('should log an info message with additional parameters successfully', async () => {
    const zenviaLogger = new ZenviaLogger();

    await zenviaLogger.info('Info message', 'param1', 'param2');

    expect(infoMock).toHaveBeenCalledWith('Info message', 'param1', 'param2');
  });

  // Log an error message with additional parameters
  it('should log an error message with additional parameters successfully', async () => {
    const zenviaLogger = new ZenviaLogger();

    await zenviaLogger.error('Error message', 'param1', 'param2');

    expect(errorMock).toHaveBeenCalledWith('Error message', 'param1', 'param2');
  });

  // Log a warning message with additional parameters
  it('should log a warning message with additional parameters successfully', async () => {
    const zenviaLogger = new ZenviaLogger();

    const message = 'Warning message';
    const param1 = 'param1';
    const param2 = 'param2';

    await zenviaLogger.warn(message, param1, param2);

    expect(warnMock).toHaveBeenCalledWith(message, param1, param2);
  });

  // Log a debug message with additional parameters
  it('should log a debug message with additional parameters successfully', async () => {
    const zenviaLogger = new ZenviaLogger();

    await zenviaLogger.debug('Debug message', 'param1', 'param2');

    expect(debugMock).toHaveBeenCalledWith('Debug message', 'param1', 'param2');
  });

  // Log a message with special characters
  it('should log a message with special characters successfully', async () => {
    const zenviaLogger = new ZenviaLogger();

    const message = 'Special characters: !@#$%^&*()_+{}|:"<>?';

    await zenviaLogger.error(message);

    expect(errorMock).toHaveBeenCalledWith(message);
  });

  // Log a message with a long string
  it('should log a message with a long string successfully', async () => {
    const zenviaLogger = new ZenviaLogger();

    const longString = 'This is a very long string that exceeds the maximum length allowed for a log message. This is just a test to check if the logger can handle long strings properly.';

    await zenviaLogger.error(longString);

    expect(errorMock).toHaveBeenCalledWith(longString);
  });

  // Log a message with a number
  it('should log a message with a number successfully', async () => {
    const zenviaLogger = new ZenviaLogger();

    await zenviaLogger.error('Error message', 123);

    expect(errorMock).toHaveBeenCalledWith('Error message', 123);
  });

  // Log a message with an object
  it('should log a message with an object successfully', async () => {
    const zenviaLogger = new ZenviaLogger();

    const message = 'Error message';
    const obj = { key: 'value' };

    await zenviaLogger.error(message, obj);

    expect(errorMock).toHaveBeenCalledWith(message, obj);
  });

  // Log a message with an array
  it('should log a message with an array successfully', async () => {
    const zenviaLogger = new ZenviaLogger();

    const message = 'Error message';
    const array = [1, 2, 3];

    await zenviaLogger.error(message, array);

    expect(errorMock).toHaveBeenCalledWith(message, array);
  });

  // Log a debug message successfully
  it('should log a debug message successfully', async () => {
    const zenviaLogger = new ZenviaLogger();

    await zenviaLogger.debug('Debug message');

    expect(debugMock).toHaveBeenCalledWith('Debug message');
  });
});
