import 'package:flutter/material.dart';

/// Custom button widget with loading state and consistent styling
///
/// This widget provides a reusable button component with:
/// - Loading indicator support
/// - Disabled state
/// - Customizable colors, icons, and text
/// - Consistent padding and styling
///
/// Usage:
/// ```dart
/// CustomButton(
///   text: 'Login',
///   onPressed: _handleLogin,
///   isLoading: _isLoading,
/// )
///
/// CustomButton.outlined(
///   text: 'Cancel',
///   onPressed: _handleCancel,
/// )
///
/// CustomButton.text(
///   text: 'Skip',
///   onPressed: _handleSkip,
/// )
/// ```
class CustomButton extends StatelessWidget {
  /// Button text
  final String text;

  /// Callback when button is pressed
  final VoidCallback? onPressed;

  /// Whether the button is in loading state
  final bool isLoading;

  /// Optional icon to display before text
  final IconData? icon;

  /// Button style variant
  final ButtonStyle? style;

  /// Whether this is an outlined button
  final bool isOutlined;

  /// Whether this is a text button
  final bool isTextButton;

  /// Minimum button width (null for full width)
  final double? minWidth;

  /// Minimum button height
  final double? minHeight;

  /// Background color (only for elevated buttons)
  final Color? backgroundColor;

  /// Foreground/text color
  final Color? foregroundColor;

  /// Border color (only for outlined buttons)
  final Color? borderColor;

  /// Font size
  final double? fontSize;

  /// Font weight
  final FontWeight? fontWeight;

  const CustomButton({
    super.key,
    required this.text,
    required this.onPressed,
    this.isLoading = false,
    this.icon,
    this.style,
    this.minWidth,
    this.minHeight,
    this.backgroundColor,
    this.foregroundColor,
    this.fontSize,
    this.fontWeight,
  })  : isOutlined = false,
        isTextButton = false,
        borderColor = null;

  /// Create an outlined button variant
  const CustomButton.outlined({
    super.key,
    required this.text,
    required this.onPressed,
    this.isLoading = false,
    this.icon,
    this.style,
    this.minWidth,
    this.minHeight,
    this.foregroundColor,
    this.borderColor,
    this.fontSize,
    this.fontWeight,
  })  : isOutlined = true,
        isTextButton = false,
        backgroundColor = null;

  /// Create a text button variant
  const CustomButton.text({
    super.key,
    required this.text,
    required this.onPressed,
    this.isLoading = false,
    this.icon,
    this.style,
    this.minWidth,
    this.minHeight,
    this.foregroundColor,
    this.fontSize,
    this.fontWeight,
  })  : isOutlined = false,
        isTextButton = true,
        backgroundColor = null,
        borderColor = null;

  @override
  Widget build(BuildContext context) {
    final theme = Theme.of(context);
    final colorScheme = theme.colorScheme;

    // Determine if button should be disabled
    final bool isDisabled = onPressed == null || isLoading;

    // Build button content
    Widget content;
    if (isLoading) {
      content = SizedBox(
        height: 20,
        width: 20,
        child: CircularProgressIndicator(
          strokeWidth: 2,
          valueColor: AlwaysStoppedAnimation<Color>(
            isTextButton
                ? foregroundColor ?? colorScheme.primary
                : foregroundColor ?? colorScheme.onPrimary,
          ),
        ),
      );
    } else if (icon != null) {
      content = Row(
        mainAxisSize: MainAxisSize.min,
        mainAxisAlignment: MainAxisAlignment.center,
        children: [
          Icon(icon, size: 20),
          const SizedBox(width: 8),
          Flexible(
            child: Text(
              text,
              overflow: TextOverflow.ellipsis,
            ),
          ),
        ],
      );
    } else {
      content = Text(text);
    }

    // Build button style
    final ButtonStyle buttonStyle = style ??
        (isTextButton
            ? _buildTextButtonStyle(context)
            : isOutlined
                ? _buildOutlinedButtonStyle(context)
                : _buildElevatedButtonStyle(context));

    // Build appropriate button widget
    if (isTextButton) {
      return TextButton(
        onPressed: isDisabled ? null : onPressed,
        style: buttonStyle,
        child: content,
      );
    } else if (isOutlined) {
      return OutlinedButton(
        onPressed: isDisabled ? null : onPressed,
        style: buttonStyle,
        child: content,
      );
    } else {
      return ElevatedButton(
        onPressed: isDisabled ? null : onPressed,
        style: buttonStyle,
        child: content,
      );
    }
  }

