import * as React from 'react';
import clsx from 'clsx';

import MuiTooltip from '@mui/material/Tooltip';
import type { TooltipProps as MuiTooltipProps } from '@mui/material/Tooltip';
import { styled } from '@mui/material/styles';

import { ASSETS_URL } from '../../../consts/common';
import { CustomIcon } from '../../custom-icon';
import type { Theme } from '../../@styles/theme-provider';

export interface LabelWithHintClasses {
  /** Styles applied to the root element. */
  root: string;
  /** Styles applied to the asterisk. */
  asterisk: string;
  /** Styles applied to the help icon. */
  helpIcon: string;
}

const LabelWithHintRoot = styled('span', {
  name: 'LabelWithHint',
  slot: 'Root'
})(({ theme }: { theme: Theme }) => ({
  ...theme.typography.h6,
  display: 'inline-flex',
  alignItems: 'center',
  color: theme.palette.primary[500]
}));

const AsteriskComponent = styled('span', {
  name: 'LabelWithHint',
  slot: 'Asterisk'
})(({ theme }: { theme: Theme }) => ({
  color: theme.palette.error[500]
}));

const HelpIconComponent = styled('span', {
  name: 'LabelWithHint',
  slot: 'HelpIcon'
})(({ theme }: { theme: Theme }) => ({
  display: 'inline-flex',
  color: theme.palette.primary[300],
  marginLeft: theme.spacing(1),
  '&:hover': {
    color: 'inherit'
  },
  '& > span': {
    color: 'inherit'
  }
}));

export interface LabelWithHintProps {
  /**
   * The content of the label.
   */
  children?: React.ReactNode;
  /**
   * If `true`, the label is displayed as required (with asterisk).
   * @default false
   */
  required?: boolean;
  /** Props to pass to the MUI Tooltip.
   * - [Tooltip API](https://mui.com/api/tooltip/)
   */
  tooltipProps?: Partial<Omit<MuiTooltipProps, 'children' | 'title'>>;
  /**
   * The content of the tooltip to be displayed over the help icon.
   */
  tooltipText?: React.ReactNode;
  /**
   * Override or extend the styles applied to the component.
   */
  classes?: Partial<LabelWithHintClasses>;
  /**
   * Custom class name in case you need to add custom styles to the component.
   */
  className?: string;
}

export const LabelWithHint = React.forwardRef(function (
  props: LabelWithHintProps,
  ref: React.Ref<HTMLSpanElement>
) {
  const {
    children,
    required = false,
    tooltipProps,
    tooltipText,
    className,
    classes,
    ...otherProps
  } = props;

  return (
    <LabelWithHintRoot ref={ref} className={clsx(classes?.root, className)} {...otherProps}>
      {children}
      {required && (
        <AsteriskComponent aria-hidden className={classes?.asterisk}>
          &thinsp;{'*'}
        </AsteriskComponent>
      )}
      {tooltipText && (
        <MuiTooltip title={tooltipText} {...tooltipProps}>
          <HelpIconComponent className={classes?.helpIcon}>
            <CustomIcon
              className={classes?.helpIcon}
              src={`${ASSETS_URL}/icons/icon_help.svg`}
              wrapper="span"
            />
          </HelpIconComponent>
        </MuiTooltip>
      )}
    </LabelWithHintRoot>
  );
});
