import React, { forwardRef, HTMLAttributes, useMemo } from 'react';
import { clsx } from 'clsx';

export interface BadgeProps extends HTMLAttributes<HTMLSpanElement> {
  variant?: 'default' | 'primary' | 'secondary' | 'success' | 'warning' | 'error' | 'info' | 'outline';
  size?: 'xs' | 'sm' | 'md' | 'lg';
  shape?: 'rounded' | 'pill' | 'square';
  dot?: boolean;
  count?: number;
  showZero?: boolean;
  max?: number;
  offset?: [number, number];
  status?: 'default' | 'error' | 'success' | 'warning' | 'processing';
  text?: string;
  color?: string;
  icon?: React.ReactNode;
  closable?: boolean;
  onClose?: (e: React.MouseEvent<HTMLElement>) => void;
}

const Badge = forwardRef<HTMLSpanElement, BadgeProps>(({
  variant = 'default',
  size = 'md',
  shape = 'rounded',
  dot = false,
  count,
  showZero = false,
  max = 99,
  offset,
  status,
  text,
  color,
  icon,
  closable = false,
  onClose,
  className,
  children,
  ...props
}, ref) => {
  const hasChildren = children !== undefined;
  const isStandalone = !hasChildren;
  
  // Calculate display count
  const displayCount = useMemo(() => {
    if (count === undefined || dot) return undefined;
    if (count === 0 && !showZero) return undefined;
    if (count > max) return `${max}+`;
    return count.toString();
  }, [count, dot, showZero, max]);

  const baseClasses = [
    'inline-flex items-center justify-center font-medium',
    'transition-all duration-200 ease-in-out',
    'whitespace-nowrap',
  ];

  const variantClasses = {
    default: [
      'bg-bg-tertiary text-text-primary border border-border-primary',
    ],
    primary: [
      'bg-color-primary text-text-inverse',
    ],
    secondary: [
      'bg-color-secondary text-text-inverse',
    ],
    success: [
      'bg-color-success text-text-inverse',
    ],
    warning: [
      'bg-color-warning text-text-inverse',
    ],
    error: [
      'bg-color-error text-text-inverse',
    ],
    info: [
      'bg-color-info text-text-inverse',
    ],
    outline: [
      'bg-transparent border border-current',
    ],
  };

  const sizeClasses = {
    xs: isStandalone ? 'px-1.5 py-0.5 text-xs min-h-4' : 'w-4 h-4 text-xs',
    sm: isStandalone ? 'px-2 py-0.5 text-xs min-h-5' : 'w-5 h-5 text-xs',
    md: isStandalone ? 'px-2.5 py-1 text-sm min-h-6' : 'w-6 h-6 text-sm',
    lg: isStandalone ? 'px-3 py-1.5 text-sm min-h-7' : 'w-7 h-7 text-sm',
  };

  const shapeClasses = {
    rounded: 'rounded-md',
    pill: 'rounded-full',
    square: 'rounded-none',
  };

  const statusClasses = {
    default: 'bg-text-tertiary',
    error: 'bg-color-error',
    success: 'bg-color-success animate-pulse',
    warning: 'bg-color-warning',
    processing: 'bg-color-info animate-pulse',
  };

  // Dot badge (status indicator)
  if (dot || status) {
    const dotClasses = clsx(
      'w-2 h-2 rounded-full',
      status ? statusClasses[status] : 'bg-color-primary'
    );

    if (hasChildren) {
      return (
        <span className="relative inline-flex" ref={ref}>
          {children}
          <span
            className={clsx(
              dotClasses,
              'absolute -top-0.5 -right-0.5 ring-2 ring-bg-primary',
              className
            )}
            style={offset ? {
              transform: `translate(${offset[0]}px, ${offset[1]}px)`,
            } : undefined}
            {...props}
          />
        </span>
      );
    }

    return (
      <span
        ref={ref}
        className={clsx(dotClasses, className)}
        {...props}
      />
    );
  }

  // Count badge
  if (count !== undefined && hasChildren) {
    if (displayCount === undefined) {
      return <>{children}</>;
    }

    return (
      <span className="relative inline-flex" ref={ref}>
        {children}
        <span
          className={clsx(
            'absolute -top-2 -right-2 flex items-center justify-center',
            'min-w-5 h-5 px-1 text-xs font-medium',
            'bg-color-error text-text-inverse rounded-full',
            'ring-2 ring-bg-primary',
            className
          )}
          style={offset ? {
            transform: `translate(${offset[0]}px, ${offset[1]}px)`,
          } : undefined}
          {...props}
        >
          {displayCount}
        </span>
      </span>
    );
  }

  // Standalone badge
  const classes = clsx(
    baseClasses,
    variantClasses[variant],
    sizeClasses[size],
    shapeClasses[shape],
    {
      'gap-1': icon || closable,
      'pr-1': closable,
    },
    className
  );

  const customStyle = color ? {
    backgroundColor: color,
    borderColor: color,
    color: getContrastColor(color),
  } : undefined;

  return (
    <span
      ref={ref}
      className={classes}
      style={customStyle}
      {...props}
    >
      {icon && (
        <span className="flex-shrink-0">{icon}</span>
      )}
      <span>{text || displayCount || children}</span>
      {closable && onClose && (
        <button
          type="button"
          className="flex-shrink-0 ml-1 hover:bg-black/10 rounded-full p-0.5 transition-colors duration-150"
          onClick={onClose}
          aria-label="Cerrar"
        >
          <svg
            className="w-3 h-3"
            fill="none"
            strokeLinecap="round"
            strokeLinejoin="round"
            strokeWidth={2}
            viewBox="0 0 24 24"
            stroke="currentColor"
          >
            <path d="M6 18L18 6M6 6l12 12" />
          </svg>
        </button>
      )}
    </span>
  );
});

// Helper function to determine contrast color
function getContrastColor(hexColor: string): string {
  // Remove # if present
  const color = hexColor.replace('#', '');
  
  // Convert to RGB
  const r = parseInt(color.substr(0, 2), 16);
  const g = parseInt(color.substr(2, 2), 16);
  const b = parseInt(color.substr(4, 2), 16);
  
  // Calculate relative luminance
  const luminance = (0.299 * r + 0.587 * g + 0.114 * b) / 255;
  
  // Return black for light colors, white for dark colors
  return luminance > 0.5 ? '#000000' : '#ffffff';
}

Badge.displayName = 'Badge';

export default Badge;