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

import {
  SentimentSurfaceComponentProps,
  SentimentSurfaceComponent,
} from './SentimentSurface.types';
import { useTheme } from '@wise/components-theming';

/**
 * SentimentSurface is a polymorphic container component that exposes and, optionally, applies
 * contextual colour tokens as CSS custom properties, based on sentiment types (`negative`,
 * `warning`, `neutral`, `success`, `proposition`).
 *
 * @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 {boolean} [hasBaseStyles=true] - If true, sets the `background-color` and `color` on the container. Otherwise, only exposes the tokens as CSS custom properties without rendering.
 * @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} [data-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',
    hasBaseStyles = true,
    style,
    className,
    children,
    id,
    'data-testid': dataTestId,
    ...props
  }: SentimentSurfaceComponentProps<T>,
  ref: ForwardedRef<HTMLElement>,
) {
  const Element = as ?? 'div';
  const BASE_CLASS = 'wds-sentiment-surface';
  const { className: closestBrandTheme } = useTheme();
  const classNames = clsx(
    closestBrandTheme,
    BASE_CLASS,
    `${BASE_CLASS}-${sentiment}-${emphasis}`,
    hasBaseStyles && `${BASE_CLASS}--hasBaseStyles`,
    className,
  );
  const sentimentProps = {
    ref,
    id,
    'data-testid': dataTestId,
    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;
