import 'package:flutter/material.dart';
import '../../core/constants/design_system.dart';

/// Types de SnackBar selon le contexte
enum SnackBarType {
  success,
  error,
  warning,
  info,
}

/// Affiche un SnackBar personnalisé avec style moderne
///
/// **Usage:**
/// ```dart
/// showCustomSnackBar(
///   context,
///   message: 'Événement créé avec succès',
///   type: SnackBarType.success,
/// );
/// ```
void showCustomSnackBar(
  BuildContext context, {
  required String message,
  SnackBarType type = SnackBarType.info,
  Duration duration = const Duration(seconds: 3),
  String? actionLabel,
  VoidCallback? onActionPressed,
}) {
  final theme = Theme.of(context);
  final isDark = theme.brightness == Brightness.dark;

  // Couleurs selon le type
  Color backgroundColor;
  Color textColor;
  IconData icon;

  switch (type) {
    case SnackBarType.success:
      backgroundColor = const Color(0xFF4CAF50);
      textColor = Colors.white;
      icon = Icons.check_circle;
      break;
    case SnackBarType.error:
      backgroundColor = const Color(0xFFF44336);
      textColor = Colors.white;
      icon = Icons.error;
      break;
    case SnackBarType.warning:
      backgroundColor = const Color(0xFFFF9800);
      textColor = Colors.white;
      icon = Icons.warning;
      break;
    case SnackBarType.info:
      backgroundColor = isDark ? theme.colorScheme.surface : Colors.grey[800]!;
      textColor = Colors.white;
      icon = Icons.info;
      break;
  }

  ScaffoldMessenger.of(context).showSnackBar(
    SnackBar(
      content: Row(
        children: [
          Icon(icon, color: textColor, size: DesignSystem.iconSizeMd),
          DesignSystem.horizontalSpace(DesignSystem.spacingMd),
          Expanded(
            child: Text(
              message,
              style: TextStyle(
                color: textColor,
                fontSize: 14,
                fontWeight: FontWeight.w500,
              ),
            ),
          ),
        ],
      ),
      backgroundColor: backgroundColor,
      behavior: SnackBarBehavior.floating,
      shape: RoundedRectangleBorder(
        borderRadius: DesignSystem.borderRadiusMd,
      ),
      margin: DesignSystem.paddingAll(DesignSystem.spacingLg),
      duration: duration,
      action: actionLabel != null
          ? SnackBarAction(
              label: actionLabel,
              textColor: textColor,
              onPressed: onActionPressed ?? () {},
            )
          : null,
    ),
  );
}

/// Toast flottant avec animation
///
/// Alternative élégante au SnackBar, s'affiche en haut de l'écran.
class CustomToast {
  static OverlayEntry? _overlayEntry;
  static bool _isVisible = false;

  /// Affiche un toast personnalisé
  static void show(
    BuildContext context, {
    required String message,
    SnackBarType type = SnackBarType.info,
    Duration duration = const Duration(seconds: 2),
    ToastPosition position = ToastPosition.top,
  }) {
    if (_isVisible) {
      hide();
    }

    final theme = Theme.of(context);
    final isDark = theme.brightness == Brightness.dark;

    // Couleurs selon le type
    Color backgroundColor;
    Color textColor;
    IconData icon;

    switch (type) {
      case SnackBarType.success:
        backgroundColor = const Color(0xFF4CAF50);
        textColor = Colors.white;
        icon = Icons.check_circle;
        break;
      case SnackBarType.error:
        backgroundColor = const Color(0xFFF44336);
        textColor = Colors.white;
        icon = Icons.error;
        break;
      case SnackBarType.warning:
        backgroundColor = const Color(0xFFFF9800);
        textColor = Colors.white;
        icon = Icons.warning;
        break;
      case SnackBarType.info:
        backgroundColor =
            isDark ? theme.colorScheme.surface : Colors.grey[800]!;
        textColor = Colors.white;
        icon = Icons.info;
        break;
    }

    _overlayEntry = OverlayEntry(
      builder: (context) => _ToastWidget(
        message: message,
        backgroundColor: backgroundColor,
        textColor: textColor,
        icon: icon,
        position: position,
        onDismiss: hide,
      ),
    );

    final overlay = Overlay.of(context);
    overlay.insert(_overlayEntry!);
    _isVisible = true;

    // Auto-dismiss après la durée spécifiée
    Future.delayed(duration, () {
      hide();
    });
  }

