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

export type CardElevation = 'flat' | 'raised' | 'floating';
export type CardPadding = 'none' | 'sm' | 'md' | 'lg';

export interface CardProps extends HTMLAttributes<HTMLDivElement> {
  elevation?: CardElevation;
  /** Padding applied to Card itself. Use `none` when composing with the parts. */
  padding?: CardPadding;
  /** Adds hover feedback. Set when the whole card is a link or button. */
  interactive?: boolean;
}

/**
 * Surface container. Compose with `CardHeader`, `CardBody` and `CardFooter`
 * for a divided layout, or pass children directly with a `padding` value.
 */
export const Card = forwardRef<HTMLDivElement, CardProps>(function Card(
  { elevation = 'raised', padding = 'none', interactive = false, className, children, ...rest },
  ref,
) {
  return (
    <div
      {...rest}
      ref={ref}
      className={cx(
        'ds-card',
        `ds-card--${elevation}`,
        `ds-card--pad-${padding}`,
        interactive && 'ds-card--interactive',
        className,
      )}
    >
      {children}
    </div>
  );
});

export interface CardSectionProps extends HTMLAttributes<HTMLDivElement> {
  children?: ReactNode;
}

/* `title` is omitted from the DOM attributes so it can carry a ReactNode
   heading rather than the native tooltip string. */
export interface CardHeaderProps extends Omit<CardSectionProps, 'title'> {
  /** Heading text. Rendered as the card's title. */
  title?: ReactNode;
  /** Secondary line under the title. */
  description?: ReactNode;
  /** Trailing content — usually a Button or Badge. */
  actions?: ReactNode;
}

export function CardHeader({
  title,
  description,
  actions,
  className,
  children,
  ...rest
}: CardHeaderProps) {
  return (
    <div {...rest} className={cx('ds-card__header', className)}>
      <div className="ds-card__header-text">
        {title != null && <h3 className="ds-card__title">{title}</h3>}
        {description != null && <p className="ds-card__description">{description}</p>}
        {children}
      </div>
      {actions != null && <div className="ds-card__actions">{actions}</div>}
    </div>
  );
}

export function CardBody({ className, children, ...rest }: CardSectionProps) {
  return (
    <div {...rest} className={cx('ds-card__body', className)}>
      {children}
    </div>
  );
}

export function CardFooter({ className, children, ...rest }: CardSectionProps) {
  return (
    <div {...rest} className={cx('ds-card__footer', className)}>
      {children}
    </div>
  );
}
