import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:rasadyar_core/core.dart';

/// Button variant types for consistent styling
enum CoreButtonVariant {
  /// Filled button with primary background color
  primary,
  /// Filled button with secondary background color  
  secondary,
  /// Button with transparent background and border
  outlined,
  /// Button with transparent background, no border
  text,
  /// Destructive action button (red theme)
  destructive,
}

/// Button size presets
enum CoreButtonSize {
  /// Small button - height 32
  small,
  /// Medium button - height 40 (default)
  medium,
  /// Large button - height 56
  large,
}

/// A unified, configurable button widget that replaces RElevated, ROutlinedElevated, etc.
/// 
/// This widget provides a consistent API and theming system across the entire app.
/// It supports different variants, sizes, loading states, and full customization.
class CoreButton extends StatelessWidget {
  /// Button text content
  final String? text;
  
  /// Custom child widget (overrides text if provided)
  final Widget? child;
  
  /// Button press callback
  final VoidCallback? onPressed;
  
  /// Button style variant
  final CoreButtonVariant variant;
  
  /// Button size preset
  final CoreButtonSize size;
  
  /// Custom width (overrides size preset)
  final double? width;
  
  /// Custom height (overrides size preset)
  final double? height;
  
  /// Whether button should take full width
  final bool isFullWidth;
  
  /// Loading state - shows progress indicator
  final bool isLoading;
  
  /// Progress value for loading indicator (0.0 to 1.0, null for indeterminate)
  final double? progress;
  
  /// Custom text style (overrides theme)
  final TextStyle? textStyle;
  
  /// Custom background color (overrides variant theme)
  final Color? backgroundColor;
  
  /// Custom foreground color (overrides variant theme)
  final Color? foregroundColor;
  
  /// Custom border color for outlined variant
  final Color? borderColor;
  
  /// Border radius (default: 8.0)
  final double borderRadius;
  
  /// Leading icon
  final Widget? icon;
  
  /// Icon placement
  final bool iconAtEnd;
  
  /// Spacing between icon and text
  final double iconSpacing;

  const CoreButton({
    super.key,
    this.text,
    this.child,
    required this.onPressed,
    this.variant = CoreButtonVariant.primary,
    this.size = CoreButtonSize.medium,
    this.width,
    this.height,
    this.isFullWidth = false,
    this.isLoading = false,
    this.progress,
    this.textStyle,
    this.backgroundColor,
    this.foregroundColor,
    this.borderColor,
    this.borderRadius = 8.0,
    this.icon,
    this.iconAtEnd = false,
    this.iconSpacing = 8.0,
  }) : assert(text != null || child != null, 'Either text or child must be provided');

  /// Creates a primary filled button
  const CoreButton.primary({
    super.key,
    this.text,
    this.child,
    required this.onPressed,
    this.size = CoreButtonSize.medium,
    this.width,
    this.height,
    this.isFullWidth = false,
    this.isLoading = false,
    this.progress,
    this.textStyle,
    this.backgroundColor,
    this.foregroundColor,
    this.borderRadius = 8.0,
    this.icon,
    this.iconAtEnd = false,
    this.iconSpacing = 8.0,
  }) : variant = CoreButtonVariant.primary,
       borderColor = null,
       assert(text != null || child != null, 'Either text or child must be provided');

  /// Creates an outlined button
  const CoreButton.outlined({
    super.key,
    this.text,
    this.child,
    required this.onPressed,
    this.size = CoreButtonSize.medium,
    this.width,
    this.height,
    this.isFullWidth = false,
    this.isLoading = false,
    this.progress,
    this.textStyle,
    this.foregroundColor,
    this.borderColor,
    this.borderRadius = 8.0,
    this.icon,
    this.iconAtEnd = false,
    this.iconSpacing = 8.0,
  }) : variant = CoreButtonVariant.outlined,
       backgroundColor = null,
       assert(text != null || child != null, 'Either text or child must be provided');

  /// Creates a text button with no background
  const CoreButton.text({
    super.key,
    this.text,
    this.child,
    required this.onPressed,
    this.size = CoreButtonSize.medium,
    this.width,
    this.height,
    this.isFullWidth = false,
    this.isLoading = false,
    this.progress,
    this.textStyle,
    this.foregroundColor,
    this.borderRadius = 8.0,
    this.icon,
    this.iconAtEnd = false,
    this.iconSpacing = 8.0,
  }) : variant = CoreButtonVariant.text,
       backgroundColor = null,
       borderColor = null,
       assert(text != null || child != null, 'Either text or child must be provided');

  /// Creates a destructive action button
  const CoreButton.destructive({
    super.key,
    this.text,
    this.child,
    required this.onPressed,
    this.size = CoreButtonSize.medium,
    this.width,
    this.height,
    this.isFullWidth = false,
    this.isLoading = false,
    this.progress,
    this.textStyle,
    this.backgroundColor,
    this.foregroundColor,
    this.borderRadius = 8.0,
    this.icon,
    this.iconAtEnd = false,
    this.iconSpacing = 8.0,
  }) : variant = CoreButtonVariant.destructive,
       borderColor = null,
       assert(text != null || child != null, 'Either text or child must be provided');

  /// Gets button dimensions based on size preset
  Size get _buttonSize {
    final buttonWidth = isFullWidth ? double.infinity : (width ?? _defaultWidth);
    final buttonHeight = height ?? _defaultHeight;
    return Size(buttonWidth, buttonHeight);
  }

  double get _defaultWidth {
    switch (size) {
      case CoreButtonSize.small:
        return 120.0;
      case CoreButtonSize.medium:
        return 150.0;
      case CoreButtonSize.large:
        return 200.0;
    }
  }