  /// Cache le toast
  static void hide() {
    if (_isVisible && _overlayEntry != null) {
      _overlayEntry!.remove();
      _overlayEntry = null;
      _isVisible = false;
    }
  }
}

/// Position du toast
enum ToastPosition {
  top,
  center,
  bottom,
}

/// Widget interne pour afficher le toast avec animation
class _ToastWidget extends StatefulWidget {
  const _ToastWidget({
    required this.message,
    required this.backgroundColor,
    required this.textColor,
    required this.icon,
    required this.position,
    required this.onDismiss,
  });

  final String message;
  final Color backgroundColor;
  final Color textColor;
  final IconData icon;
  final ToastPosition position;
  final VoidCallback onDismiss;

  @override
  State<_ToastWidget> createState() => _ToastWidgetState();
}

class _ToastWidgetState extends State<_ToastWidget>
    with SingleTickerProviderStateMixin {
  late AnimationController _controller;
  late Animation<double> _fadeAnimation;
  late Animation<Offset> _slideAnimation;

  @override
  void initState() {
    super.initState();
    _controller = AnimationController(
      vsync: this,
      duration: DesignSystem.durationMedium,
    );

    _fadeAnimation = Tween<double>(
      begin: 0.0,
      end: 1.0,
    ).animate(
      CurvedAnimation(
        parent: _controller,
        curve: DesignSystem.curveDecelerate,
      ),
    );

    // Animation de slide selon la position
    Offset beginOffset;
    switch (widget.position) {
      case ToastPosition.top:
        beginOffset = const Offset(0, -1);
        break;
      case ToastPosition.center:
        beginOffset = const Offset(0, 0);
        break;
      case ToastPosition.bottom:
        beginOffset = const Offset(0, 1);
        break;
    }

    _slideAnimation = Tween<Offset>(
      begin: beginOffset,
      end: Offset.zero,
    ).animate(
      CurvedAnimation(
        parent: _controller,
        curve: DesignSystem.curveDecelerate,
      ),
    );

    _controller.forward();
  }

  @override
  void dispose() {
    _controller.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    // Position selon l'énumération
    Alignment alignment;
    EdgeInsets margin;

    switch (widget.position) {
      case ToastPosition.top:
        alignment = Alignment.topCenter;
        margin = EdgeInsets.only(
          top: MediaQuery.of(context).padding.top + DesignSystem.spacingLg,
        );
        break;
      case ToastPosition.center:
        alignment = Alignment.center;
        margin = EdgeInsets.zero;
        break;
      case ToastPosition.bottom:
        alignment = Alignment.bottomCenter;
        margin = EdgeInsets.only(
          bottom:
              MediaQuery.of(context).padding.bottom + DesignSystem.spacingLg,
        );
        break;
    }

    return Positioned.fill(
      child: Align(
        alignment: alignment,
        child: SlideTransition(
          position: _slideAnimation,
          child: FadeTransition(
            opacity: _fadeAnimation,
            child: GestureDetector(
              onTap: () {
                _controller.reverse().then((_) => widget.onDismiss());
              },
              child: Container(
                margin: margin +
                    DesignSystem.paddingHorizontal(DesignSystem.spacingLg),
                padding: DesignSystem.paddingAll(DesignSystem.spacingLg),
                decoration: BoxDecoration(
                  color: widget.backgroundColor,
                  borderRadius: DesignSystem.borderRadiusMd,
                  boxShadow: DesignSystem.shadowLg,
                ),
                child: Row(
                  mainAxisSize: MainAxisSize.min,
                  children: [
                    Icon(
                      widget.icon,
                      color: widget.textColor,
                      size: DesignSystem.iconSizeMd,
                    ),
                    DesignSystem.horizontalSpace(DesignSystem.spacingMd),
                    Flexible(
                      child: Text(
                        widget.message,
                        style: TextStyle(
                          color: widget.textColor,
                          fontSize: 14,
                          fontWeight: FontWeight.w500,
                        ),
                        maxLines: 3,
                        overflow: TextOverflow.ellipsis,
                      ),
                    ),
                  ],
                ),
              ),
            ),
          ),
        ),
      ),
    );
  }
}

