import { useAppConfig } from '@/components/AppStateProvider';
import { FormHelperText, InputLabel, Stack } from '@mui/material';
import { useTheme } from '@mui/material/styles';
import React, { PropsWithChildren, ReactElement } from 'react';
import { CommonInputProps, FieldTitle, useInput, useTranslate } from 'react-admin';

function LabeledInput({
  label,
  children,
  display = 'label',
  helperText,
  sx,
  addLabel,
  divider = false,
  ...props
}: LabeledInputProps): JSX.Element {
  const theme = useTheme();
  const translate = useTranslate();
  const { getCurrentDialog } = useAppConfig();
  const { source, resource, isRequired, chip } = props;
  const {
    fieldState: { invalid }
  } = useInput(props);
  const dialogResource = getCurrentDialog();
  return (
    <Stack
      spacing={1}
      sx={{
        // @ts-ignore
        width: props?.fullWidth ? '100%' : 'auto',
        '& .MuiFormHelperText-root': {
          pb: 0,
          // @see: https://github.com/marmelab/react-admin/blob/master/packages/ra-ui-materialui/src/input/SelectArrayInput.tsx#L340
          // the 'invalid' prop is not used inside the react-admin component. This is necessary if we want to support
          // remove error message colorization when the field is in error state.
          /** @ts-ignore */
          color: invalid ? theme.palette.error.main : theme.palette.text.secondary,
          '& span': {
            display: 'none'
          }
        },
        ...sx
      }}
    >
      {display === 'label' && label !== false && addLabel !== false && (
        <InputLabel
          error={invalid === true}
          sx={{
            // @ts-ignore
            borderBottom: divider ? `1px solid ${theme.palette.divider}` : 'none',
            pt: 0.5,
            pb: divider ? 1 : 0,
            mt: divider ? 1 : 0
          }}
        >
          <FieldTitle label={label} source={source} resource={dialogResource || resource} isRequired={isRequired} />
        </InputLabel>
      )}
      {React.isValidElement(children)
        ? React.cloneElement(children, {
            // @ts-ignore
            ...children.props,
            ...props,
            chip: chip && typeof chip === 'function' ? React.createElement(chip) : chip,
            label: display === 'legend' ? label : false
          })
        : children}
      {helperText ? (
        <FormHelperText
          sx={{
            pl: 1.8,
            pb: 2,
            marginTop: '0 !important'
          }}
          error={invalid === true}
        >
          {React.isValidElement(helperText)
            ? helperText
            : typeof helperText === 'string'
            ? translate(helperText, { _: helperText })
            : helperText}
        </FormHelperText>
      ) : null}
    </Stack>
  );
}

type LabeledInputProps = PropsWithChildren<
  CommonInputProps & {
    sx?: any;
    label?: string | ReactElement | false;
    addLabel?: boolean;
    resource?: string;
    isRequired?: boolean;
    display?: 'legend' | 'label';
    helperText?: string | boolean | React.ReactElement | null;
    divider?: boolean;
    chip?: any;
  }
>;

export { LabeledInput };
export type { LabeledInputProps };
