import type { HTMLAttributes, ReactNode } from 'react';
import { cx } from '../../utils/cx';
import './Alert.css';

export type AlertTone = 'info' | 'success' | 'warning' | 'danger';

/* `title` is omitted from the DOM attributes so it can carry a ReactNode
   heading rather than the native tooltip string. */
export interface AlertProps extends Omit<HTMLAttributes<HTMLDivElement>, 'title'> {
  tone?: AlertTone;
  /** Bold first line. */
  title?: ReactNode;
  /** Replaces the default tone icon. Pass `null` to drop the icon entirely. */
  icon?: ReactNode | null;
  /** Renders a close button and is called when it is pressed. */
  onDismiss?: () => void;
  /** Accessible name for the close button. */
  dismissLabel?: string;
  children?: ReactNode;
}

const ICONS: Record<AlertTone, ReactNode> = {
  info: (
    <svg viewBox="0 0 16 16" fill="none" stroke="currentColor" strokeWidth="1.5">
      <circle cx="8" cy="8" r="6.25" />
      <path d="M8 7.25v4" strokeLinecap="round" />
      <circle cx="8" cy="5" r="0.75" fill="currentColor" stroke="none" />
    </svg>
  ),
  success: (
    <svg viewBox="0 0 16 16" fill="none" stroke="currentColor" strokeWidth="1.5">
      <circle cx="8" cy="8" r="6.25" />
      <path d="M5.25 8.25l2 2 3.5-4" strokeLinecap="round" strokeLinejoin="round" />
    </svg>
  ),
  warning: (
    <svg viewBox="0 0 16 16" fill="none" stroke="currentColor" strokeWidth="1.5">
      <path d="M8 2.25l6 11H2l6-11z" strokeLinejoin="round" />
      <path d="M8 6.5v3" strokeLinecap="round" />
      <circle cx="8" cy="11.4" r="0.75" fill="currentColor" stroke="none" />
    </svg>
  ),
  danger: (
    <svg viewBox="0 0 16 16" fill="none" stroke="currentColor" strokeWidth="1.5">
      <circle cx="8" cy="8" r="6.25" />
      <path d="M8 4.75v4" strokeLinecap="round" />
      <circle cx="8" cy="11.2" r="0.75" fill="currentColor" stroke="none" />
    </svg>
  ),
};

/**
 * Inline message about the state of the page or a recent action.
 * `danger` and `warning` announce assertively; the rest announce politely.
 */
export function Alert({
  tone = 'info',
  title,
  icon,
  onDismiss,
  dismissLabel = 'Dismiss',
  className,
  children,
  ...rest
}: AlertProps) {
  const resolvedIcon = icon === undefined ? ICONS[tone] : icon;
  const assertive = tone === 'danger' || tone === 'warning';

  return (
    <div
      {...rest}
      role={assertive ? 'alert' : 'status'}
      className={cx('ds-alert', `ds-alert--${tone}`, className)}
    >
      {resolvedIcon != null && (
        <span className="ds-alert__icon" aria-hidden="true">
          {resolvedIcon}
        </span>
      )}
      <div className="ds-alert__content">
        {title != null && <p className="ds-alert__title">{title}</p>}
        {children != null && <div className="ds-alert__body">{children}</div>}
      </div>
      {onDismiss && (
        <button type="button" className="ds-alert__dismiss" onClick={onDismiss}>
          <span className="ds-visually-hidden">{dismissLabel}</span>
          <svg viewBox="0 0 16 16" fill="none" stroke="currentColor" strokeWidth="1.5" aria-hidden="true">
            <path d="M4 4l8 8M12 4l-8 8" strokeLinecap="round" />
          </svg>
        </button>
      )}
    </div>
  );
}
