import 'package:flutter/material.dart';
import '../halo_tokens.dart';

enum HaloButtonVariant { primary, secondary, ghost }

enum HaloButtonSize { sm, md, lg }

class HaloButton extends StatelessWidget {
  const HaloButton({
    super.key,
    required this.label,
    required this.onPressed,
    this.variant = HaloButtonVariant.primary,
    this.size = HaloButtonSize.md,
    this.icon,
    this.fullWidth = false,
  });

  final String label;
  final VoidCallback? onPressed;
  final HaloButtonVariant variant;
  final HaloButtonSize size;
  final Widget? icon;
  final bool fullWidth;

  @override
  Widget build(BuildContext context) {
    final disabled = onPressed == null;
    final padding = _padding();
    final fontSize = _fontSize();
    const shape = RoundedRectangleBorder(borderRadius: HaloRadius.pill);
    final textStyle = TextStyle(
      fontFamily: HaloTokens.fontBody,
      fontSize: fontSize,
      fontWeight: FontWeight.w600,
    );

    Widget child = _content(textStyle);

    Widget button;
    switch (variant) {
      case HaloButtonVariant.primary:
        button = Container(
          decoration: disabled
              ? null
              : const BoxDecoration(
                  borderRadius: HaloRadius.pill,
                  boxShadow: HaloShadows.button,
                ),
          child: ElevatedButton(
            onPressed: onPressed,
            style: ElevatedButton.styleFrom(
              backgroundColor: HaloTokens.brand,
              foregroundColor: Colors.white,
              disabledBackgroundColor: HaloTokens.brandSoft,
              disabledForegroundColor: HaloTokens.inkMuted,
              elevation: 0,
              padding: padding,
              shape: shape,
              textStyle: textStyle,
            ),
            child: child,
          ),
        );
        break;
      case HaloButtonVariant.secondary:
        button = OutlinedButton(
          onPressed: onPressed,
          style: OutlinedButton.styleFrom(
            foregroundColor: HaloTokens.brandDark,
            disabledForegroundColor: HaloTokens.inkMuted,
            backgroundColor: HaloTokens.surface,
            side: BorderSide(
              color: disabled ? HaloTokens.border : HaloTokens.brandSoft,
            ),
            padding: padding,
            shape: shape,
            textStyle: textStyle,
          ),
          child: child,
        );
        break;
      case HaloButtonVariant.ghost:
        button = TextButton(
          onPressed: onPressed,
          style: TextButton.styleFrom(
            foregroundColor: HaloTokens.brandDark,
            disabledForegroundColor: HaloTokens.inkMuted,
            padding: padding,
            shape: shape,
            textStyle: textStyle,
          ),
          child: child,
        );
        break;
    }

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

  Widget _content(TextStyle textStyle) {
    if (icon == null) {
      return Text(label, style: textStyle);
    }
    return Row(
      mainAxisSize: MainAxisSize.min,
      mainAxisAlignment: MainAxisAlignment.center,
      children: [
        IconTheme(
          data: IconThemeData(size: textStyle.fontSize! + 2),
          child: icon!,
        ),
        const SizedBox(width: HaloSpacing.s8),
        Text(label, style: textStyle),
      ],
    );
  }

  EdgeInsets _padding() {
    switch (size) {
      case HaloButtonSize.sm:
        return const EdgeInsets.symmetric(
          horizontal: HaloSpacing.s16,
          vertical: HaloSpacing.s8,
        );
      case HaloButtonSize.md:
        return const EdgeInsets.symmetric(
          horizontal: HaloSpacing.s24,
          vertical: HaloSpacing.s12,
        );
      case HaloButtonSize.lg:
        return const EdgeInsets.symmetric(
          horizontal: HaloSpacing.s32,
          vertical: HaloSpacing.s16,
        );
    }
  }

  double _fontSize() {
    switch (size) {
      case HaloButtonSize.sm:
        return 13;
      case HaloButtonSize.md:
        return 15;
      case HaloButtonSize.lg:
        return 16;
    }
  }
}
