import cx from "classnames";
import React, { JSX } from "react";
import ConditionalWrapper from "../../utils/ConditionalWrapper";
import { Buttons } from "../Buttons";
import { Icon } from "../Icon";

import data from "./data";

export type AlertType = "warning" | "info" | "danger" | "success";

interface AlertProps extends React.HTMLAttributes<HTMLDivElement> {
  /** Additional action buttons to add interactivity */
  actionButtons?: React.ReactNode;
  /** Description of the alert */
  description?: React.ReactNode;
  /** Level of the heading in heading hierarchy */
  headingLevel?: number;
  /** Sets Alert to full width */
  isFullWidth?: boolean;
  /** Callback function when close button is clicked */
  onClose?: () => void;
  /** Custom title renderer. Passes props as function parameter. */
  renderTitle?: (props: AlertProps) => React.ReactNode;
  /** Main text message */
  title?: string;
  /** Type of alert, sets icon and color */
  type?: AlertType;
  className?: string;
}

const CLASS_ROOT = "alert";

const Alert: React.FC<AlertProps> = ({
  className,
  type = "info",
  title,
  renderTitle,
  description,
  headingLevel = 3,
  actionButtons,
  isFullWidth,
  onClose,
  ...other
}) => {
  const HEADINGTAG = `h${headingLevel}` as keyof JSX.IntrinsicElements;
  const classes = cx(
    CLASS_ROOT,
    {
      [`${CLASS_ROOT}--${type}`]: type,
      [`${CLASS_ROOT}--full-width`]: isFullWidth,
    },
    className,
  );

  const alertTitle =
    (renderTitle &&
      renderTitle({
        className,
        type,
        title,
        renderTitle,
        description,
        headingLevel,
        actionButtons,
        isFullWidth,
        onClose,
        ...other,
      })) ||
    (title &&
      React.createElement(
        HEADINGTAG,
        { className: `${CLASS_ROOT}__title` },
        title,
      ));

  return (
    <div className={classes} {...other}>
      <div className={`${CLASS_ROOT}__icon`}>
        <Icon name={data[type]} color={type} size="medium" />
      </div>
      <div className={`${CLASS_ROOT}__content`}>
        {alertTitle}
        {description && (
          <ConditionalWrapper
            condition={typeof description === "string"}
            wrapper={<p />}
          >
            {description}
          </ConditionalWrapper>
        )}
        {actionButtons && (
          <ConditionalWrapper
            condition={React.Children.count(actionButtons) > 1}
            wrapper={<Buttons />}
          >
            {React.Children.map(actionButtons, (button) => button)}
          </ConditionalWrapper>
        )}
      </div>
      {onClose && (
        <div className={`${CLASS_ROOT}__close`}>
          <button onClick={onClose}>
            <Icon name="close" size="medium" />
          </button>
        </div>
      )}
    </div>
  );
};

Alert.displayName = "Alert";

export { Alert };
