/**
 * Tests pour le service ErrorHandler
 */

import { ErrorHandler } from '../errorHandler';
import { AxiosError } from 'axios';

// Mock du Toast
const mockToast = {
  current: {
    show: jest.fn()
  }
};

describe('ErrorHandler', () => {
  beforeEach(() => {
    jest.clearAllMocks();
    ErrorHandler.setToast(mockToast as any);
  });

  describe('handleApiError', () => {
    it('should handle 400 Bad Request', () => {
      const error = new AxiosError('Bad Request', '400', undefined, undefined, {
        status: 400,
        data: { error: 'Données invalides' }
      } as any);

      ErrorHandler.handleApiError(error, 'test');

      expect(mockToast.current.show).toHaveBeenCalledWith({
        severity: 'error',
        summary: 'Données invalides',
        detail: 'Données invalides',
        life: 5000
      });
    });

    it('should handle 401 Unauthorized', () => {
      const error = new AxiosError('Unauthorized', '401', undefined, undefined, {
        status: 401,
        data: { error: 'Non autorisé' }
      } as any);

      // Mock window.location
      delete (window as any).location;
      window.location = { href: '' } as any;

      ErrorHandler.handleApiError(error);

      expect(mockToast.current.show).toHaveBeenCalledWith({
        severity: 'error',
        summary: 'Non autorisé',
        detail: 'Veuillez vous reconnecter',
        life: 5000
      });
      expect(window.location.href).toBe('/auth/login');
    });

    it('should handle 404 Not Found', () => {
      const error = new AxiosError('Not Found', '404', undefined, undefined, {
        status: 404,
        data: { error: 'Ressource non trouvée' }
      } as any);

      ErrorHandler.handleApiError(error);

      expect(mockToast.current.show).toHaveBeenCalledWith({
        severity: 'error',
        summary: 'Ressource non trouvée',
        detail: 'Ressource non trouvée',
        life: 5000
      });
    });

    it('should handle 422 Validation Errors', () => {
      const error = new AxiosError('Validation Error', '422', undefined, undefined, {
        status: 422,
        data: {
          error: 'Erreurs de validation',
          details: [
            { field: 'nom', message: 'Le nom est obligatoire' },
            { field: 'email', message: 'Email invalide' }
          ]
        }
      } as any);

      ErrorHandler.handleApiError(error);

      expect(mockToast.current.show).toHaveBeenCalledWith({
        severity: 'error',
        summary: 'Erreurs de validation',
        detail: 'nom: Le nom est obligatoire\nemail: Email invalide',
        life: 5000
      });
    });

    it('should handle 500 Internal Server Error', () => {
      const error = new AxiosError('Internal Server Error', '500', undefined, undefined, {
        status: 500,
        data: { error: 'Erreur serveur' }
      } as any);

      ErrorHandler.handleApiError(error);

      expect(mockToast.current.show).toHaveBeenCalledWith({
        severity: 'error',
        summary: 'Erreur serveur',
        detail: 'Une erreur interne s\'est produite. Veuillez réessayer plus tard.',
        life: 5000
      });
    });

    it('should handle network errors', () => {
      const error = new AxiosError('Network Error');
      error.request = {};

      ErrorHandler.handleApiError(error);

      expect(mockToast.current.show).toHaveBeenCalledWith({
        severity: 'error',
        summary: 'Erreur de connexion',
        detail: 'Impossible de contacter le serveur. Vérifiez votre connexion internet.',
        life: 5000
      });
    });
  });

  describe('validation methods', () => {
    it('should validate required fields', () => {
      const fields = {
        nom: 'John',
        email: '',
        age: null,
        actif: true
      };

      const errors = ErrorHandler.validateRequired(fields);

      expect(errors).toEqual([
        'Le champ "email" est obligatoire',
        'Le champ "age" est obligatoire'
      ]);
    });

    it('should validate email addresses', () => {
      expect(ErrorHandler.validateEmail('test@example.com')).toBe(true);
      expect(ErrorHandler.validateEmail('invalid-email')).toBe(false);
      expect(ErrorHandler.validateEmail('')).toBe(false);
    });

    it('should validate phone numbers', () => {
      expect(ErrorHandler.validatePhoneNumber('01 23 45 67 89')).toBe(true);
      expect(ErrorHandler.validatePhoneNumber('0123456789')).toBe(true);
      expect(ErrorHandler.validatePhoneNumber('+33 1 23 45 67 89')).toBe(true);
      expect(ErrorHandler.validatePhoneNumber('invalid')).toBe(false);
    });

    it('should validate SIRET numbers', () => {
      expect(ErrorHandler.validateSiret('12345678901234')).toBe(false); // Invalid checksum
      expect(ErrorHandler.validateSiret('123456789')).toBe(false); // Too short
      expect(ErrorHandler.validateSiret('abcd')).toBe(false); // Not numeric
    });
  });

  describe('message methods', () => {
    it('should show success message', () => {
      ErrorHandler.showSuccess('Succès', 'Opération réussie');

      expect(mockToast.current.show).toHaveBeenCalledWith({
        severity: 'success',
        summary: 'Succès',
        detail: 'Opération réussie',
        life: 3000
      });
    });

    it('should show warning message', () => {
      ErrorHandler.showWarning('Attention', 'Avertissement');

      expect(mockToast.current.show).toHaveBeenCalledWith({
        severity: 'warn',
        summary: 'Attention',
        detail: 'Avertissement',
        life: 4000
      });
    });

    it('should show info message', () => {
      ErrorHandler.showInfo('Information', 'Message informatif');

      expect(mockToast.current.show).toHaveBeenCalledWith({
        severity: 'info',
        summary: 'Information',
        detail: 'Message informatif',
        life: 3000
      });
    });
  });
});