/// Bottom sheet personnalisé avec design moderne
Future<T?> showCustomBottomSheet<T>({
  required BuildContext context,
  required Widget child,
  bool isDismissible = true,
  bool enableDrag = true,
  Color? backgroundColor,
  double? initialChildSize,
  double? minChildSize,
  double? maxChildSize,
}) {
  final theme = Theme.of(context);

  return showModalBottomSheet<T>(
    context: context,
    isScrollControlled: true,
    isDismissible: isDismissible,
    enableDrag: enableDrag,
    backgroundColor: Colors.transparent,
    builder: (context) => DraggableScrollableSheet(
      initialChildSize: initialChildSize ?? 0.6,
      minChildSize: minChildSize ?? 0.3,
      maxChildSize: maxChildSize ?? 0.9,
      builder: (context, scrollController) => Container(
        decoration: BoxDecoration(
          color: backgroundColor ?? theme.scaffoldBackgroundColor,
          borderRadius: const BorderRadius.vertical(
            top: Radius.circular(DesignSystem.radiusXl),
          ),
          boxShadow: DesignSystem.shadowXl,
        ),
        child: Column(
          children: [
            // Handle pour indiquer qu'on peut glisser
            Container(
              margin: DesignSystem.paddingVertical(DesignSystem.spacingMd),
              width: 40,
              height: 4,
              decoration: BoxDecoration(
                color: theme.dividerColor,
                borderRadius: DesignSystem.borderRadiusRound,
              ),
            ),
            Expanded(
              child: SingleChildScrollView(
                controller: scrollController,
                child: child,
              ),
            ),
          ],
        ),
      ),
    ),
  );
}

/// Dialog personnalisé avec animation élégante
Future<T?> showCustomDialog<T>({
  required BuildContext context,
  required Widget child,
  bool barrierDismissible = true,
}) {
  return showGeneralDialog<T>(
    context: context,
    barrierDismissible: barrierDismissible,
    barrierColor: Colors.black54,
    transitionDuration: DesignSystem.durationMedium,
    transitionBuilder: (context, animation, secondaryAnimation, child) {
      return ScaleTransition(
        scale: Tween<double>(
          begin: 0.8,
          end: 1.0,
        ).animate(
          CurvedAnimation(
            parent: animation,
            curve: DesignSystem.curveDecelerate,
          ),
        ),
        child: FadeTransition(
          opacity: animation,
          child: child,
        ),
      );
    },
    pageBuilder: (context, animation, secondaryAnimation) {
      return Center(
        child: Container(
          margin: DesignSystem.paddingAll(DesignSystem.spacing2xl),
          decoration: BoxDecoration(
            color: Theme.of(context).scaffoldBackgroundColor,
            borderRadius: DesignSystem.borderRadiusXl,
            boxShadow: DesignSystem.shadowXl,
          ),
          child: Material(
            color: Colors.transparent,
            child: child,
          ),
        ),
      );
    },
  );
}

/// Extensions pour faciliter l'utilisation
extension SnackBarExtensions on BuildContext {
  /// Affiche un snackbar de succès
  void showSuccess(String message) {
    showCustomSnackBar(
      this,
      message: message,
      type: SnackBarType.success,
    );
  }

  /// Affiche un snackbar d'erreur
  void showError(String message) {
    showCustomSnackBar(
      this,
      message: message,
      type: SnackBarType.error,
    );
  }

  /// Affiche un snackbar d'avertissement
  void showWarning(String message) {
    showCustomSnackBar(
      this,
      message: message,
      type: SnackBarType.warning,
    );
  }

  /// Affiche un snackbar d'information
  void showInfo(String message) {
    showCustomSnackBar(
      this,
      message: message,
      type: SnackBarType.info,
    );
  }

  /// Affiche un toast de succès
  void toastSuccess(String message) {
    CustomToast.show(
      this,
      message: message,
      type: SnackBarType.success,
    );
  }

  /// Affiche un toast d'erreur
  void toastError(String message) {
    CustomToast.show(
      this,
      message: message,
      type: SnackBarType.error,
    );
  }
}
