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

enum ModernButtonType {
  primary,
  secondary,
  outline,
  text,
  danger,
}

enum ModernButtonSize {
  small,
  medium,
  large,
}

class ModernButton extends StatefulWidget {
  final String text;
  final VoidCallback? onPressed;
  final ModernButtonType type;
  final ModernButtonSize size;
  final bool isLoading;
  final bool isDisabled;
  final Widget? icon;
  final bool isIconOnly;
  final double? width;
  final double? height;
  final EdgeInsetsGeometry? padding;
  final BorderRadius? borderRadius;
  final String? tooltip;

  const ModernButton({
    super.key,
    required this.text,
    this.onPressed,
    this.type = ModernButtonType.primary,
    this.size = ModernButtonSize.medium,
    this.isLoading = false,
    this.isDisabled = false,
    this.icon,
    this.isIconOnly = false,
    this.width,
    this.height,
    this.padding,
    this.borderRadius,
    this.tooltip,
  });

  @override
  State<ModernButton> createState() => _ModernButtonState();
}

class _ModernButtonState extends State<ModernButton>
    with SingleTickerProviderStateMixin {
  late AnimationController _animationController;
  late Animation<double> _scaleAnimation;
  late Animation<double> _elevationAnimation;
  bool _isPressed = false;

  @override
  void initState() {
    super.initState();
    _animationController = AnimationController(
      duration: UIConstants.durationFast,
      vsync: this,
    );

    _scaleAnimation = Tween<double>(
      begin: 1.0,
      end: 0.95,
    ).animate(CurvedAnimation(
      parent: _animationController,
      curve: UIConstants.curveFast,
    ));

    _elevationAnimation = Tween<double>(
      begin: 1.0,
      end: 0.0,
    ).animate(CurvedAnimation(
      parent: _animationController,
      curve: UIConstants.curveFast,
    ));
  }

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

  void _onTapDown(TapDownDetails details) {
    if (!widget.isDisabled && !widget.isLoading) {
      setState(() {
        _isPressed = true;
      });
      _animationController.forward();
    }
  }

  void _onTapUp(TapUpDetails details) {
    if (!widget.isDisabled && !widget.isLoading) {
      setState(() {
        _isPressed = false;
      });
      _animationController.reverse();
    }
  }

  void _onTapCancel() {
    if (!widget.isDisabled && !widget.isLoading) {
      setState(() {
        _isPressed = false;
      });
      _animationController.reverse();
    }
  }

  bool get _canPress =>
      !widget.isDisabled && !widget.isLoading && widget.onPressed != null;

  Color _getBackgroundColor(ThemeData theme) {
    if (!_canPress) {
      return theme.colorScheme.surfaceVariant;
    }

    switch (widget.type) {
      case ModernButtonType.primary:
        return theme.colorScheme.primary;
      case ModernButtonType.secondary:
        return theme.colorScheme.secondary;
      case ModernButtonType.outline:
      case ModernButtonType.text:
        return Colors.transparent;
      case ModernButtonType.danger:
        return theme.colorScheme.error;
    }
  }

  Color _getTextColor(ThemeData theme) {
    if (!_canPress) {
      return theme.colorScheme.onSurfaceVariant;
    }

    switch (widget.type) {
      case ModernButtonType.primary:
      case ModernButtonType.secondary:
      case ModernButtonType.danger:
        return theme.colorScheme.onPrimary;
      case ModernButtonType.outline:
        return theme.colorScheme.primary;
      case ModernButtonType.text:
        return theme.colorScheme.primary;
    }
  }

  Color _getBorderColor(ThemeData theme) {
    if (!_canPress) {
      return theme.colorScheme.outline;
    }

    switch (widget.type) {
      case ModernButtonType.outline:
        return theme.colorScheme.primary;
      case ModernButtonType.danger:
        return theme.colorScheme.error;
      default:
        return Colors.transparent;
    }
  }

  double _getHeight() {
    if (widget.height != null) return widget.height!;

    switch (widget.size) {
      case ModernButtonSize.small:
        return UIConstants.buttonHeightSmall +
            4; // extra room to avoid text clip
      case ModernButtonSize.medium:
        return UIConstants.buttonHeightMedium + 4;
      case ModernButtonSize.large:
        return UIConstants.buttonHeightLarge + 4;
    }
  }

  EdgeInsetsGeometry _getPadding() {
    if (widget.padding != null) return widget.padding!;

    switch (widget.size) {
      case ModernButtonSize.small:
        return const EdgeInsets.symmetric(
          horizontal: UIConstants.spacing16,
          vertical: UIConstants.spacing6,
        );
      case ModernButtonSize.medium:
        return const EdgeInsets.symmetric(
          horizontal: UIConstants.spacing24,
          vertical: UIConstants.spacing14,
        );
      case ModernButtonSize.large:
        return const EdgeInsets.symmetric(
          horizontal: UIConstants.spacing32,
          vertical: UIConstants.spacing18,
        );
    }
  }

  double _getBorderRadius() {
    if (widget.borderRadius != null) {
      return widget.borderRadius!.topLeft.x;
    }

    switch (widget.size) {
      case ModernButtonSize.small:
        return UIConstants.radius8;
      case ModernButtonSize.medium:
        return UIConstants.radius16;
      case ModernButtonSize.large:
        return UIConstants.radius20;
    }
  }

  TextStyle _getTextStyle(ThemeData theme) {
    switch (widget.size) {
      case ModernButtonSize.small:
        return theme.textTheme.labelMedium?.copyWith(
              fontWeight: FontWeight.w600,
            ) ??
            const TextStyle();
      case ModernButtonSize.medium:
        return theme.textTheme.labelLarge?.copyWith(
              fontWeight: FontWeight.w600,
            ) ??
            const TextStyle();
      case ModernButtonSize.large:
        return theme.textTheme.titleMedium?.copyWith(
              fontWeight: FontWeight.w600,
            ) ??
            const TextStyle();
    }
  }

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

    return AnimatedBuilder(
      animation: _animationController,
      builder: (context, child) {
        return Transform.scale(
          scale: _scaleAnimation.value,
          child: GestureDetector(
            onTapDown: _onTapDown,
            onTapUp: _onTapUp,
            onTapCancel: _onTapCancel,
            child: Container(
              width: widget.width,
              height: _getHeight(),
              decoration: BoxDecoration(
                color: _getBackgroundColor(theme),
                borderRadius: BorderRadius.circular(_getBorderRadius()),
                border: Border.all(
                  color: _getBorderColor(theme),
                  width: widget.type == ModernButtonType.outline ? 1.5 : 0,
                ),
                boxShadow: _canPress
                    ? [
                        BoxShadow(
                          color: _getBackgroundColor(theme).withOpacity(0.3),
                          blurRadius: 8 * _elevationAnimation.value,
                          offset: Offset(0, 4 * _elevationAnimation.value),
                        ),
                      ]
                    : null,
              ),
              child: Material(
                color: Colors.transparent,
                child: InkWell(
                  onTap: _canPress ? widget.onPressed : null,
                  borderRadius: BorderRadius.circular(_getBorderRadius()),
                  child: Container(
                    padding: _getPadding(),
                    child: Row(
                      mainAxisSize: MainAxisSize.min,
                      mainAxisAlignment: MainAxisAlignment.center,
                      children: [
                        if (widget.isLoading) ...[
                          SizedBox(
                            width: 20,
                            height: 20,
                            child: CircularProgressIndicator(
                              strokeWidth: 2,
                              valueColor: AlwaysStoppedAnimation<Color>(
                                _getTextColor(theme),
                              ),
                            ),
                          ),
                          if (!widget.isIconOnly) ...[
                            const SizedBox(width: UIConstants.spacing12),
                          ],
                        ] else ...[
                          if (widget.icon != null && !widget.isIconOnly) ...[
                            IconTheme(
                              data: IconThemeData(
                                color: _getTextColor(theme),
                                size: _getHeight() * 0.4,
                              ),
                              child: widget.icon!,
                            ),
                            const SizedBox(width: UIConstants.spacing12),
                          ],
                        ],
                        if (!widget.isIconOnly) ...[
                          Flexible(
                            child: Text(
                              widget.text,
                              style: _getTextStyle(theme).copyWith(
                                color: _getTextColor(theme),
                                height: 1.2,
                              ),
                              strutStyle: const StrutStyle(
                                height: 1.2,
                                forceStrutHeight: true,
                              ),
                              textAlign: TextAlign.center,
                              overflow: TextOverflow.ellipsis,
                            ),
                          ),
                        ],
                      ],
                    ),
                  ),
                ),
              ),
            ),
          ),
        );
      },
    );
  }
}
