import 'package:flutter/material.dart';

/// Bouton personnalisé moderne et élégant.
///
/// Design épuré avec des proportions optimisées pour une application professionnelle.
/// Supporte Material 3 avec des variantes tonal, outlined et text.
///
/// **Usage:**
/// ```dart
/// CustomButton(
///   text: 'Confirmer',
///   onPressed: () {},
///   variant: ButtonVariant.primary,
///   size: ButtonSize.medium,
/// )
/// ```
class CustomButton extends StatelessWidget {
  const CustomButton({
    required this.text,
    required this.onPressed,
    super.key,
    this.icon,
    this.isLoading = false,
    this.isEnabled = true,
    this.variant = ButtonVariant.primary,
    this.size = ButtonSize.medium,
    this.fullWidth = false,
  });

  final String text;
  final VoidCallback onPressed;
  final IconData? icon;
  final bool isLoading;
  final bool isEnabled;
  final ButtonVariant variant;
  final ButtonSize size;
  final bool fullWidth;

  @override
  Widget build(BuildContext context) {
    final theme = Theme.of(context);
    final isDisabled = !isEnabled || isLoading;

    final buttonStyle = _getButtonStyle(theme, variant, size);
    final textStyle = _getTextStyle(theme, variant, size);

    Widget child = isLoading
        ? SizedBox(
            height: size == ButtonSize.small ? 14 : (size == ButtonSize.medium ? 16 : 18),
            width: size == ButtonSize.small ? 14 : (size == ButtonSize.medium ? 16 : 18),
            child: CircularProgressIndicator(
              strokeWidth: 2,
              valueColor: AlwaysStoppedAnimation<Color>(
                _getLoadingColor(theme, variant),
              ),
            ),
          )
        : Row(
            mainAxisSize: fullWidth ? MainAxisSize.max : MainAxisSize.min,
            mainAxisAlignment: MainAxisAlignment.center,
            children: [
              if (icon != null) ...[
                Icon(icon, size: _getIconSize(size)),
                SizedBox(width: size == ButtonSize.small ? 6 : 8),
              ],
              Text(text, style: textStyle),
            ],
          );

    Widget button;
    switch (variant) {
      case ButtonVariant.primary:
        button = ElevatedButton(
          onPressed: isDisabled ? null : onPressed,
          style: buttonStyle,
          child: child,
        );
        break;
      case ButtonVariant.tonal:
        button = FilledButton.tonal(
          onPressed: isDisabled ? null : onPressed,
          style: buttonStyle,
          child: child,
        );
        break;
      case ButtonVariant.outlined:
        button = OutlinedButton(
          onPressed: isDisabled ? null : onPressed,
          style: buttonStyle,
          child: child,
        );
        break;
      case ButtonVariant.text:
        button = TextButton(
          onPressed: isDisabled ? null : onPressed,
          style: buttonStyle,
          child: child,
        );
        break;
    }

    return fullWidth ? SizedBox(width: double.infinity, child: button) : button;
  }

  ButtonStyle _getButtonStyle(
    ThemeData theme,
    ButtonVariant variant,
    ButtonSize size,
  ) {
    final padding = _getPadding(size);
    final borderRadius = BorderRadius.circular(_getBorderRadius(size));
    final elevation = variant == ButtonVariant.primary ? 2.0 : 0.0;

    switch (variant) {
      case ButtonVariant.primary:
        return ElevatedButton.styleFrom(
          padding: padding,
          elevation: elevation,
          shape: RoundedRectangleBorder(borderRadius: borderRadius),
          minimumSize: Size.zero,
          tapTargetSize: MaterialTapTargetSize.shrinkWrap,
        );
      case ButtonVariant.tonal:
        return FilledButton.styleFrom(
          padding: padding,
          shape: RoundedRectangleBorder(borderRadius: borderRadius),
          minimumSize: Size.zero,
          tapTargetSize: MaterialTapTargetSize.shrinkWrap,
        );
      case ButtonVariant.outlined:
        return OutlinedButton.styleFrom(
          padding: padding,
          side: BorderSide(
            color: theme.colorScheme.outline,
            width: 1.5,
          ),
          shape: RoundedRectangleBorder(borderRadius: borderRadius),
          minimumSize: Size.zero,
          tapTargetSize: MaterialTapTargetSize.shrinkWrap,
        );
      case ButtonVariant.text:
        return TextButton.styleFrom(
          padding: padding,
          shape: RoundedRectangleBorder(borderRadius: borderRadius),
          minimumSize: Size.zero,
          tapTargetSize: MaterialTapTargetSize.shrinkWrap,
        );
    }
  }

  TextStyle _getTextStyle(
    ThemeData theme,
    ButtonVariant variant,
    ButtonSize size,
  ) {
    final fontSize = _getFontSize(size);
    final fontWeight = size == ButtonSize.small ? FontWeight.w500 : FontWeight.w600;

    Color textColor;
    switch (variant) {
      case ButtonVariant.primary:
        textColor = theme.colorScheme.onPrimary;
        break;
      case ButtonVariant.tonal:
        textColor = theme.colorScheme.onSecondaryContainer;
        break;
      case ButtonVariant.outlined:
      case ButtonVariant.text:
        textColor = theme.colorScheme.primary;
        break;
    }

    return TextStyle(
      fontSize: fontSize,
      fontWeight: fontWeight,
      color: textColor,
      letterSpacing: 0.1,
    );
  }

  Color _getLoadingColor(ThemeData theme, ButtonVariant variant) {
    switch (variant) {
      case ButtonVariant.primary:
        return theme.colorScheme.onPrimary;
      case ButtonVariant.tonal:
        return theme.colorScheme.onSecondaryContainer;
      case ButtonVariant.outlined:
      case ButtonVariant.text:
        return theme.colorScheme.primary;
    }
  }

  EdgeInsets _getPadding(ButtonSize size) {
    switch (size) {
      case ButtonSize.small:
        return const EdgeInsets.symmetric(horizontal: 12, vertical: 6);
      case ButtonSize.medium:
        return const EdgeInsets.symmetric(horizontal: 16, vertical: 10);
      case ButtonSize.large:
        return const EdgeInsets.symmetric(horizontal: 20, vertical: 12);
    }
  }

  double _getFontSize(ButtonSize size) {
    switch (size) {
      case ButtonSize.small:
        return 13;
      case ButtonSize.medium:
        return 14;
      case ButtonSize.large:
        return 15;
    }
  }

  double _getIconSize(ButtonSize size) {
    switch (size) {
      case ButtonSize.small:
        return 16;
      case ButtonSize.medium:
        return 18;
      case ButtonSize.large:
        return 20;
    }
  }

  double _getBorderRadius(ButtonSize size) {
    switch (size) {
      case ButtonSize.small:
        return 8;
      case ButtonSize.medium:
        return 10;
      case ButtonSize.large:
        return 12;
    }
  }
}

/// Variantes de boutons disponibles (Material 3).
enum ButtonVariant {
  /// Bouton principal élevé (filled, elevated)
  primary,

  /// Bouton tonal (filled tonal - Material 3)
  tonal,

  /// Bouton avec bordure (outlined)
  outlined,

  /// Bouton texte sans fond (text)
  text,
}

/// Tailles de boutons disponibles.
enum ButtonSize {
  /// Petite taille - compact
  small,

  /// Taille moyenne - standard
  medium,

  /// Grande taille - proéminente
  large,
}
