/**
 * Service centralisé de gestion d'erreurs pour BTP Xpress
 */

import { Toast } from 'primereact/toast';
import { AxiosError } from 'axios';

export interface ErrorDetails {
  code?: string;
  message: string;
  field?: string;
  severity: 'error' | 'warn' | 'info';
}

export interface ApiErrorResponse {
  error: string;
  message?: string;
  details?: ErrorDetails[];
  timestamp?: string;
  path?: string;
}

export class ErrorHandler {
  private static toast: React.RefObject<Toast> | null = null;

  static setToast(toastRef: React.RefObject<Toast>) {
    this.toast = toastRef;
  }

  /**
   * Gère les erreurs API avec messages appropriés
   */
  static handleApiError(error: unknown, context?: string): void {
    console.error(`Erreur API ${context ? `(${context})` : ''}:`, error);

    if (error instanceof AxiosError) {
      const response = error.response;
      
      if (response) {
        const status = response.status;
        const data = response.data as ApiErrorResponse;
        
        switch (status) {
          case 400:
            this.showError('Données invalides', data.message || data.error || 'Vérifiez les informations saisies');
            break;
          case 401:
            this.showError('Non autorisé', 'Veuillez vous reconnecter');
            // Ne pas rediriger si on est en train de traiter un code d'autorisation
            if (typeof window !== 'undefined') {
              const currentUrl = window.location.href;
              const hasAuthCode = currentUrl.includes('code=') && currentUrl.includes('/dashboard');

              if (!hasAuthCode) {
                // Rediriger vers la page de connexion
                window.location.href = '/api/auth/login';
              } else {
                console.log('🔄 ErrorHandler: Erreur 401 ignorée car authentification en cours...');
              }
            }
            break;
          case 403:
            this.showError('Accès refusé', 'Vous n\'avez pas les permissions nécessaires');
            break;
          case 404:
            this.showError('Ressource non trouvée', data.message || 'L\'élément demandé n\'existe pas');
            break;
          case 409:
            this.showError('Conflit', data.message || 'Cette opération entre en conflit avec l\'état actuel');
            break;
          case 422:
            this.handleValidationErrors(data);
            break;
          case 500:
            this.showError('Erreur serveur', 'Une erreur interne s\'est produite. Veuillez réessayer plus tard.');
            break;
          case 503:
            this.showError('Service indisponible', 'Le service est temporairement indisponible');
            break;
          default:
            this.showError('Erreur réseau', `Erreur ${status}: ${data.message || data.error || 'Erreur inconnue'}`);
        }
      } else if (error.request) {
        this.showError('Erreur de connexion', 'Impossible de contacter le serveur. Vérifiez votre connexion internet.');
      } else {
        this.showError('Erreur', error.message || 'Une erreur inattendue s\'est produite');
      }
    } else if (error instanceof Error) {
      this.showError('Erreur', error.message);
    } else {
      this.showError('Erreur', 'Une erreur inconnue s\'est produite');
    }
  }

  /**
   * Gère les erreurs de validation (422)
   */
  private static handleValidationErrors(data: ApiErrorResponse): void {
    if (data.details && data.details.length > 0) {
      const messages = data.details.map(detail => 
        detail.field ? `${detail.field}: ${detail.message}` : detail.message
      );
      this.showError('Erreurs de validation', messages.join('\n'));
    } else {
      this.showError('Erreur de validation', data.message || data.error || 'Données invalides');
    }
  }

  /**
   * Affiche un message d'erreur
   */
  static showError(summary: string, detail: string): void {
    if (this.toast?.current) {
      this.toast.current.show({
        severity: 'error',
        summary,
        detail,
        life: 5000
      });
    } else {
      console.error(`${summary}: ${detail}`);
    }
  }

  /**
   * Affiche un message d'avertissement
   */
  static showWarning(summary: string, detail: string): void {
    if (this.toast?.current) {
      this.toast.current.show({
        severity: 'warn',
        summary,
        detail,
        life: 4000
      });
    } else {
      console.warn(`${summary}: ${detail}`);
    }
  }

  /**
   * Affiche un message de succès
   */
  static showSuccess(summary: string, detail: string): void {
    if (this.toast?.current) {
      this.toast.current.show({
        severity: 'success',
        summary,
        detail,
        life: 3000
      });
    } else {
      console.log(`${summary}: ${detail}`);
    }
  }

  /**
   * Affiche un message d'information
   */
  static showInfo(summary: string, detail: string): void {
    if (this.toast?.current) {
      this.toast.current.show({
        severity: 'info',
        summary,
        detail,
        life: 3000
      });
    } else {
      console.info(`${summary}: ${detail}`);
    }
  }

  /**
   * Valide les champs obligatoires
   */
  static validateRequired(fields: Record<string, any>): string[] {
    const errors: string[] = [];
    
    Object.entries(fields).forEach(([fieldName, value]) => {
      if (value === null || value === undefined || 
          (typeof value === 'string' && value.trim() === '') ||
          (Array.isArray(value) && value.length === 0)) {
        errors.push(`Le champ "${fieldName}" est obligatoire`);
      }
    });
    
    return errors;
  }

  /**
   * Valide un email
   */
  static validateEmail(email: string): boolean {
    const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
    return emailRegex.test(email);
  }

  /**
   * Valide un numéro de téléphone français
   */
  static validatePhoneNumber(phone: string): boolean {
    const phoneRegex = /^(?:(?:\+|00)33|0)\s*[1-9](?:[\s.-]*\d{2}){4}$/;
    return phoneRegex.test(phone);
  }

  /**
   * Valide un SIRET
   */
  static validateSiret(siret: string): boolean {
    if (!siret || siret.length !== 14) return false;
    
    const digits = siret.replace(/\s/g, '').split('').map(Number);
    if (digits.some(isNaN)) return false;
    
    // Algorithme de validation SIRET
    let sum = 0;
    for (let i = 0; i < 14; i++) {
      let digit = digits[i];
      if (i % 2 === 1) {
        digit *= 2;
        if (digit > 9) digit -= 9;
      }
      sum += digit;
    }
    
    return sum % 10 === 0;
  }
}
