import React, { forwardRef, ReactNode, HTMLAttributes } from 'react';
import { cn } from '../../lib/utils';

// Badge variants
type BadgeVariant = 'primary' | 'secondary' | 'success' | 'warning' | 'error' | 'info' | 'neutral';

// Badge sizes
type BadgeSize = 'sm' | 'md' | 'lg';

// Badge props interface
interface BadgeProps extends HTMLAttributes<HTMLDivElement> {
  variant?: BadgeVariant;
  size?: BadgeSize;
  icon?: ReactNode;
  iconPosition?: 'left' | 'right';
  rounded?: boolean;
  children?: ReactNode;
}

// Helper function to get variant styles
const getVariantStyles = (variant: BadgeVariant) => {
  switch (variant) {
    case 'primary':
      return 'bg-primary text-white';
    case 'secondary':
      return 'bg-secondary text-white';
    case 'success':
      return 'bg-success text-white';
    case 'warning':
      return 'bg-warning text-gray-900';
    case 'error':
      return 'bg-danger text-white';
    case 'info':
      return 'bg-info text-white';
    case 'neutral':
      return 'bg-gray-200 text-gray-800';
    default:
      return 'bg-primary text-white';
  }
};

// Helper function to get size styles
const getSizeStyles = (size: BadgeSize) => {
  switch (size) {
    case 'sm':
      return 'text-xs px-2 py-0.5';
    case 'md':
      return 'text-sm px-3 py-1';
    case 'lg':
      return 'text-base px-4 py-1.5';
    default:
      return 'text-sm px-3 py-1';
  }
};

// Helper function to get icon spacing
const getIconSpacing = (size: BadgeSize, iconPosition: 'left' | 'right') => {
  const spacing = {
    sm: iconPosition === 'left' ? 'mr-1' : 'ml-1',
    md: iconPosition === 'left' ? 'mr-1.5' : 'ml-1.5',
    lg: iconPosition === 'left' ? 'mr-2' : 'ml-2',
  };
  return spacing[size];
};

// Helper function to get icon size
const getIconSize = (size: BadgeSize) => {
  const sizeClasses = {
    sm: 'w-3 h-3',
    md: 'w-4 h-4',
    lg: 'w-5 h-5',
  };
  return sizeClasses[size];
};

// Main Badge Component
export const Badge = forwardRef<HTMLDivElement, BadgeProps>(
  (
    {
      variant = 'primary',
      size = 'md',
      icon,
      iconPosition = 'left',
      rounded = true,
      className = '',
      children,
      ...props
    },
    ref
  ) => {
    return (
      <div
        ref={ref}
        className={cn(
          // Base styles
          'inline-flex items-center justify-center font-medium',
          'transition-all duration-200 ease-in-out',
          // Variant styles
          getVariantStyles(variant),
          // Size styles
          getSizeStyles(size),
          // Border radius
          rounded ? 'rounded-full' : 'rounded-md',
          // Custom classes
          className
        )}
        {...props}
      >
        {/* Icon - Left position */}
        {icon && iconPosition === 'left' && (
          <span className={cn('flex items-center justify-center', getIconSpacing(size, 'left'), getIconSize(size))}>
            {icon}
          </span>
        )}

        {/* Badge content */}
        {children && <span>{children}</span>}

        {/* Icon - Right position */}
        {icon && iconPosition === 'right' && (
          <span className={cn('flex items-center justify-center', getIconSpacing(size, 'right'), getIconSize(size))}>
            {icon}
          </span>
        )}
      </div>
    );
  }
);

Badge.displayName = 'Badge';

// Badge Group Component for multiple badges
interface BadgeGroupProps extends HTMLAttributes<HTMLDivElement> {
  children?: ReactNode;
  gap?: 'xs' | 'sm' | 'md' | 'lg';
}

export const BadgeGroup = forwardRef<HTMLDivElement, BadgeGroupProps>(
  ({ gap = 'sm', className = '', children, ...props }, ref) => {
    const gapClasses = {
      xs: 'gap-1',
      sm: 'gap-2',
      md: 'gap-3',
      lg: 'gap-4',
    };

    return (
      <div
        ref={ref}
        className={cn('flex flex-wrap items-center', gapClasses[gap], className)}
        {...props}
      >
        {children}
      </div>
    );
  }
);

BadgeGroup.displayName = 'BadgeGroup';

// Export types for external use
export type { BadgeProps, BadgeVariant, BadgeSize, BadgeGroupProps };