import React, { ReactElement } from 'react';
import css from '../../../utils/css';
import { CommonProps } from '../../common';
import Icon from '../../Icon';
import { InputProps } from '../../Input/Input';
import { TextAreaProps } from '../../Input/TextArea';
import {
  FieldWrapper,
  ValidateSuffixWrapper,
  TextAreaWrapper,
} from './StyledField';
import ValidateIcon from './ValidateIcon';
import { isInput } from './types';

export interface FieldProps extends CommonProps {
  /**
   * Input component to be wrapped.
   */
  children: ReactElement<InputProps | TextAreaProps>;
  /**
   * Validation status of children's value.
   */
  validateStatus?: 'success' | 'warning' | 'error' | 'validating';
}

export const getValidateSuffixElement = (
  children: ReactElement<InputProps>,
  validateStatus: 'success' | 'warning' | 'error' | 'validating'
) => {
  const { suffix, size } = children.props;
  const suffixElement =
    typeof suffix === 'string' ? (
      <Icon
        icon={suffix}
        intent="subdued-text"
        data-test-id="input-suffix-icon"
      />
    ) : (
      suffix
    );

  return (
    <ValidateSuffixWrapper data-test-id="validate-suffix-wrapper">
      {suffixElement}
      <ValidateIcon status={validateStatus} size={size} />
    </ValidateSuffixWrapper>
  );
};

export const getValidatedChildren = (
  children: ReactElement<InputProps | TextAreaProps>,
  validateStatus?: 'success' | 'warning' | 'error' | 'validating'
) => {
  if (validateStatus === undefined) {
    return children;
  }

  if (isInput(children)) {
    return React.cloneElement(children, {
      ...children.props,
      suffix: getValidateSuffixElement(children, validateStatus),
    });
  }

  const { size } = children.props;

  return (
    <TextAreaWrapper
      themeSize={size !== undefined ? size : 'medium'}
      data-test-id="text-area-field-wrapper"
    >
      {children}
      <ValidateIcon status={validateStatus} />
    </TextAreaWrapper>
  );
};

const Field = ({
  children,
  validateStatus,
  id,
  className,
  style,
  sx = {},
  'data-test-id': dataTestId,
}: FieldProps) => {
  const validatedChildren = getValidatedChildren(children, validateStatus);

  return (
    <FieldWrapper
      themeStatus={validateStatus}
      id={id}
      className={className}
      style={{ ...style, ...css(sx) }}
      data-test-id={dataTestId}
    >
      {validatedChildren}
    </FieldWrapper>
  );
};

export default Field;