  double get _defaultHeight {
    switch (size) {
      case CoreButtonSize.small:
        return 32.0;
      case CoreButtonSize.medium:
        return 40.0;
      case CoreButtonSize.large:
        return 56.0;
    }
  }

  /// Gets theme colors based on variant
  _ButtonTheme get _theme {
    switch (variant) {
      case CoreButtonVariant.primary:
        return _ButtonTheme(
          backgroundColor: backgroundColor ?? AppColor.blueNormal,
          foregroundColor: foregroundColor ?? Colors.white,
          borderColor: null,
        );
      case CoreButtonVariant.secondary:
        return _ButtonTheme(
          backgroundColor: backgroundColor ?? AppColor.darkGreyNormal,
          foregroundColor: foregroundColor ?? AppColor.textColor,
          borderColor: null,
        );
      case CoreButtonVariant.outlined:
        return _ButtonTheme(
          backgroundColor: backgroundColor ?? Colors.transparent,
          foregroundColor: foregroundColor ?? (borderColor ?? AppColor.blueNormal),
          borderColor: borderColor ?? AppColor.blueNormal,
        );
      case CoreButtonVariant.text:
        return _ButtonTheme(
          backgroundColor: backgroundColor ?? Colors.transparent,
          foregroundColor: foregroundColor ?? AppColor.blueNormal,
          borderColor: null,
        );
      case CoreButtonVariant.destructive:
        return _ButtonTheme(
          backgroundColor: backgroundColor ?? AppColor.error,
          foregroundColor: foregroundColor ?? Colors.white,
          borderColor: null,
        );
    }
  }

  TextStyle get _textTheme {
    final baseStyle = textStyle ?? AppFonts.yekan16;
    return baseStyle.copyWith(color: _theme.foregroundColor);
  }

  Widget _buildContent() {
    if (isLoading) {
      return SizedBox(
        width: 20,
        height: 20,
        child: CircularProgressIndicator(
          strokeWidth: 2.0,
          valueColor: AlwaysStoppedAnimation<Color>(_theme.foregroundColor),
          value: progress,
        ),
      );
    }

    final content = child ?? Text(text!, style: _textTheme);
    
    if (icon != null) {
      final iconWidget = IconTheme(
        data: IconThemeData(color: _theme.foregroundColor, size: 18),
        child: icon!,
      );
      
      if (iconAtEnd) {
        return Row(
          mainAxisSize: MainAxisSize.min,
          children: [
            content,
            SizedBox(width: iconSpacing),
            iconWidget,
          ],
        );
      } else {
        return Row(
          mainAxisSize: MainAxisSize.min,
          children: [
            iconWidget,
            SizedBox(width: iconSpacing),
            content,
          ],
        );
      }
    }
    
    return content;
  }

  @override
  Widget build(BuildContext context) {
    final isEnabled = onPressed != null && !isLoading;
    final theme = _theme;
    final buttonSize = _buttonSize;

    if (variant == CoreButtonVariant.outlined) {
      return ConstrainedBox(
        constraints: BoxConstraints.tightFor(
          width: buttonSize.width,
          height: buttonSize.height,
        ),
        child: OutlinedButton(
          onPressed: isEnabled ? onPressed : null,
          style: OutlinedButton.styleFrom(
            backgroundColor: theme.backgroundColor,
            foregroundColor: theme.foregroundColor,
            side: BorderSide(
              color: isEnabled ? theme.borderColor! : theme.borderColor!.withOpacity(0.38),
              width: 1.5,
            ),
            shape: RoundedRectangleBorder(
              borderRadius: BorderRadius.circular(borderRadius),
            ),
            padding: EdgeInsets.zero,
            textStyle: _textTheme,
          ),
          child: _buildContent(),
        ),
      );
    }

    if (variant == CoreButtonVariant.text) {
      return ConstrainedBox(
        constraints: BoxConstraints.tightFor(
          width: buttonSize.width,
          height: buttonSize.height,
        ),
        child: TextButton(
          onPressed: isEnabled ? onPressed : null,
          style: TextButton.styleFrom(
            backgroundColor: theme.backgroundColor,
            foregroundColor: theme.foregroundColor,
            shape: RoundedRectangleBorder(
              borderRadius: BorderRadius.circular(borderRadius),
            ),
            padding: EdgeInsets.zero,
            textStyle: _textTheme,
          ),
          child: _buildContent(),
        ),
      );
    }

    // Default to ElevatedButton for primary, secondary, destructive
    return ConstrainedBox(
      constraints: BoxConstraints.tightFor(
        width: buttonSize.width,
        height: buttonSize.height,
      ),
      child: ElevatedButton(
        onPressed: isEnabled ? onPressed : null,
        style: ElevatedButton.styleFrom(
          backgroundColor: theme.backgroundColor,
          foregroundColor: theme.foregroundColor,
          disabledBackgroundColor: theme.backgroundColor.withOpacity(0.38),
          disabledForegroundColor: theme.foregroundColor.withOpacity(0.38),
          shape: RoundedRectangleBorder(
            borderRadius: BorderRadius.circular(borderRadius),
          ),
          padding: EdgeInsets.zero,
          textStyle: _textTheme,
        ),
        child: _buildContent(),
      ),
    );
  }
}

/// Internal theme data for button variants
class _ButtonTheme {
  final Color backgroundColor;
  final Color foregroundColor;
  final Color? borderColor;

  const _ButtonTheme({
    required this.backgroundColor,
    required this.foregroundColor,
    this.borderColor,
  });
}