import { FC, useState } from 'react';
import { useFormContext } from 'react-hook-form';

import DeleteOutlineOutlined from '@material-hu/icons/material/DeleteOutlineOutlined';
import IconButton from '@material-hu/mui/IconButton';
import Stack, { StackProps } from '@material-hu/mui/Stack';
import Tooltip from '@material-hu/mui/Tooltip';

import { useLokaliseTranslation } from 'src/utils/i18n';
import { Check, CheckProps } from 'src/components/FormInputs/FormOptions/Check';
import FormTextField, {
  FormTextFieldProps,
} from 'src/components/FormInputs/FormTextField';

import { FormOptionsTypes, OptionField } from './types';

export type OptionProps = StackProps &
  CheckProps & {
    name: string;
    onRemove?: () => void;
    min?: number;
    minLength?: number;
    maxLength?: number;
    disabledInput?: boolean;
    removeDisplay?: 'allways' | 'hover' | 'never';
    allowRepeated?: boolean;
    formTextFieldProps?: Omit<FormTextFieldProps, 'name'>;
    checkSide?: 'left' | 'right';
    resetOnEmptyBlur?: boolean;
  };

export const Option: FC<OptionProps> = props => {
  const {
    name,
    getOptionName,
    optionsName,
    index,
    onRemove = () => null,
    type = FormOptionsTypes.RADIO,
    min = 1,
    minChecked = 1,
    minLength,
    maxLength,
    disabledCheck = false,
    disabledInput = false,
    removeDisplay = 'hover',
    color = 'primary',
    allowRepeated = false,
    ignoreMinChecked = false,
    checkboxProps = {},
    radioProps = {},
    formTextFieldProps = {},
    showErrors = true,
    checkSide = 'left',
    label,
    resetOnEmptyBlur = false,
    ...containerProps
  } = props;

  const [hasBeenBlurred, setHasBeenBlurred] = useState(false);
  const [previousState, setPreviousState] = useState('');

  const { t } = useLokaliseTranslation(['general']);
  const { setValue, watch } = useFormContext();

  const options = watch(optionsName) as OptionField[];
  const { value } = watch(name);

  const isJustCreated = !hasBeenBlurred;
  const countRepeated = options.filter(option => option.value === value).length;
  const isRepeated = countRepeated > 1;

  const handleBlur = (newValue: string) => {
    if (newValue === '' && resetOnEmptyBlur) {
      if (options.length > min) {
        onRemove();
      } else {
        setValue(`${name}.value`, previousState, { shouldDirty: true });
      }
    }

    setHasBeenBlurred(true);
  };

  const handleFocus = (
    event: React.FocusEvent<HTMLInputElement>,
    newValue: string,
  ) => {
    if (resetOnEmptyBlur) {
      setPreviousState(newValue);
    }

    if (isJustCreated) {
      event.target.select();
    }
  };

  const isRepeatedError = showErrors && !allowRepeated && isRepeated;
  const removeDisabled = options.length <= min;

  return (
    <Stack
      {...containerProps}
      sx={{
        flexDirection: 'row',
        alignItems: 'center',
        width: '100%',
        ...((removeDisabled || removeDisplay === 'hover') && {
          '& #option-delete-container': {
            ml: '36px',
            '& > *': {
              display: 'none',
            },
          },
        }),
        ...(!removeDisabled &&
          removeDisplay === 'hover' && {
            '&:hover #option-delete-container': {
              m: 0,
              '& > *': {
                display: 'inline-flex',
              },
            },
          }),
        ...containerProps.sx,
      }}
    >
      {checkSide === 'left' && (
        <Check
          name={name}
          getOptionName={getOptionName}
          optionsName={optionsName}
          index={index}
          type={type}
          minChecked={minChecked}
          disabledCheck={disabledCheck}
          ignoreMinChecked={ignoreMinChecked}
          color={color}
          checkboxProps={checkboxProps}
          radioProps={radioProps}
          showErrors={showErrors}
          label={label}
        />
      )}
      <FormTextField
        name={`${name}.value`}
        variant="outlined"
        size="small"
        onBlur={handleBlur}
        onFocus={handleFocus}
        disabled={disabledInput}
        error={isRepeatedError}
        aria-describedby={isRepeatedError ? 'error-repeated' : undefined}
        maxLength={maxLength}
        minLength={minLength}
        {...formTextFieldProps}
      />
      {checkSide === 'right' && (
        <Check
          name={name}
          getOptionName={getOptionName}
          optionsName={optionsName}
          index={index}
          type={type}
          minChecked={minChecked}
          disabledCheck={disabledCheck}
          ignoreMinChecked={ignoreMinChecked}
          color={color}
          checkboxProps={checkboxProps}
          radioProps={radioProps}
          showErrors={showErrors}
          label={label}
        />
      )}
      {removeDisplay !== 'never' && (
        <Stack id="option-delete-container">
          <Tooltip title={t('delete')}>
            <IconButton
              id="option-delete-button"
              onClick={onRemove}
              disabled={removeDisabled}
            >
              <DeleteOutlineOutlined fontSize="small" />
            </IconButton>
          </Tooltip>
        </Stack>
      )}
    </Stack>
  );
};

export default Option;
