import { afterEach, beforeEach, describe, expect, it } from 'vitest';
import { ErrorType } from '../../components/models';
import { mapError, setErrorMappers } from './ErrorMapper';
import { ErrorMapper } from './ErrorMapper.type';

describe('mapError', () => {
  const errorMapper1: ErrorMapper = (error) => {
    if (typeof error === 'string') {
      return { title: 'String Error', body: error };
    }
    return undefined;
  };

  const errorMapper2: ErrorMapper = (error) => {
    if (typeof error === 'number') {
      return { title: 'Number Error', body: error.toString() };
    }
    return undefined;
  };

  const errorMapper3: ErrorMapper = (error) => {
    if (error instanceof Error) {
      return { title: 'Custom Error', body: error.message };
    }
    return undefined;
  };

  beforeEach(() => {
    setErrorMappers([errorMapper1, errorMapper2, errorMapper3]);
  });

  afterEach(() => {
    setErrorMappers([]);
  });

  it('should map a string error', () => {
    const error: ErrorType = 'Something went wrong';
    const mappedError = mapError(error);
    expect(mappedError).toEqual({
      title: 'String Error',
      body: 'Something went wrong',
    });
  });

  it('should map a number error', () => {
    const error: ErrorType = 42;
    const mappedError = mapError(error);
    expect(mappedError).toEqual({ title: 'Number Error', body: '42' });
  });

  it('should map a custom error', () => {
    const error: ErrorType = new Error('Custom error message');
    const mappedError = mapError(error);
    expect(mappedError).toEqual({
      title: 'Custom Error',
      body: 'Custom error message',
    });
  });

  it('should return the original error if no mapper can map it', () => {
    const error: ErrorType = {
      title: 'Unknown Error',
      body: 'Something unexpected happened',
    };
    const mappedError = mapError(error);
    expect(mappedError).toBe(error);
  });
});
