import 'package:em2rp/services/api_service.dart';
import 'package:flutter/material.dart';

/// Utilitaires partages pour la suppression d'equipement avec forcage.
class EquipmentDeleteUtils {
  static const String _legacyConflictToken = 'future_event_assignment';
  static const List<String> _conflictMessageTokens = [
    'cannot delete equipment because it is assigned to upcoming events',
    'cannot delete equipment because it is assigned to future events',
    'assigned to upcoming events',
    'assigned to future events',
  ];

  static const String deleteDialogTitle = 'Confirmer la suppression';
  static const String deleteDialogCancelLabel = 'Annuler';
  static const String deleteDialogConfirmLabel = 'Supprimer';
  static const String deleteSuccessMessage = 'Équipement supprimé avec succès';

  /// Retourne [name] si renseigne, sinon [id].
  static String resolveEquipmentLabel({required String id, String? name}) {
    final trimmedName = name?.trim();
    if (trimmedName == null || trimmedName.isEmpty) {
      return id;
    }
    return trimmedName;
  }

  /// Construit le message de confirmation de suppression d'un equipement.
  static String buildSingleDeleteConfirmationMessage(String equipmentLabel) {
    return 'Voulez-vous vraiment supprimer "$equipmentLabel" ?\n\n'
        'Cette action est irréversible.';
  }

  /// Construit le message de confirmation de suppression multiple.
  static String buildBulkDeleteConfirmationMessage(int selectedCount) {
    return 'Voulez-vous vraiment supprimer $selectedCount équipement(s) ?\n\n'
        'Cette action est irréversible.';
  }

  /// Construit le message de succes de suppression multiple.
  static String buildBulkDeleteSuccessMessage(int deletedCount) {
    return '$deletedCount équipement(s) supprimé(s) avec succès';
  }

  /// Construit un message d'erreur de suppression homogene.
  static String buildDeleteErrorMessage(Object error) {
    return 'Erreur lors de la suppression : $error';
  }

  /// Indique si l'erreur correspond a un conflit de suppression 409.
  static bool isFutureAssignmentDeleteConflict(Object error) {
    if (error is ApiException && !error.isConflict) {
      return false;
    }

    final normalizedMessage = _normalizeErrorMessage(error);
    if (normalizedMessage.contains(_legacyConflictToken)) {
      return true;
    }

    return _conflictMessageTokens.any(normalizedMessage.contains);
  }

  /// Affiche la confirmation de suppression forcee.
  static Future<bool> showForceDeleteDialog(
    BuildContext context, {
    required String equipmentLabel,
  }) async {
    final shouldForceDelete = await showDialog<bool>(
      context: context,
      builder: (dialogContext) => AlertDialog(
        title: const Text('Équipement utilisé dans un événement à venir'),
        content: Text(
          '"$equipmentLabel" est assigné à au moins un événement à venir.\n\n'
          'Voulez-vous forcer la suppression ?',
        ),
        actions: [
          TextButton(
            onPressed: () => Navigator.pop(dialogContext, false),
            child: const Text('Annuler'),
          ),
          TextButton(
            onPressed: () => Navigator.pop(dialogContext, true),
            style: TextButton.styleFrom(foregroundColor: Colors.red),
            child: const Text('Forcer la suppression'),
          ),
        ],
      ),
    );

    return shouldForceDelete == true;
  }

  /// Execute une suppression, puis propose un forcage en cas de conflit 409.
  static Future<bool> deleteWithFutureAssignmentCheck({
    required BuildContext context,
    required String equipmentLabel,
    required Future<void> Function({bool forceDelete}) deleteEquipment,
  }) async {
    try {
      await deleteEquipment(forceDelete: false);
      return true;
    } catch (error) {
      if (!isFutureAssignmentDeleteConflict(error)) {
        rethrow;
      }

      if (!context.mounted) {
        return false;
      }

      final shouldForceDelete = await showForceDeleteDialog(
        context,
        equipmentLabel: equipmentLabel,
      );
      if (!shouldForceDelete) {
        return false;
      }

      await deleteEquipment(forceDelete: true);
      return true;
    }
  }

  static String _normalizeErrorMessage(Object error) {
    if (error is ApiException) {
      return error.message.toLowerCase();
    }
    return error.toString().toLowerCase();
  }
}
