/// Widget for displaying user-friendly error messages with retry capability
library error_display_widget;

import 'package:flutter/material.dart';
import '../../core/error/failures.dart';
import '../design_system/tokens/app_colors.dart';

/// Error display widget that shows failures in a user-friendly way
class ErrorDisplayWidget extends StatelessWidget {
  final Failure failure;
  final VoidCallback? onRetry;
  final bool showRetryButton;

  const ErrorDisplayWidget({
    super.key,
    required this.failure,
    this.onRetry,
    this.showRetryButton = true,
  });

  @override
  Widget build(BuildContext context) {
    return Center(
      child: Padding(
        padding: const EdgeInsets.all(12.0),
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            // Error icon
            Icon(
              _getErrorIcon(),
              size: 40,
              color: _getErrorColor(context),
            ),
            const SizedBox(height: 12),

            // Error title
            Text(
              _getErrorTitle(),
              style: Theme.of(context).textTheme.titleLarge?.copyWith(
                    fontWeight: FontWeight.bold,
                    color: _getErrorColor(context),
                  ),
              textAlign: TextAlign.center,
            ),
            const SizedBox(height: 12),

            // Error message
            Text(
              failure.getUserMessage(),
              style: Theme.of(context).textTheme.bodyLarge?.copyWith(
                    color: Theme.of(context).colorScheme.onSurfaceVariant,
                  ),
              textAlign: TextAlign.center,
            ),

            // Retry button (if retryable and callback provided)
            if (showRetryButton && failure.isRetryable && onRetry != null) ...[
              const SizedBox(height: 16),
              ElevatedButton.icon(
                onPressed: onRetry,
                icon: const Icon(Icons.refresh),
                label: const Text('Réessayer'),
                style: ElevatedButton.styleFrom(
                  padding: const EdgeInsets.symmetric(
                    horizontal: 32,
                    vertical: 10,
                  ),
                ),
              ),
            ],
          ],
        ),
      ),
    );
  }

  /// Get appropriate icon for error type
  IconData _getErrorIcon() {
    if (failure is NetworkFailure) {
      return Icons.wifi_off;
    } else if (failure is UnauthorizedFailure) {
      return Icons.lock_outline;
    } else if (failure is ForbiddenFailure) {
      return Icons.block;
    } else if (failure is NotFoundFailure) {
      return Icons.search_off;
    } else if (failure is ValidationFailure) {
      return Icons.error_outline;
    } else if (failure is ServerFailure) {
      return Icons.cloud_off;
    } else if (failure is NotImplementedFailure) {
      return Icons.construction;
    } else {
      return Icons.warning_amber;
    }
  }

  /// Get appropriate color for error type
  Color _getErrorColor(BuildContext context) {
    if (failure is NetworkFailure) {
      return AppColors.warning;
    } else if (failure is UnauthorizedFailure) {
      return AppColors.error;
    } else if (failure is ForbiddenFailure) {
      return AppColors.warning;
    } else if (failure is ValidationFailure) {
      return AppColors.warningUI;
    } else if (failure is NotImplementedFailure) {
      return AppColors.info;
    } else {
      return Theme.of(context).colorScheme.error;
    }
  }

  /// Get appropriate title for error type
  String _getErrorTitle() {
    if (failure is NetworkFailure) {
      return 'Problème de connexion';
    } else if (failure is UnauthorizedFailure) {
      return 'Session expirée';
    } else if (failure is ForbiddenFailure) {
      return 'Accès refusé';
    } else if (failure is NotFoundFailure) {
      return 'Non trouvé';
    } else if (failure is ValidationFailure) {
      return 'Données invalides';
    } else if (failure is ServerFailure) {
      return 'Erreur serveur';
    } else if (failure is NotImplementedFailure) {
      return 'Bientôt disponible';
    } else {
      return 'Une erreur est survenue';
    }
  }
}

/// Compact error banner for inline display
class ErrorBanner extends StatelessWidget {
  final Failure failure;
  final VoidCallback? onRetry;
  final VoidCallback? onDismiss;

  const ErrorBanner({
    super.key,
    required this.failure,
    this.onRetry,
    this.onDismiss,
  });

