// /components/ui/Button.tsx
import * as React from 'react';
import clsx from 'clsx';

export type ButtonVariant = 'primary' | 'secondary' | 'soft';
export type ButtonSize = 'xs' | 'sm' | 'md' | 'lg' | 'xl';
export type ButtonShape = 'default' | 'pill' | 'circle';
export type ButtonTone = 'indigo' | 'gray' | 'rose' | 'emerald';

export interface ButtonProps
  extends React.ButtonHTMLAttributes<HTMLButtonElement> {
  variant?: ButtonVariant;
  size?: ButtonSize;
  shape?: ButtonShape; // "default" (normal), "pill" (rounded-full), "circle" (nur Icon)
  icon?: React.ReactNode;
  iconPosition?: 'leading' | 'trailing';
  fullWidth?: boolean;
  tone?: ButtonTone; // NEU: Farbton
}

const baseClasses =
  'inline-flex items-center justify-center font-semibold shadow-xs ' +
  'focus-visible:outline-2 focus-visible:outline-offset-2 ' +
  'disabled:opacity-50 disabled:cursor-not-allowed transition-colors duration-150';

// Farb-Kombinationen pro Variant + Tone
const variantToneClasses: Record<ButtonVariant, Record<ButtonTone, string>> = {
  primary: {
    indigo:
      'bg-indigo-600 text-white hover:bg-indigo-500 ' +
      'focus-visible:outline-indigo-600 ' +
      'dark:bg-indigo-500 dark:text-white dark:hover:bg-indigo-400 dark:shadow-none dark:focus-visible:outline-indigo-500',
    gray:
      'bg-gray-900 text-white hover:bg-gray-800 ' +
      'focus-visible:outline-gray-900 ' +
      'dark:bg-gray-700 dark:text-white dark:hover:bg-gray-600 dark:shadow-none dark:focus-visible:outline-gray-700',
    rose:
      'bg-rose-600 text-white hover:bg-rose-500 ' +
      'focus-visible:outline-rose-600 ' +
      'dark:bg-rose-500 dark:text-white dark:hover:bg-rose-400 dark:shadow-none dark:focus-visible:outline-rose-500',
    emerald:
      'bg-emerald-600 text-white hover:bg-emerald-500 ' +
      'focus-visible:outline-emerald-600 ' +
      'dark:bg-emerald-500 dark:text-white dark:hover:bg-emerald-400 dark:shadow-none dark:focus-visible:outline-emerald-500',
  },
  secondary: {
    indigo:
      'bg-white text-gray-900 inset-ring inset-ring-gray-300 hover:bg-gray-50 ' +
      'focus-visible:outline-indigo-600 ' +
      'dark:bg-white/10 dark:text-white dark:shadow-none dark:inset-ring-white/5 dark:hover:bg-white/20 dark:focus-visible:outline-indigo-500',
    gray:
      'bg-white text-gray-900 inset-ring inset-ring-gray-300 hover:bg-gray-50 ' +
      'focus-visible:outline-gray-900 ' +
      'dark:bg-white/10 dark:text-white dark:shadow-none dark:inset-ring-white/5 dark:hover:bg-white/20 dark:focus-visible:outline-gray-700',
    rose:
      'bg-white text-rose-600 inset-ring inset-ring-rose-200 hover:bg-rose-50 ' +
      'focus-visible:outline-rose-600 ' +
      'dark:bg-white/10 dark:text-rose-300 dark:shadow-none dark:inset-ring-rose-500/40 dark:hover:bg-rose-500/10 dark:focus-visible:outline-rose-500',
    emerald:
      'bg-white text-emerald-600 inset-ring inset-ring-emerald-200 hover:bg-emerald-50 ' +
      'focus-visible:outline-emerald-600 ' +
      'dark:bg-white/10 dark:text-emerald-300 dark:shadow-none dark:inset-ring-emerald-500/40 dark:hover:bg-emerald-500/10 dark:focus-visible:outline-emerald-500',
  },
  soft: {
    indigo:
      'bg-indigo-50 text-indigo-600 hover:bg-indigo-100 ' +
      'focus-visible:outline-indigo-600 ' +
      'dark:bg-indigo-500/20 dark:text-indigo-400 dark:shadow-none dark:hover:bg-indigo-500/30 dark:focus-visible:outline-indigo-500',
    gray:
      'bg-gray-100 text-gray-800 hover:bg-gray-200 ' +
      'focus-visible:outline-gray-900 ' +
      'dark:bg-gray-700/40 dark:text-gray-100 dark:shadow-none dark:hover:bg-gray-700/60 dark:focus-visible:outline-gray-600',
    rose:
      'bg-rose-50 text-rose-600 hover:bg-rose-100 ' +
      'focus-visible:outline-rose-600 ' +
      'dark:bg-rose-500/20 dark:text-rose-300 dark:shadow-none dark:hover:bg-rose-500/30 dark:focus-visible:outline-rose-500',
    emerald:
      'bg-emerald-50 text-emerald-600 hover:bg-emerald-100 ' +
      'focus-visible:outline-emerald-600 ' +
      'dark:bg-emerald-500/20 dark:text-emerald-300 dark:shadow-none dark:hover:bg-emerald-500/30 dark:focus-visible:outline-emerald-500',
  },
};

