import React from 'react';
import Box from '@mui/material/Box';
import type { BoxProps } from '@mui/material/Box';
import type { Theme } from '@mui/material/styles';

// ─── Types ───────────────────────────────────────────────────────────────────

/** Colour intent for the badge */
export type BadgeColor = 'default' | 'brand' | 'success' | 'warning' | 'error' | 'info';

/** Props for the FA Badge component */
export interface BadgeProps extends Omit<BoxProps, 'color'> {
  /** Colour intent */
  color?: BadgeColor;
  /** Visual style: "filled" (solid background) or "soft" (tonal/subtle background) */
  variant?: 'filled' | 'soft';
  /** Size preset */
  size?: 'small' | 'medium' | 'large';
  /** Optional leading icon */
  icon?: React.ReactNode;
  /** Label text */
  children: React.ReactNode;
}

// ─── Colour maps ─────────────────────────────────────────────────────────────

const filledColors: Record<BadgeColor, { bg: string; text: string }> = {
  default: { bg: 'var(--fa-color-neutral-700)', text: 'var(--fa-color-white)' },
  brand: { bg: 'var(--fa-color-interactive-default)', text: 'var(--fa-color-white)' },
  success: { bg: 'var(--fa-color-feedback-success)', text: 'var(--fa-color-white)' },
  warning: { bg: 'var(--fa-color-feedback-warning)', text: 'var(--fa-color-white)' },
  error: { bg: 'var(--fa-color-feedback-error)', text: 'var(--fa-color-white)' },
  info: { bg: 'var(--fa-color-feedback-info)', text: 'var(--fa-color-white)' },
};

const softColors: Record<BadgeColor, { bg: string; text: string }> = {
  default: { bg: 'var(--fa-color-neutral-200)', text: 'var(--fa-color-neutral-700)' },
  brand: { bg: 'var(--fa-color-brand-200)', text: 'var(--fa-color-brand-700)' },
  success: {
    bg: 'var(--fa-color-feedback-success-subtle)',
    text: 'var(--fa-color-feedback-success)',
  },
  warning: { bg: 'var(--fa-color-feedback-warning-subtle)', text: 'var(--fa-color-text-warning)' },
  error: { bg: 'var(--fa-color-feedback-error-subtle)', text: 'var(--fa-color-feedback-error)' },
  info: { bg: 'var(--fa-color-feedback-info-subtle)', text: 'var(--fa-color-feedback-info)' },
};

// ─── Component ───────────────────────────────────────────────────────────────

/**
 * Status indicator label for the FA design system.
 *
 * Pill-shaped, display-only badge for communicating status, category,
 * or emphasis. Used in PriceCard ("Popular"), ServiceOption ("Included"),
 * and other contexts.
 *
 * Colour options:
 * - `default` — neutral grey (general labels)
 * - `brand` — warm gold/copper (promoted, featured)
 * - `success` — green (confirmed, included, available)
 * - `warning` — amber (limited, expiring, attention)
 * - `error` — red (sold out, unavailable, urgent)
 * - `info` — blue (new, updated, informational)
 *
 * Variant options:
 * - `soft` (default) — tonal background, coloured text. Calmer, preferred for FA.
 * - `filled` — solid background, white text. For high-priority emphasis.
 *
 * **Accessibility**: If a Badge contains only an icon (no text children),
 * provide an `aria-label` prop so screen readers can announce the status.
 */
export const Badge = React.forwardRef<HTMLDivElement, BadgeProps>(
  ({ color = 'default', variant = 'soft', size = 'medium', icon, children, sx, ...props }, ref) => {
    const sizeMap = {
      small: {
        height: 'var(--fa-badge-height-sm)',
        px: 'var(--fa-badge-padding-x-sm)',
        fontSize: 'var(--fa-badge-font-size-sm)',
        iconSize: 'var(--fa-badge-icon-size-sm)',
      },
      medium: {
        height: 'var(--fa-badge-height-md)',
        px: 'var(--fa-badge-padding-x-md)',
        fontSize: 'var(--fa-badge-font-size-md)',
        iconSize: 'var(--fa-badge-icon-size-md)',
      },
      large: {
        height: 'var(--fa-badge-height-lg)',
        px: 'var(--fa-badge-padding-x-lg)',
        fontSize: 'var(--fa-badge-font-size-lg)',
        iconSize: 'var(--fa-badge-icon-size-lg)',
      },
    } as const;

    const s = sizeMap[size];

    return (
      <Box
        ref={ref}
        component="span"
        sx={[
          (theme: Theme) => {
            const colors = variant === 'filled' ? filledColors[color] : softColors[color];

            return {
              display: 'inline-flex',
              alignItems: 'center',
              gap: 'var(--fa-badge-icon-gap-default)',
              minHeight: s.height,
              px: s.px,
              borderRadius: 'var(--fa-badge-border-radius-default)',
              backgroundColor: colors.bg,
              color: colors.text,
              fontSize: s.fontSize,
              fontWeight: 600,
              fontFamily: theme.typography.fontFamily,
              lineHeight: 1,
              letterSpacing: '0.02em',
              whiteSpace: 'nowrap',
              userSelect: 'none',
              // Icon sizing
              '& > .MuiSvgIcon-root, & > svg': {
                fontSize: s.iconSize,
                flexShrink: 0,
              },
            };
          },
          ...(Array.isArray(sx) ? sx : [sx]),
        ]}
        {...props}
      >
        {icon}
        {children}
      </Box>
    );
  },
);

Badge.displayName = 'Badge';
export default Badge;
