import React, { useCallback, useRef, useState } from 'react';
import { FieldInputProps } from 'formik';
import { EmojiData, Picker } from 'emoji-mart';
import EmojiSuggestion from '../EmojiSuggestion';
import { InputFieldProps } from '../../interfaces';
import useOutsideClick from '../../hooks/useOutsideClick';
import { EmojiIcon, Typography } from '../../';
import { EmojiToggle, Dialog, EmojiToggleWrapper } from './styles';
import colors from '../../theme/colors';

type EmojiInputProps = Pick<
  InputFieldProps,
  | 'setFieldValue'
  | 'maxLength'
  | 'dataCy'
  | 'dataTestId'
  | 'placeholder'
  | 'isBottom'
  | 'characterLimit'
> & {
  field: FieldInputProps<any>;
};

const EmojiInput = ({
  setFieldValue,
  field,
  maxLength,
  dataCy,
  dataTestId,
  placeholder,
  isBottom,
  characterLimit,
}: EmojiInputProps) => {
  const [emojiText, setEmojiText] = useState('');
  const textareaRef = useRef<HTMLTextAreaElement>(
    document.createElement('textarea')
  );
  const picker = useRef<HTMLDivElement>(null);
  const [showPicker, setPickerState] = useState(false);
  const dismissPicker = useCallback(() => {
    setPickerState(false);
  }, [setPickerState]);

  useOutsideClick([picker], dismissPicker);

  const togglePicker = () => {
    setPickerState(!showPicker);
  };

  const emojiInserted = (
    messageWithEmoji: string,
    suggestedEmoji?: boolean
  ) => {
    if (setFieldValue) {
      if (suggestedEmoji) {
        setFieldValue(
          field.name,
          `${field.value.replace(emojiText, '')}${messageWithEmoji.replace(
            `:${emojiText}`,
            messageWithEmoji
          )} `
        );
        setEmojiText('');
      } else {
        setFieldValue(field.name, `${field.value}${messageWithEmoji} `);
      }
    }
    textareaRef.current.focus();
  };

  const addEmoji = (emoji: EmojiData) => {
    if ('native' in emoji) {
      emojiInserted(emoji.native);
      dismissPicker();
    }
  };

  const handleChange = (e: React.ChangeEvent<HTMLTextAreaElement>) => {
    if (setFieldValue) {
      setEmojiText(e.target.value);
      setFieldValue(field.name, e.target.value);
    }
  };

  return (
    <>
      <EmojiSuggestion value={emojiText} onSelection={emojiInserted} />
      <textarea
        ref={textareaRef}
        data-cy={dataCy}
        data-testid={dataTestId}
        placeholder={placeholder}
        onChange={handleChange}
        maxLength={maxLength}
        name={field.name}
        value={field.value}
        id={field.name}
        onBlur={field.onBlur}
      />
      <div ref={picker}>
        <Dialog isBottom={isBottom}>
          {showPicker && (
            <Picker
              emoji=""
              title=""
              native={true}
              showPreview={false}
              showSkinTones={false}
              onSelect={addEmoji}
            />
          )}
        </Dialog>
        <EmojiToggleWrapper>
          {characterLimit && (
            <Typography
              variant={'utility4'}
              color={
                field.value?.length > characterLimit
                  ? colors.error[700]
                  : colors.neutral[400]
              }
            >
              {field.value?.length || 0}/{characterLimit}
            </Typography>
          )}
          <EmojiToggle type="button" onClick={togglePicker}>
            <EmojiIcon width={18} />
          </EmojiToggle>
        </EmojiToggleWrapper>
      </div>
    </>
  );
};

export default EmojiInput;
