import React, { ReactElement, ReactNode } from 'react';
import css from '../../../utils/css';

import {
  StyledParagraphBlock,
  StyledDivBlock,
  StyledSpanInline,
  StyledLabelInline,
} from './StyledText';
import { CommonProps } from '../../common';

export interface TextProps extends CommonProps {
  /**
   * Text content.
   */
  children: ReactNode;
  /**
   * Text's font-size.
   */
  fontSize?: 10 | 12 | 14 | 16;
  /**
   * Text's font-weight.
   */
  fontWeight?: 'regular' | 'light' | 'semi-bold' | 'bold';
  /**
   * Which form element the text is bound to. This only gets effect when tagName is label.
   */
  htmlFor?: string;
  /**
   * Visual intent color to apply to text.
   */
  intent?:
    | 'main'
    | 'subdued'
    | 'body'
    | 'primary'
    | 'success'
    | 'danger'
    | 'warning'
    | 'error'
    | 'white';
  /**
   * HTML tag name to use for rendered element.
   */
  tagName?: 'div' | 'p' | 'span' | 'label';
}

const Text = ({
  children,
  intent = 'main',
  fontSize = 14,
  fontWeight = 'regular',
  tagName = 'p',
  htmlFor,
  id,
  className,
  style,
  sx = {},
  'data-test-id': dataTestId,
}: TextProps): ReactElement => {
  const commonTextProps = {
    themeIntent: intent,
    themeFontSize: fontSize,
    themeFontWeight: fontWeight,
    as: tagName,
    id,
    className,
    style: { ...style, ...css(sx) },
    'data-test-id': dataTestId,
    children,
  };

  switch (tagName) {
    case 'div':
      return <StyledDivBlock {...commonTextProps} />;
    case 'p':
      return <StyledParagraphBlock {...commonTextProps} />;
    case 'span':
      return <StyledSpanInline {...commonTextProps} />;
    case 'label':
      return <StyledLabelInline {...commonTextProps} htmlFor={htmlFor} />;
  }
};

export default Text;
