import { clsx } from 'clsx';
import messages from './Label.messages';
import { useIntl } from 'react-intl';
import Body from '../body';
import { CommonProps } from '../common';
import { PropsWithChildren } from 'react';

export type LabelProps = {
  id?: string;
  htmlFor?: string;
  className?: string;
  children?: React.ReactNode;
};

/**
 * Avoid using `<Label>` component directly
 * it's for edge cases when `<Field />` isn't suitable for some reasons.
 *
 * Example:
 * ```
 * <Field label={..} description={..} required={..}>..</Field>
 * ```
 */
const Label = ({ className, children, htmlFor, id }: LabelProps) => {
  return (
    <label
      id={id}
      htmlFor={htmlFor}
      className={clsx(
        'np-label d-flex flex-column np-text-body-default-bold text-primary m-b-0',
        className,
      )}
    >
      {children}
    </label>
  );
};

export type LabelOptionalProps = PropsWithChildren<CommonProps>;

// eslint-disable-next-line functional/immutable-data
Label.Optional = function Optional({ children, className }: LabelOptionalProps) {
  const { formatMessage } = useIntl();
  return (
    <div>
      {children}
      <Body as="span" className={clsx('text-secondary', 'm-l-1', className)}>
        {formatMessage(messages.optionalLabel)}
      </Body>
    </div>
  );
};

export type LabelDescriptionProps = PropsWithChildren<CommonProps> & { id?: string };

// eslint-disable-next-line functional/immutable-data
Label.Description = function Description({ id, children, className }: LabelDescriptionProps) {
  return children ? (
    <Body id={id} className={clsx('text-secondary', className)}>
      {children}
    </Body>
  ) : null;
};

export { Label };