// Größen wie in deinen Snippets (rectangular)
const sizeClasses: Record<ButtonSize, string> = {
  xs: 'rounded-sm px-2 py-1 text-xs',
  sm: 'rounded-sm px-2 py-1 text-sm',
  md: 'rounded-md px-2.5 py-1.5 text-sm',
  lg: 'rounded-md px-3 py-2 text-sm',
  xl: 'rounded-md px-3.5 py-2.5 text-sm',
};

// Pill / "rounded primary/secondary buttons" Größen
const pillSizeClasses: Record<ButtonSize, string> = {
  xs: 'rounded-full px-2.5 py-1 text-xs',
  sm: 'rounded-full px-2.5 py-1 text-sm',
  md: 'rounded-full px-3 py-1.5 text-sm',
  lg: 'rounded-full px-3.5 py-2 text-sm',
  xl: 'rounded-full px-4 py-2.5 text-sm',
};

// Circular Buttons – nur Icon
const circleSizeClasses: Record<ButtonSize, string> = {
  xs: 'rounded-full p-1',
  sm: 'rounded-full p-1.5',
  md: 'rounded-full p-2',
  lg: 'rounded-full p-2',
  xl: 'rounded-full p-2.5',
};

function getSizeClasses(size: ButtonSize, shape: ButtonShape): string {
  switch (shape) {
    case 'pill':
      return pillSizeClasses[size];
    case 'circle':
      return circleSizeClasses[size];
    default:
      return sizeClasses[size];
  }
}

const Button = React.forwardRef<HTMLButtonElement, ButtonProps>(
  (
    {
      variant = 'primary',
      tone = 'indigo', // NEU: Default
      size = 'md',
      shape = 'default',
      icon,
      iconPosition = 'leading',
      fullWidth,
      className,
      children,
      type = 'button',
      ...props
    },
    ref
  ) => {
    const hasIcon = !!icon;
    const hasLabel = React.Children.count(children) > 0;

    const gapClasses =
      hasIcon && hasLabel
        ? size === 'xl'
          ? 'gap-x-2'
          : 'gap-x-1.5'
        : '';

    return (
      <button
        ref={ref}
        type={type}
        className={clsx(
          baseClasses,
          variantToneClasses[variant][tone],
          getSizeClasses(size, shape),
          gapClasses,
          fullWidth && 'w-full',
          className
        )}
        {...props}
      >
        {hasIcon && iconPosition === 'leading' && (
          <span aria-hidden="true">{icon}</span>
        )}

        {hasLabel ? (
          children
        ) : hasIcon ? (
          // Für reine Icon-Buttons: Text nur für Screenreader, per aria-label steuerbar
          <span className="sr-only">{props['aria-label'] ?? 'Button'}</span>
        ) : null}

        {hasIcon && iconPosition === 'trailing' && (
          <span aria-hidden="true">{icon}</span>
        )}
      </button>
    );
  }
);

Button.displayName = 'Button';

export default Button;