  /// Build elevated button style
  ButtonStyle _buildElevatedButtonStyle(BuildContext context) {
    final colorScheme = Theme.of(context).colorScheme;

    return ElevatedButton.styleFrom(
      backgroundColor: backgroundColor ?? colorScheme.primary,
      foregroundColor: foregroundColor ?? colorScheme.onPrimary,
      minimumSize: Size(
        minWidth ?? double.infinity,
        minHeight ?? 48,
      ),
      textStyle: TextStyle(
        fontSize: fontSize ?? 16,
        fontWeight: fontWeight ?? FontWeight.w600,
      ),
      elevation: 0,
      shape: RoundedRectangleBorder(
        borderRadius: BorderRadius.circular(8),
      ),
      padding: const EdgeInsets.symmetric(
        horizontal: 24,
        vertical: 12,
      ),
    );
  }

  /// Build outlined button style
  ButtonStyle _buildOutlinedButtonStyle(BuildContext context) {
    final colorScheme = Theme.of(context).colorScheme;

    return OutlinedButton.styleFrom(
      foregroundColor: foregroundColor ?? colorScheme.primary,
      side: BorderSide(
        color: borderColor ?? colorScheme.primary,
        width: 1.5,
      ),
      minimumSize: Size(
        minWidth ?? double.infinity,
        minHeight ?? 48,
      ),
      textStyle: TextStyle(
        fontSize: fontSize ?? 16,
        fontWeight: fontWeight ?? FontWeight.w600,
      ),
      shape: RoundedRectangleBorder(
        borderRadius: BorderRadius.circular(8),
      ),
      padding: const EdgeInsets.symmetric(
        horizontal: 24,
        vertical: 12,
      ),
    );
  }

  /// Build text button style
  ButtonStyle _buildTextButtonStyle(BuildContext context) {
    final colorScheme = Theme.of(context).colorScheme;

    return TextButton.styleFrom(
      foregroundColor: foregroundColor ?? colorScheme.primary,
      minimumSize: Size(
        minWidth ?? 0,
        minHeight ?? 48,
      ),
      textStyle: TextStyle(
        fontSize: fontSize ?? 16,
        fontWeight: fontWeight ?? FontWeight.w600,
      ),
      shape: RoundedRectangleBorder(
        borderRadius: BorderRadius.circular(8),
      ),
      padding: const EdgeInsets.symmetric(
        horizontal: 16,
        vertical: 12,
      ),
    );
  }
}

/// Icon button with loading state
class CustomIconButton extends StatelessWidget {
  /// Icon to display
  final IconData icon;

  /// Callback when button is pressed
  final VoidCallback? onPressed;

  /// Whether the button is in loading state
  final bool isLoading;

  /// Icon size
  final double? iconSize;

  /// Icon color
  final Color? color;

  /// Background color
  final Color? backgroundColor;

  /// Tooltip text
  final String? tooltip;

  const CustomIconButton({
    super.key,
    required this.icon,
    required this.onPressed,
    this.isLoading = false,
    this.iconSize,
    this.color,
    this.backgroundColor,
    this.tooltip,
  });

  @override
  Widget build(BuildContext context) {
    final theme = Theme.of(context);
    final bool isDisabled = onPressed == null || isLoading;

    Widget button = IconButton(
      icon: isLoading
          ? SizedBox(
              height: iconSize ?? 24,
              width: iconSize ?? 24,
              child: CircularProgressIndicator(
                strokeWidth: 2,
                valueColor: AlwaysStoppedAnimation<Color>(
                  color ?? theme.colorScheme.primary,
                ),
              ),
            )
          : Icon(
              icon,
              size: iconSize ?? 24,
              color: color,
            ),
      onPressed: isDisabled ? null : onPressed,
      style: backgroundColor != null
          ? IconButton.styleFrom(
              backgroundColor: backgroundColor,
            )
          : null,
    );

    if (tooltip != null) {
      return Tooltip(
        message: tooltip!,
        child: button,
      );
    }

    return button;
  }
}