  @override
  Widget build(BuildContext context) {
    return Container(
      margin: const EdgeInsets.all(16),
      padding: const EdgeInsets.all(10),
      decoration: BoxDecoration(
        color: _getErrorColor(context).withOpacity(0.1),
        border: Border.all(
          color: _getErrorColor(context),
          width: 1,
        ),
        borderRadius: BorderRadius.circular(8),
      ),
      child: Row(
        children: [
          Icon(
            _getErrorIcon(),
            color: _getErrorColor(context),
          ),
          const SizedBox(width: 12),
          Expanded(
            child: Column(
              crossAxisAlignment: CrossAxisAlignment.start,
              children: [
                Text(
                  _getErrorTitle(),
                  style: TextStyle(
                    fontWeight: FontWeight.bold,
                    color: _getErrorColor(context),
                  ),
                ),
                const SizedBox(height: 4),
                Text(
                  failure.getUserMessage(),
                  style: TextStyle(
                    fontSize: 13,
                    color: Theme.of(context).colorScheme.onSurfaceVariant,
                  ),
                ),
              ],
            ),
          ),
          if (failure.isRetryable && onRetry != null)
            TextButton(
              onPressed: onRetry,
              child: const Text('Réessayer'),
            ),
          if (onDismiss != null)
            IconButton(
              icon: const Icon(Icons.close, size: 20),
              onPressed: onDismiss,
              padding: EdgeInsets.zero,
              constraints: const BoxConstraints(),
            ),
        ],
      ),
    );
  }

  IconData _getErrorIcon() {
    if (failure is NetworkFailure) {
      return Icons.wifi_off;
    } else if (failure is UnauthorizedFailure) {
      return Icons.lock_outline;
    } else if (failure is ForbiddenFailure) {
      return Icons.block;
    } else if (failure is NotFoundFailure) {
      return Icons.search_off;
    } else if (failure is ValidationFailure) {
      return Icons.error_outline;
    } else if (failure is ServerFailure) {
      return Icons.cloud_off;
    } else if (failure is NotImplementedFailure) {
      return Icons.construction;
    } else {
      return Icons.warning_amber;
    }
  }

  Color _getErrorColor(BuildContext context) {
    if (failure is NetworkFailure) {
      return AppColors.warning;
    } else if (failure is UnauthorizedFailure) {
      return AppColors.error;
    } else if (failure is ForbiddenFailure) {
      return AppColors.warning;
    } else if (failure is ValidationFailure) {
      return AppColors.warningUI;
    } else if (failure is NotImplementedFailure) {
      return AppColors.info;
    } else {
      return Theme.of(context).colorScheme.error;
    }
  }

  String _getErrorTitle() {
    if (failure is NetworkFailure) {
      return 'Problème de connexion';
    } else if (failure is UnauthorizedFailure) {
      return 'Session expirée';
    } else if (failure is ForbiddenFailure) {
      return 'Accès refusé';
    } else if (failure is NotFoundFailure) {
      return 'Non trouvé';
    } else if (failure is ValidationFailure) {
      return 'Données invalides';
    } else if (failure is ServerFailure) {
      return 'Erreur serveur';
    } else if (failure is NotImplementedFailure) {
      return 'Bientôt disponible';
    } else {
      return 'Erreur';
    }
  }
}

/// Show error as a SnackBar
void showErrorSnackBar(
  BuildContext context,
  Failure failure, {
  VoidCallback? onRetry,
}) {
  final snackBar = SnackBar(
    content: Row(
      children: [
        Icon(
          failure is NetworkFailure ? Icons.wifi_off : Icons.error_outline,
          color: Colors.white,
        ),
        const SizedBox(width: 12),
        Expanded(
          child: Text(failure.getUserMessage()),
        ),
      ],
    ),
    backgroundColor: failure is NetworkFailure ? AppColors.warning : AppColors.error,
    behavior: SnackBarBehavior.floating,
    action: failure.isRetryable && onRetry != null
        ? SnackBarAction(
            label: 'Réessayer',
            textColor: Colors.white,
            onPressed: onRetry,
          )
        : null,
    duration: Duration(seconds: failure.isRetryable ? 6 : 4),
  );

  ScaffoldMessenger.of(context).showSnackBar(snackBar);
}
