import { useAppConfig } from '@/components/AppStateProvider';
import { useTheme } from '@emotion/react';
import { FormHelperText, InputLabel, Stack, SxProps } from '@mui/material';
import React, { PropsWithChildren } from 'react';
import { FieldTitle, useTranslate } from 'react-admin';
import { useFormContext } from 'react-hook-form';

/**
 * Allows you to display an array of inputs with a label and a helper text with the Mantis theme style.
 */
function LabeledArrayInput({
  label,
  children,
  display = 'label',
  helperText,
  sx,
  addLabel,
  divider = false,
  fullWidth,
  ...props
}: LabeledArrayInputProps): React.ReactElement {
  const theme = useTheme() as any;
  const translate = useTranslate();
  const { getCurrentDialog } = useAppConfig();
  const { source, resource, isRequired } = props;
  const { getFieldState, formState } = useFormContext();
  const { error } = getFieldState(source, formState);
  const dialogResource = getCurrentDialog();

  return (
    <Stack
      spacing={1}
      sx={{
        '& .MuiFormHelperText-root': {
          // @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.
          color: error ? theme.palette.error.main : theme.palette.text.secondary,
          '& span': {
            display: 'none'
          }
        },
        width: fullWidth ? '100%' : 'auto',
        ...sx
      }}
    >
      {display === 'label' && label !== false && addLabel !== false && (
        <InputLabel
          error={!!error}
          sx={{
            borderBottom: divider ? `1px solid ${theme.palette.divider}` : 'none',
            pb: divider ? 1 : 0,
            mt: divider ? 1 : 0,
            pt: 1
          }}
        >
          <FieldTitle label={label} source={source} resource={dialogResource || resource} isRequired={isRequired} />
        </InputLabel>
      )}
      {React.isValidElement(children)
        ? React.cloneElement(children, {
            // @ts-ignore
            ...children.props,
            ...props,
            label: display === 'legend' ? label : false
          })
        : children}
      {display === 'label' && helperText ? (
        <FormHelperText
          sx={{
            pl: 1.8,
            pb: 2,
            marginTop: '0 !important'
          }}
          error={!!error}
        >
          {React.isValidElement(helperText)
            ? helperText
            : typeof helperText === 'string'
            ? translate(helperText, { _: helperText })
            : helperText}
        </FormHelperText>
      ) : null}
    </Stack>
  );
}

type LabeledArrayInputProps = PropsWithChildren<{
  label?: string | boolean;
  addLabel?: boolean;
  resource?: string;
  isRequired?: boolean;
  source: string;
  display?: 'legend' | 'label';
  helperText?: string | boolean;
  divider?: boolean;
  sx?: SxProps;
  fullWidth?: boolean;
}>;

export { LabeledArrayInput };
export type { LabeledArrayInputProps };
