import { forwardRef, ElementType, ForwardedRef } from 'react';
import { clsx } from 'clsx';

import {
  SentimentSurfaceComponentProps,
  SentimentSurfaceComponent,
} from './SentimentSurface.types';
import { getSentimentSurfaceClassName } from './classMap';

/**
 * SentimentSurface is a polymorphic container component that applies contextual background colours
 * and text styling based on sentiment types (negative, warning, neutral, success, proposition).
 * It's designed to visually communicate the nature or importance of its content through colour.
 *
 * @param {ElementType} [as='div'] - Optional prop to override the HTML element rendered.
 * @param {Sentiment} sentiment - Required prop to set the sentiment type (negative, warning, neutral, success, proposition).
 * @param {Emphasis} [emphasis='base'] - Optional prop to specify the emphasis level (base or elevated).
 * @param {ReactNode} [children] - Content to render inside the surface.
 * @param {string} [className] - Additional CSS classes to apply.
 * @param {CSSProperties} [style] - Inline styles to apply.
 * @param {string} [id] - Unique identifier for the component.
 * @param {string} [testId] - A unique string that appears as data attribute `data-testid` in the rendered code.
 *
 * @component
 * @example
 * ```tsx
 * // Basic usage with negative sentiment
 * <SentimentSurface sentiment="negative">
 *   Your payment has failed
 * </SentimentSurface>
 * ```
 *
 * @see {@link SentimentSurface} for further information.
 * @see {@link https://storybook.wise.design/?path=/docs/sentiment-surface--docs|Storybook Wise Design}
 */
// @ts-expect-error - Generic forwardRef limitation. See: https://fettblog.eu/typescript-react-generic-forward-refs/
const SentimentSurface: SentimentSurfaceComponent = forwardRef(function SentimentSurface<
  T extends ElementType = 'div',
>(
  {
    as,
    sentiment,
    emphasis = 'base',
    className,
    style,
    children,
    id,
    testId,
    ...props
  }: SentimentSurfaceComponentProps<T>,
  ref: ForwardedRef<HTMLElement>,
) {
  const Element = as ?? 'div';
  const classNames = clsx(getSentimentSurfaceClassName(sentiment, emphasis), className);
  const sentimentProps = {
    ref,
    id,
    'data-testid': testId,
    className: classNames,
    style,
    ...props,
  };

  return (
    // @ts-expect-error - Generic forwardRef limitation. See: https://fettblog.eu/typescript-react-generic-forward-refs/
    <Element {...sentimentProps}>{children}</Element>
  );
});

SentimentSurface.displayName = 'SentimentSurface';

export default SentimentSurface;
