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

export interface StatusDotProps extends HTMLAttributes<HTMLSpanElement> {
  /**
   * Status variant determining color and animation
   * @default 'default'
   */
  status?: 'default' | 'success' | 'error' | 'warning' | 'info' | 'processing';

  /**
   * Size of the status dot
   * @default 'md'
   */
  size?: 'sm' | 'md' | 'lg';

  /**
   * Whether to show a pulse animation
   * @default false (true for 'processing' and 'success' status)
   */
  pulse?: boolean;

  /**
   * Position offset when used as overlay [x, y]
   * @example [4, -4] moves dot 4px right and 4px up
   */
  offset?: [number, number];

  /**
   * Whether this dot is positioned as an overlay
   * @default false
   */
  overlay?: boolean;

  /**
   * Optional text label to display next to the dot
   */
  label?: string;
}

/**
 * StatusDot - Displays status indicators as colored dots
 *
 * Features:
 * - Multiple status variants (online/offline/busy/processing)
 * - Optional pulse animation
 * - Standalone or overlay mode
 * - Optional text label
 * - Responsive sizing
 * - Accessible with proper ARIA labels
 *
 * @example
 * ```tsx
 * // Standalone status dot
 * <StatusDot status="success" />
 *
 * // With label
 * <StatusDot status="success" label="Online" />
 *
 * // As overlay on avatar
 * <div className="relative">
 *   <Avatar />
 *   <StatusDot status="success" overlay />
 * </div>
 *
 * // With pulse animation
 * <StatusDot status="processing" pulse />
 * ```
 */
export const StatusDot = forwardRef<HTMLSpanElement, StatusDotProps>(({
  status = 'default',
  size = 'md',
  pulse = status === 'processing' || status === 'success',
  offset,
  overlay = false,
  label,
  className,
  style,
  ...props
}, ref) => {
  // Base container classes
  const containerClasses = label ? [
    'inline-flex items-center gap-2',
  ] : [];

  // Base dot classes
  const baseDotClasses = [
    'rounded-full',
    'transition-all duration-200 ease-in-out',
  ];

  // Overlay-specific classes
  const overlayClasses = overlay ? [
    'absolute',
    'ring-2 ring-[var(--bg-primary)]',
    'bottom-0',
    'right-0',
  ] : [];

  // Status-specific classes using CSS custom properties
  const statusClasses = {
    default: 'bg-[var(--text-tertiary)]',
    success: 'bg-[var(--color-success)]',
    error: 'bg-[var(--color-error)]',
    warning: 'bg-[var(--color-warning)]',
    info: 'bg-[var(--color-info)]',
    processing: 'bg-[var(--color-info)]',
  };

  // Size-specific classes
  const sizeClasses = {
    sm: 'w-2 h-2',
    md: 'w-2.5 h-2.5',
    lg: 'w-3 h-3',
  };

  // Pulse animation classes
  const pulseClasses = pulse ? 'animate-pulse' : '';

  const dotClasses = clsx(
    baseDotClasses,
    overlayClasses,
    statusClasses[status],
    sizeClasses[size],
    pulseClasses,
  );

  // Calculate offset style if provided
  const offsetStyle = offset && overlay ? {
    transform: `translate(${offset[0]}px, ${offset[1]}px)`,
  } : undefined;

  // Status labels for accessibility
  const statusLabels = {
    default: 'Default',
    success: 'Online',
    error: 'Offline',
    warning: 'Away',
    info: 'Busy',
    processing: 'Processing',
  };

  const ariaLabel = label || statusLabels[status];

  // If there's a label, render as a container with dot + text
  if (label && !overlay) {
    return (
      <span
        ref={ref}
        className={clsx(containerClasses, className)}
        role="status"
        aria-label={ariaLabel}
        {...props}
      >
        <span className={dotClasses} aria-hidden="true" />
        <span className="text-sm text-[var(--text-secondary)]">{label}</span>
      </span>
    );
  }

  // Otherwise, render just the dot
  return (
    <span
      ref={ref}
      className={clsx(dotClasses, className)}
      style={{
        ...style,
        ...offsetStyle,
      }}
      role="status"
      aria-label={ariaLabel}
      {...props}
    />
  );
});

StatusDot.displayName = 'StatusDot';

export default StatusDot;
