import React from "react";
import styles from "./Text.module.css";
import textConstants from "./Text.constantProps";
import getCompliedClassName from "../../utils/getCompliedClassName";
import textPropTypes, {
  defaultProps,
  propsDescription
} from "./Text.propTypes";
import constantProps from "./Text.constantProps";
import getCompliedCustomId from "../../utils/getCompliedCustomId";
import PropTypes from "prop-types";

const tagNamesMapping = {
  [textConstants.type.heading]: {
    [textConstants.level.one]: "h1",
    [textConstants.level.two]: "h2",
    [textConstants.level.three]: "h3",
    [textConstants.level.four]: "h4",
    [textConstants.level.five]: "h5",
    [textConstants.level.six]: "h6"
  },
  [textConstants.type.paragraph]: "p",
  [textConstants.type.blockquote]: "blockquote"
};

const getTagNameByTypeProperty = (type, level) => {
  if (type === textConstants.type.heading) {
    return tagNamesMapping[type][level];
  } else {
    return tagNamesMapping[type];
  }
};

const defaultTagName = "span";

export default function Text(props) {
  let {
    textEllipsis,
    wordWrap,
    variant,

    size,
    stretch,
    auto,
    align,
    direction,
    weight,
    transform,
    colorPalette,
    decoration,
    decorationColor,
    type,
    level,

    startIcon,
    endIcon,

    lineHeight,
    letterSpacing,
    indent,

    tagName,
    onClick,

    customClassName,
    customId,
    customIdPrefix,

    ariaLabel,
    role,
    tabIndex,

    children,
    content,
    tagAttributeProps
  } = props;

  let hasIcon = startIcon || endIcon;

  let className = getCompliedClassName(
    customClassName,
    {
      [styles.base]: true,
      [styles.ellipsis]: !!textEllipsis,
      [styles.wrap]: !!wordWrap,
      [styles[variant]]: !!variant,
      [styles[size]]: !!size,
      [styles.stretch]: !!stretch,
      [styles.auto]: !!auto,
      [styles[direction]]: !!direction,
      [styles[align]]: !!align,
      [styles[weight]]: !!weight,
      [styles[transform]]: !!transform,
      [styles[colorPalette]]: !!colorPalette,
      [styles[lineHeight]]: !!lineHeight,
      [styles[letterSpacing]]: !!letterSpacing,
      [styles[decoration]]: !!decoration,
      [styles[decorationColor]]: !!decorationColor,
      [styles[indent]]: !!indent,
      [styles[type]]: !!type,
      [styles[level]]: !!level,
      [styles.content]: !!(children || hasIcon)
    },
    {
      [customClassName.base]: !!customClassName.base,
      [customClassName.textEllipsis]: !!customClassName.textEllipsis,
      [customClassName.wordWrap]: !!customClassName.wordWrap,
      [customClassName.variant]: !!customClassName.variant,
      [customClassName.size]: !!customClassName.size,
      [customClassName.stretch]: !!customClassName.stretch,
      [customClassName.auto]: !!customClassName.auto,
      [customClassName.direction]: !!customClassName.direction,
      [customClassName.align]: !!customClassName.align,
      [customClassName.weight]: !!customClassName.weight,
      [customClassName.transform]: !!customClassName.transform,
      [customClassName.colorPalette]: !!customClassName.colorPalette,
      [customClassName.lineHeight]: !!customClassName.lineHeight,
      [customClassName.letterSpacing]: !!customClassName.letterSpacing,
      [customClassName.decoration]: !!customClassName.decoration,
      [customClassName.decorationColor]: !!customClassName.decorationColor,
      [customClassName.indent]: !!customClassName.indent,
      [customClassName.type]: !!customClassName.type,
      [customClassName.level]: !!customClassName.level
    }
  );

  let textProperties = {
    className: className,
    onClick,

    "data-id": getCompliedCustomId(props, customId.text),

    "aria-label": ariaLabel,
    role: role,
    tabIndex,
    ...tagAttributeProps
  };

  let displayTagName =
    tagName ||
    (props.type && getTagNameByTypeProperty(props.type, props.level)) ||
    defaultTagName;
  let displayContent = (
    <>
      <RenderAsIcon icon={startIcon} className={styles.start_icon} />
      {content && hasIcon ? <span>{content}</span> : content || null}
      {!content && children ? children : null}
      <RenderAsIcon icon={endIcon} className={styles.end_icon} />
    </>
  );

  let element = React.createElement(displayTagName);
  return <element.type {...textProperties}>{displayContent}</element.type>;
}

Text.propTypes = textPropTypes;
Text.defaultProps = defaultProps;
Text.propsDescription = propsDescription;
Text.constantProps = constantProps;

const RenderAsIcon = (props) => {
  return props.icon ? (
    <span className={props.className}>{props.icon}</span>
  ) : null;
};

RenderAsIcon.propTypes = {
  icon: PropTypes.any,
  className: PropTypes.string
};
